diff --git a/MANIFEST.in b/MANIFEST.in index 921a5a2..4bd8102 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -2,6 +2,5 @@ include src/gui/DAMARIS3.png include src/gui/DAMARIS3.ico include src/gui/damaris.glade include src/gui/damaris.gladep -include doc/index.html -recursive-include doc/reference-html *.html *.gif *.png *.css -recursive-include doc/tutorial-html *.html *.gif *.png *.css *.tar.gz *.sh +#recursive-include doc/reference-html *.html *.gif *.png *.css +#recursive-include doc/tutorial-html *.html *.gif *.png *.css *.tar.gz *.sh diff --git a/debian/control b/debian/control index 899de7c..2ba72d2 100644 --- a/debian/control +++ b/debian/control @@ -2,7 +2,7 @@ Source: python3-damaris Section: science Priority: optional Maintainer: Markus Rosenstihl -Build-Depends: python3, debhelper, python3-dev, dh-sequence-python3, dpkg-dev, pybuild-plugin-pyproject +Build-Depends: python3, debhelper, python3-dev, dh-sequence-python3, dpkg-dev, pybuild-plugin-pyproject, sphinx-common, sphinx-rtd-theme-common Standards-Version: 3.7.3 X-Python3-Version: >= 3.5 Rules-Requires-Root: no diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..5382ff7 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,13 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: python3-damaris +Upstream-Contact: Markus Rosenstihl +Source: https://gitea.pkm.physik.tu-darmstadt.de/IPKM/python3-damaris + +Files: * +Copyright: © 2007-2026, Achim Gaedke, Markus Rosenstihl, and others +License: GPL-2.0 + +Files: debian/* +Copyright: © 2007-2026, Achim Gaedke, Markus Rosenstihl, and others +License: GPL-2.0 +Comment: Debian packaging is under the same license as upstream diff --git a/debian/install b/debian/install new file mode 100644 index 0000000..8ec5064 --- /dev/null +++ b/debian/install @@ -0,0 +1 @@ +doc/ usr/share/doc/python3-damaris/ diff --git a/debian/rules b/debian/rules index fa57c81..9f25e53 100755 --- a/debian/rules +++ b/debian/rules @@ -13,7 +13,12 @@ PYBASE=$(CURDIR)/debian/${PACKAGE_NAME} DH_ALWAYS_EXCLUDE=CVS:.git:venv:.venv:*.h5 %: - dh $@ --buildsystem=pybuild + dh $@ --buildsystem=pybuild --with sphinxdoc + +override_dh_auto_build: + dh_auto_build + sphinx-build -N -bhtml doc/ build/doc + override_dh_auto_test: PYBUILD_TEST_ARGS="-v $(CURDIR)/tests" dh_auto_test diff --git a/doc/Doxyfile b/doc/Doxyfile deleted file mode 100644 index c8c23e8..0000000 --- a/doc/Doxyfile +++ /dev/null @@ -1,242 +0,0 @@ -# Doxyfile 1.5.3 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "python DAMARIS" -PROJECT_NUMBER = 0.13-svn -OUTPUT_DIRECTORY = . -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class " \ - "The $name widget " \ - "The $name file " \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = NO -STRIP_FROM_PATH = -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -QT_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = NO -BUILTIN_STL_SUPPORT = NO -CPP_CLI_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = YES -EXTRACT_PRIVATE = YES -EXTRACT_STATIC = YES -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -EXTRACT_ANON_NSPACES = NO -HIDE_UNDOC_MEMBERS = NO -HIDE_UNDOC_CLASSES = NO -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text " -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = damaris -INPUT_ENCODING = ISO-8859-15 -FILE_PATTERNS = *.py \ - *.PY -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXCLUDE_SYMBOLS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = YES -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = NO -REFERENCES_RELATION = NO -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = NO -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = reference-html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -HTML_DYNAMIC_SECTIONS = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = NO -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = NO -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -MSCGEN_PATH = -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = YES -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = /usr/bin/ -DOTFILE_DIRS = -DOT_GRAPH_MAX_NODES = 50 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = NO diff --git a/doc/Makefile b/doc/Makefile index 3449de1..1bf2b91 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,7 +4,7 @@ # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= -SPHINXBUILD ?= python -m sphinx +SPHINXBUILD ?= python3 -m sphinx SOURCEDIR = . BUILDDIR = _build diff --git a/doc/README.txt b/doc/README.txt deleted file mode 100644 index d951574..0000000 --- a/doc/README.txt +++ /dev/null @@ -1,24 +0,0 @@ -by now the documentation creation is not automatized... - -# html reference -# requires dot and doxygen - -cd doc -ln -s ../src damaris -doxygen Doxyfile -rm damaris - -# todo: copy damaris logo - -# html wiki export -# requires moinmoin and damaris/data as wikidata - -cd doc -# underlay must be writable, so we have to copy it... -cp -r /usr/share/moin/underlay wikiunderlay -python dump_wiki.py -cp -r /usr/share/moin/htdocs/modern tutorial-html -rm -r wikiunderlay wikiconfig.py - -# get useful numpy doc -wget http://www.scipy.org/Numpy_Example_List_With_Doc?action=print diff --git a/doc/bibdesk_db.bib b/doc/bibdesk_db.bib new file mode 100644 index 0000000..987fa2a --- /dev/null +++ b/doc/bibdesk_db.bib @@ -0,0 +1,572 @@ +%% This BibTeX bibliography file was created using BibDesk. +%% http://bibdesk.sourceforge.net/ + + +%% Created for Markus Rosenstihl at 2006-12-19 09:26:29 +0100 + + +%% Saved with string encoding Western (ASCII) + + + +@article{JohnsonJr.:1999qy, + Author = {Johnson Jr. , C. S. }, + Date-Added = {2006-12-19 09:09:29 +0100}, + Date-Modified = {2006-12-19 09:26:29 +0100}, + Journal = {Progress in Nuclear Magnetic Resonance Spectroscopy}, + Keywords = {Diffusion ordered NMR, Pulsed magnetic field gradient-NMR experiment, Pulse sequences}, + Number = {3-4}, + Pages = {203--256}, + Title = {Diffusion ordered nuclear magnetic resonance spectroscopy: principles and applications}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6THC-3WPPGH1-1/2/3fa6062ee641585428d7740781b53cce}, + Volume = {34}, + Year = {1999}} + +@book{Gadke:2006fk, + Author = {Achim G{\"a}dke and Christopher Schmitt and Holger Stork and Nikolaus Nestle}, + Booktitle = {8th International Bologna Conference on Magnetic Resonance in Porous Media}, + Date-Added = {2006-12-19 04:09:22 +0100}, + Date-Modified = {2006-12-19 04:15:08 +0100}, + Pages = {P72}, + Title = {DAMARIS -- A Flexible and Open Software Platform for NMR Spectrometer Control}, + Publisher = {N/A}, + Year = {2006}} + +@book{Berger:2004vn, + Author = {Stefan Berger and Siegmar Braun}, + Date-Added = {2006-12-19 01:47:37 +0100}, + Date-Modified = {2006-12-19 01:48:51 +0100}, + Publisher = {Wiley-VCH}, + Title = {200 and More NMR Experiments}, + Year = {2004}} + +@book{Slichter:1978kx, + Author = {Charles P. Slichter}, + Date-Added = {2006-12-18 15:48:35 +0100}, + Date-Modified = {2006-12-18 15:50:03 +0100}, + Publisher = {Springer-Verlag}, + Title = {Principles of Magnetic Resonance}, + Year = {1978}} + +@book{Abragam:1982uq, + Author = {Anatole Abragam}, + Date-Added = {2006-12-18 15:45:37 +0100}, + Date-Modified = {2006-12-18 15:48:18 +0100}, + Edition = {2}, + Keywords = {basics}, + Publisher = {Oxford University Press}, + Title = {Principles of Nuclear Magnetism}, + Year = {1982}} + +@book{Fukushima:1981fk, + Author = {Eiichi Fukushima and Stephen B. W. Roeder}, + Date-Added = {2006-12-17 22:58:59 +0100}, + Date-Modified = {2006-12-17 23:01:22 +0100}, + Publisher = {Westview Press}, + Title = {Experimental Pulse NMR--A Nuts and Bolts Approach}, + Year = {1981}} + +@book{Butz:1998fr, + Author = {Tilman Butz}, + Date-Added = {2006-12-15 12:01:23 +0100}, + Date-Modified = {2006-12-15 12:07:02 +0100}, + Edition = {1}, + Publisher = {Teubner}, + Title = {Fouriertransformation f{\"u}r Fu{\ss}g{\"a}nger}, + Year = {1998}} + +@book{Weiger:rt, + Author = {Markus Weiger and Detlef Moskau and Rainer Kerssebaum and William E. Hull}, + Date-Added = {2006-12-14 18:51:06 +0100}, + Date-Modified = {2006-12-14 18:58:32 +0100}, + Publisher = {Bruker Biospin GmbH}, + Title = {NMR Tips for Shimming}, + Volume = {3}} + +@book{Virginia-W.-Miner:1997yq, + Author = {Virginia W. Miner and Woodrow W. Conover}, + Date-Added = {2006-12-14 18:42:09 +0100}, + Date-Modified = {2006-12-14 18:44:36 +0100}, + Publisher = {Acorn NMR Inc.}, + Title = {The Shimming of High Resolution NMR Magnets}, + Year = {1997}} + +@article{Geil:1998fj, + Abstract = {Nuclear magnetic resonance field gradient methods provide a powerful tool with which to study translational molecular diffusion. Techniques described use the huge static field gradients available in the stray field of superconducting magnets or in specially designed anti-Helmholtz magnets. The experimental concepts and the dynamical ranges of these methods are discussed in detail and carefully compared with established pulsed-field gradient methods. Large-magnitude static field gradients combined with short radiofrequency-pulse spacings give access to very small diffusion coefficients (down to 10-15 m2 s-1) and a high spatial resolution (molecular displacements down to 10 nm). The advantages of static field gradient techniques are demonstrated with several experimental applications selected from the fields of polymer physics, supercooled melts, and biomedical research.}, + Author = {Burkhard Geil}, + Date-Added = {2006-12-13 20:58:13 +0100}, + Date-Modified = {2006-12-17 22:33:24 +0100}, + Journal = {Concepts in Magnetic Resonance}, + Number = {5}, + Pages = {299-321}, + Title = {Measurement of Translational Molecular Diffusion Using Ultrahigh Magnetic Field Gradient NMR}, + Url = {http://dx.doi.org/10.1002/(SICI)1099-0534(1998)10:5<299::AID-CMR3>3.0.CO;2-S}, + Volume = {10}, + Year = {1998}} + +@article{PhysRev.80.580, + Author = {Hahn, E. L.}, + Date-Added = {2006-12-11 16:21:00 +0100}, + Date-Modified = {2006-12-11 16:21:23 +0100}, + Doi = {10.1103/PhysRev.80.580}, + Journal = {Phys. Rev.}, + Month = {Nov}, + Number = {4}, + Numpages = {14}, + Pages = {580--594}, + Publisher = {American Physical Society}, + Title = {Spin Echoes}, + Volume = {80}, + Year = {1950}} + +@article{tanner:2523, + Author = {J. E. Tanner}, + Date-Added = {2006-12-08 15:52:58 +0100}, + Date-Modified = {2006-12-08 15:53:16 +0100}, + Journal = {The Journal of Chemical Physics}, + Number = {5}, + Pages = {2523-2526}, + Publisher = {AIP}, + Title = {Use of the Stimulated Echo in NMR Diffusion Studies}, + Url = {http://link.aip.org/link/?JCP/52/2523/1}, + Volume = {52}, + Year = {1970}} + +@article{Karlicek:1980qy, + Abstract = {An NMR technique for measuring the diffusion constant D in the presence of a large nonuniform background magnetic field gradient G0 is presented. The technique uses a Carr-Purcell-Meiboom-Gill of pulse train that attenuates the effects of diffusion due to the background gradient, interspersed with an alternating pulsed field gradient sequence (APFG) that attenuates the observed echo in the presence of the known applied gradient. Calculations for the observed echo amplitude are presented that show the APFG technique eliminates contributions from the cross term between the background and applied gradients. Results of tests of the technique are presented for the measurement of D in H2O in the presence of G0 \~{} 160 G/cm. Also described are the results of preliminary measurements of D in LaNi5H6; D = (6.2 +/- 0.5) x 10-8 cm2/see at 331.2 K and G0 \~{} 2.9 kG/cm.}, + Author = {Karlicek, Jr. , R. F. and Lowe, I. J.}, + Date-Added = {2006-12-08 15:35:55 +0100}, + Date-Modified = {2006-12-17 22:23:54 +0100}, + Journal = {Journal of Magnetic Resonance (1969)}, + Number = {1}, + Pages = {75--91}, + Title = {A Modified Pulsed Gradient Technique for Measuring Diffusion in the Presence of Large Background Gradients}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CV99DJ-SV/2/145723cbb9920cf9f29e16a10977ae5e}, + Volume = {37}, + Year = {1980}} + +@book{Stroustrup:2000fk, + Author = {Bjarne Stroustrup}, + Date-Added = {2006-12-08 10:53:57 +0100}, + Date-Modified = {2006-12-08 10:58:20 +0100}, + Keywords = {c++}, + Publisher = {Addison-Wesley}, + Title = {The C++ Programming Language}, + Year = {2000}} + +@article{Traficante:1987fk, + Abstract = {In a variety of fields of spectroscopy, many apodization functions are presently available that can be used to multiply a time-domain signal, so that after Fourier transformation the resolution will be improved, in the sense that the linewidths will be reduced in the frequency domain. Until recently, these functions increased either the resolution or the signal-to-noise ratio (S/N), and always one at the expense of the other. Recently a function that may be used to increase either resolution, S/N, or both simultaneously was introduced. A mathematical explanation of how the function operates is presented, along with an improved version of the original form. Results are reported that demonstrate an increase in SIN of up to a factor of two, while simultaneously increasing resolution. Also presented are some problems that may arise from the use of this function, as well as a comparison with the commonly used Gaussian apodization.}, + Author = {Traficante, Daniel D. and Nemeth, Gregory A.}, + Date-Added = {2006-11-30 14:41:06 +0100}, + Date-Modified = {2006-12-17 22:25:01 +0100}, + Journal = {Journal of Magnetic Resonance (1969)}, + Keywords = {TRAF window functions}, + Number = {2}, + Pages = {237--245}, + Title = {A New and Improved Apodization Function for Resolution Enhancement in NMR Spectroscopy}, + Ty = {JOUR}, + Url = {https://doi.org/10.1016/0022-2364(87)90053-9}, + Volume = {71}, + Year = {1987}} + +@article{Hurlimann:2001lr, + Abstract = {We analyze the evolution of magnetization following any series of radiofrequency pulses in strongly inhomogeneous fields, with particular attention to diffusion and relaxation effects. When the inhomogeneity of the static magnetic field approaches or exceeds the strength of the RF field, the magnetization has contributions from different coherence pathways. The diffusion or relaxation induced decay of the signal amplitude is in general nonexponential, even if the sample has single relaxation times T1, T2 and a single diffusion coefficient D. In addition, the shape of the echo depends on diffusion and relaxation. It is possible to separate contributions from different coherence pathways by phase cycling of the RF pulses. The general analysis is tested on stray field measurements using two different pulse sequences. We find excellent agreement between measurements and calculations. The inversion recovery sequence is used to study the relaxation effects. We demonstrate two different approaches of data analysis to extract the relaxation time T1. Finite pulse width effects on the timing of the echo formation are also studied. Diffusion effects are analyzed using the Carr-Purcell-Meiboom-Gill sequence. In a stray field of a constant gradient g, we find that unrestricted diffusion leads to nonexponential signal decay versus echo number N, but within experimental error the diffusion attenuation is still only a function of g2Dt3EN, where tE is the echo spacing.}, + Author = {Hurlimann, M. D.}, + Date-Added = {2006-11-29 22:15:02 +0100}, + Date-Modified = {2006-11-29 22:15:53 +0100}, + Journal = {Journal of Magnetic Resonance}, + Keywords = {stray field NMR, relaxation, diffusion, CPMG}, + Number = {2}, + Pages = {367--378}, + Title = {Diffusion and Relaxation Effects in General Stray Field NMR Experiments}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6WJX-457VFD9-5X/2/c1b8eef6563bc75c1bd5a3aff293285a}, + Volume = {148}, + Year = {2001}} + +@article{VasenkovS._jp003899f, + Author = {Vasenkov, S. and Bohlmann, W. and Galvosas, P. and Geier, O. and Liu, H. and Karger, J.}, + Date-Added = {2006-09-08 14:54:07 +0200}, + Date-Modified = {2006-09-08 14:54:26 +0200}, + Journal = {Journal of Physical Chemistry B}, + Number = {25}, + Pages = {5922-5927}, + Title = {PFG NMR Study of Diffusion in MFI-Type Zeolites: Evidence of the Existence of Intracrystalline Transport Barriers}, + Url = {http://dx.doi.org/10.1021/jp003899f}, + Volume = {105}, + Year = {2001}} + +@article{PhysRevB.45.143, + Author = {Mitra, Partha P. and Sen, Pabitra N.}, + Date-Added = {2006-09-06 15:08:24 +0200}, + Date-Modified = {2006-09-06 15:09:38 +0200}, + Doi = {10.1103/PhysRevB.45.143}, + Journal = {Phys. Rev. B}, + Month = {Jan}, + Number = {1}, + Numpages = {13}, + Pages = {143--156}, + Publisher = {American Physical Society}, + Title = {Effects of microgeometry and surface relaxation on NMR pulsed-field-gradient experiments: Simple pore geometries}, + Volume = {45}, + Year = {1992}} + +@article{Ammann:1982fk, + Author = {Ammann, Claude and Meier, Pierre and Merbach, AndreE.}, + Date-Added = {2006-09-04 18:51:24 +0200}, + Date-Modified = {2006-09-04 18:52:43 +0200}, + Journal = {Journal of Magnetic Resonance (1969)}, + Number = {2}, + Pages = {319--321}, + Title = {A simple multinuclear NMR thermometer}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CRG6VF-DP/2/930fa4d35a7cde2194604d70cb4cbe54}, + Volume = {46}, + Year = {1982}} + +@article{Gutsze:2005lr, + Abstract = {Necessary conditions for measuring intracrystalline diffusion in small crystal size systems via field-gradient NMR are discussed. As an illustrative case self-diffusion coefficients of water adsorbed in NaA zeolites (average crystal diameter about 1 {$[$}mu{$]$}m) have been measured by 1H-NMR stimulated echoes in static magnetic field gradients of up to 180 T/m in the temperature range of 254-344 K. Obtaining intracrystalline diffusion coefficients necessitates a sufficiently high spatial resolution only provided by such large field gradients.}, + Author = {Gutsze, Aleksander and Masierak, Wlodzimierz and Geil, Burkhard and Kruk, Danuta and Pahlke, Hannes and Fujara, Franz}, + Date-Added = {2006-09-04 18:46:43 +0200}, + Date-Modified = {2006-12-17 22:32:44 +0100}, + Journal = {Solid State Nuclear Magnetic Resonance}, + Keywords = {Zeolites, Diffusion, Field-gradient NMR}, + Number = {2-4}, + Pages = {244--249}, + T2 = {Special issue in honor of Prof. Jerzy Blicharski}, + Title = {On the Problem of Field-Gradient NMR Measurements of Intracrystalline Diffusion in Small Crystallites--Water in NaA Zeolites as an Example}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6THK-4HNSJHK-1/2/505f1d77590a9aa708c87b84356e583d}, + Volume = {28}, + Year = {2005}} + +@article{Codd:1999kx, + Abstract = {A simple matrix formalism presented by Callaghan {$[$}J. Magn. Reson.129, 74-84 (1997){$]$}, and based on the multiple propagator approach of Caprihanet al.{$[$}J. Magn. Reson. A118, 94-102 (1996){$]$}, allows for the calculation of the echo attenuation,E(q), in spin echo diffusion experiments, for practically all gradient waveforms. We have extended the method to the treatment of restricted diffusion in parallel plate, cylindrical, and spherical geometries, including the effects of fluid-surface interactions. In particular, theq-space coherence curves are presented for the finite-width gradient pulse PGSE experiment and the results of the matrix calculations compare precisely with published computer simulations. It is shown that the use of long gradient pulses ({$[$}delta{$]$} \~{}a2/D) create the illusion of smaller pores if a narrow pulse approximation is assumed, while ignoring the presence of significant wall relaxation can lead to both an underestimation of the pore dimensions and a misidentification of the pore geometry.}, + Author = {Codd, S. L. and Callaghan, P. T.}, + Date-Added = {2006-09-04 13:31:33 +0200}, + Date-Modified = {2006-09-04 13:31:50 +0200}, + Journal = {Journal of Magnetic Resonance}, + Number = {2}, + Pages = {358--372}, + Title = {Spin Echo Analysis of Restricted Diffusion under Generalized Gradient Waveforms: Planar, Cylindrical, and Spherical Pores with Wall Relaxivity}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6WJX-45FKS2F-58/2/3afb0da70e7f67b52aa3f841799d54a7}, + Volume = {137}, + Year = {1999}} + +@article{hinshaw:3709, + Author = {Waldo S. Hinshaw}, + Date-Added = {2006-09-04 13:27:05 +0200}, + Date-Modified = {2006-09-04 13:27:18 +0200}, + Journal = {Journal of Applied Physics}, + Number = {8}, + Pages = {3709-3721}, + Publisher = {AIP}, + Title = {Image formation by nuclear magnetic resonance: The sensitive-point method}, + Url = {http://link.aip.org/link/?JAP/47/3709/1}, + Volume = {47}, + Year = {1976}} + +@article{0022-3735-11-4-001, + Abstract = {Diffusion and flow can be measured very delicately and accurately using an NMR system. The essence of the method is that motion of magnetic nuclei in a magnetic field and a magnetic gradient results in those nuclei changing their Larmor precession frequency and their phase angle in the field. Since NMR can be set up to measure the number of nuclei at specific phase angles, the motion of groups of nuclei can be determined very accurately. Self-diffusion of molecules was first measured by Hahn in 1950. Self-diffusion of molecules and flow of molecules can be separated in an NMR measurement as was shown by Carr and Purcell in 1954. This review describes some techniques of NMR diffusion and flow measurements, and a method of plotting phase angles of isochromatic spin groups for theoretical analyses and simulations of NMR experiments. }, + Author = {J R Singer}, + Date-Added = {2006-09-04 13:21:22 +0200}, + Date-Modified = {2006-09-04 13:21:44 +0200}, + Journal = {Journal of Physics E: Scientific Instruments}, + Number = {4}, + Pages = {281-291}, + Title = {NMR diffusion and flow measurements and an introduction to spin phase graphing}, + Url = {http://stacks.iop.org/0022-3735/11/281}, + Volume = {11}, + Year = {1978}} + +@article{PhysRevB.1.2048, + Abstract = {A theoretical and experimental study is made of the response of a two-ingredient spin system when repeatedly pulsed at resonance by a number of 90$\,^{\circ}$ rf pulses. With a long train of 90$\,^{\circ}$ pulses, a sustained chain of solid echoes was produced for Na23 in NaF. The peak echo amplitude was found to decay nonexponentially for short times (i.e., the first few echoes), settling down for long times to an exponential decay characterized by a time constant T2?. A theoretical expression for T2? derived in a similar manner to that for a single-ingredient spin system, described previously by Waugh and Wang and by Mansfield and Ware, does not fit the experimental data. A more general theoretical approach to the multiple-pulse experiments is developed, based on the use of a logarithmic operator. Using this formalism together with a line-narrowing model similar to Anderson's theory of spectral line narrowing in solids in the presence of an exchange interaction, a new expression for T2? is derived. Some related long-pulse experiments have been performed in which the Na23 magnetization following an initial 90$\,^{\circ}$ pulse is spin-locked in a low rf field. These experiments simulate the mean rf field in the multiple-pulse experiment. Oscillation of the spin-locked magnetization is observed. Theoretical expressions are derived which describe these oscillations, and their relation to the multiple-pulse experiments is discussed. Mentioned briefly are some multiple-pulse experiments on F19 in CaF2 doped with paramagnetic impurities; also discussed briefly are some earlier multiple-pulse double-resonance experiments carried out on both nuclear species in NaF.}, + Author = {Mansfield, P. and Richards, K. H. B. and Ware, D.}, + Date-Added = {2006-09-04 13:15:31 +0200}, + Date-Modified = {2006-09-04 13:15:52 +0200}, + Doi = {10.1103/PhysRevB.1.2048}, + Journal = {Phys. Rev. B}, + Month = {Mar}, + Number = {5}, + Numpages = {15}, + Pages = {2048--2063}, + Publisher = {American Physical Society}, + Title = {NMR Spin Dynamics in Solids. II. Pulse Experiments in Two-Spin-Species Systems}, + Volume = {1}, + Year = {1970}} + +@article{PhysRev.168.318, + Abstract = {An experimental and theoretical study is made of the response of a single-magnetic-species spin system to a coherent train of resonant 90$\,^{\circ}$ rf pulses of spacing 2?, following at time ? an initial preparatory 90$\,^{\circ}$ pulse. The rf phase of the coherent pulses is shifted 90$\,^{\circ}$ with respect to the initial pulse. It is shown that this pulse sequence will produce a sustained "solid-echo" chain for times much greater than T2, i.e., approaching the spin-lattice relaxation time. This therefore shows promise as a new method of chemical-shift measurement in solids, as well as a direct method of measuring the rotating-frame spin-lattice relaxation time T1?. Except for a small initial oscillation, the amplitudes of successive even or odd echo maxima in CaF2 are found to decay exponentially with a time constant T2?. It is shown theoretically that a simple diagonal assumption for the density matrix plus the rotational symmetry properties of the dipolar Hamiltonian to 90$\,^{\circ}$ pulses could explain the observed ?-5 dependence of T2? as well as the oscillatory effect. Numerical evaluation of the magnitude of T2? based on a cumulant-moment approximation gives good agreement with experiment. + +Further related experiments have been performed by spin-locking the F19 magnetization in long pulses of low amplitude. These experiments are intended to simulate the multiple-pulse sequences by replacing the coherent-pulse train with its mean field. The results reveal considerable oscillatory effects due to mutual exchange of energy between the Zeeman and dipolar subsystems in the rotating reference frame. A theoretical analysis is given which supports these effects. An estimate is made of the Zeeman dipolar cross-relaxation time, and is compared with Provotorov's theory as modified by Walstedt. + +In the multiple-pulse experiment, the "solid-echo" amplitude modulation may be ascribed to mutual energy exchange between the rf Zeeman energy in the zeroth Fourier harmonic of the pulse train (the mean pulse field) and the dipolar energy. Because of the higher harmonics in the Fourier expansion, however, the initial oscillatory effects disappear as ? increases.}, + Author = {Mansfield, P. and Ware, D.}, + Date-Added = {2006-09-04 13:14:11 +0200}, + Date-Modified = {2006-09-04 13:16:18 +0200}, + Doi = {10.1103/PhysRev.168.318}, + Journal = {Phys. Rev.}, + Month = {Apr}, + Number = {2}, + Numpages = {16}, + Pages = {318--334}, + Publisher = {American Physical Society}, + Title = {NMR Spin Dynamics in Solids. I. Artificial Line Narrowing and Zeeman Spin-Spin Relaxation in the Rotating Frame}, + Volume = {168}, + Year = {1968}} + +@article{PhysRevB.12.3618, + Author = {Mansfield, P. and Grannell, P. K.}, + Date-Added = {2006-09-04 11:57:37 +0200}, + Date-Modified = {2006-09-04 11:57:54 +0200}, + Doi = {10.1103/PhysRevB.12.3618}, + Journal = {Phys. Rev. B}, + Month = {Nov}, + Number = {9}, + Numpages = {16}, + Pages = {3618--3634}, + Publisher = {American Physical Society}, + Title = {"Diffraction" and microscopy in solids and liquids by NMR}, + Volume = {12}, + Year = {1975}} + +@article{Hrovat:1981fj, + Abstract = {In NMR diffusion measurements, the application of pulsed magnetic field gradients can produce additional magnetic field gradients, residual gradients, which decay slowly after the pulse. Results indicate that at least two types of residual gradients are present. These are quantitatively measured and analyzed. The consequences of their presence have been carefully examined with significant results for Fourier transform experiments and pulsed gradient calibration. For example, multicomponent systems may mistakenly exhibit different diffusion rates for each component when Fourier transform techniques are used. The residual gradient, since it distorts the background magnetic field gradient, may increase the sensitivity to mismatch of the pulsed gradients as well as affect the calibration of the pulsed gradient. It is demonstrated that the lineshape can be an accurate indicator of the magnetic field gradient. Several factors which may distort the lineshape are analyzed and found not to be critical. As a consequence of these findings, an optimal procedure is described for the measurement of diffusion rates using the pulsed gradient method.}, + Author = {Hrovat, Mirko I. and Wade, Chas G.}, + Date-Added = {2006-09-04 11:54:48 +0200}, + Date-Modified = {2006-09-04 11:55:03 +0200}, + Journal = {Journal of Magnetic Resonance (1969)}, + Number = {1}, + Pages = {67--80}, + Title = {NMR pulsed gradient diffusion measurements. II. Residual gradients and lineshape distortions}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CV97PK-57/2/8b73eaae5fa697df67062125bbf77675}, + Volume = {45}, + Year = {1981}} + +@article{Hrovat:1981uq, + Abstract = {The effect of a steady gradient (g0) on the stability of the spin echo in NMR pulsed-gradient (g) diffusion measurements was examined quantitatively and shown to give an improvement in stability if g0 {$|$}{$|$} g. The results also yield a method to determine directly, without the use of a reference compound, g and the angle between g and g0 through the use of an intentional mismatch of gradient pulses. Experimental results on water and glycerine verify the applicability of this technique.}, + Author = {Hrovat, Mirko I. and Wade, Charles G.}, + Date-Added = {2006-09-04 11:53:38 +0200}, + Date-Modified = {2006-09-04 11:53:53 +0200}, + Journal = {Journal of Magnetic Resonance (1969)}, + Number = {1}, + Pages = {62--75}, + Title = {NMR pulsed-gradient diffusion measurements. I. Spin-echo stability and gradient calibration}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CV9BMD-172/2/59bfe4c39bad9763b825d12be107c046}, + Volume = {44}, + Year = {1981}} + +@article{Marion-Fischer:2004fk, + Abstract = {This paper reports on the upgrading of a standard solid state NMR spectrometer, which has been used in combination with a field variable 7 T cryomagnet, to a low-cost combined SFG and PFG NMR spectrometer. Both methods are applied to solid lithium as a simple test case. The results show that under the given conditions SFG NMR and PFG NMR can provide tracer diffusion coefficients for 7Li diffusion down to about 10-14 and 10-13 m2/s, respectively. SFG and PFG NMR are complementary methods. The paper demonstrates advantages and disadvantages of each method with a concrete example and why it is desirable to be able to apply both methods to the same sample.}, + Author = {Marion Fischer, D. and Duwe, Peter and Indris, Sylvio and Heitjans, Paul}, + Date-Added = {2006-09-04 11:51:18 +0200}, + Date-Modified = {2006-09-04 11:51:35 +0200}, + Journal = {Solid State Nuclear Magnetic Resonance}, + Keywords = {Diffusion, Lithium, SFG NMR, PFG NMR}, + Number = {2}, + Pages = {74--83}, + Title = {Tracer diffusion measurements in solid lithium: a test case for the comparison between NMR in static and pulsed magnetic field gradients after upgrading a standard solid state NMR spectrometer}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6THK-4C47M0W-2/2/1326b04f87facd2d6e49738bf3b6f2eb}, + Volume = {26}, + Year = {2004}} + +@article{Sorland:1997lr, + Author = {Sorland, Geir Humborstad}, + Date-Added = {2006-09-04 11:48:47 +0200}, + Date-Modified = {2006-09-04 11:49:12 +0200}, + Journal = {Journal of Magnetic Resonance}, + Number = {1}, + Pages = {146--148}, + Title = {Short-Time PFGSTE Diffusion Measurements}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6WJX-45NJPN6-N/2/fe7f5766085cc329540b5fbbf4f0b7c2}, + Volume = {126}, + Year = {1997}} + +@article{stejskal:3597, + Author = {E. O. Stejskal}, + Date-Added = {2006-09-04 11:45:19 +0200}, + Date-Modified = {2006-09-04 11:46:14 +0200}, + Journal = {The Journal of Chemical Physics}, + Number = {10}, + Pages = {3597-3603}, + Publisher = {AIP}, + Title = {Use of Spin Echoes in a Pulsed Magnetic-Field Gradient to Study Anisotropic, Restricted Diffusion and Flow}, + Url = {http://link.aip.org/link/?JCP/43/3597/1}, + Volume = {43}, + Year = {1965}} + +@article{tanner:1768, + Author = {J. E. Tanner and E. O. Stejskal}, + Date-Added = {2006-09-04 11:41:04 +0200}, + Date-Modified = {2006-09-04 11:42:02 +0200}, + Journal = {The Journal of Chemical Physics}, + Number = {4}, + Pages = {1768-1777}, + Publisher = {AIP}, + Title = {Restricted Self-Diffusion of Protons in Colloidal Systems by the Pulsed-Gradient, Spin-Echo Method}, + Url = {http://link.aip.org/link/?JCP/49/1768/1}, + Volume = {49}, + Year = {1968}} + +@article{PhysRev.94.630, + Author = {Carr, H. Y. and Purcell, E. M.}, + Date-Added = {2006-09-04 11:20:51 +0200}, + Date-Modified = {2006-09-04 11:21:28 +0200}, + Doi = {10.1103/PhysRev.94.630}, + Journal = {Phys. Rev.}, + Keywords = {diffusion, CPMG}, + Month = {May}, + Number = {3}, + Numpages = {8}, + Pages = {630--638}, + Publisher = {American Physical Society}, + Title = {Effects of Diffusion on Free Precession in Nuclear Magnetic Resonance Experiments}, + Volume = {94}, + Year = {1954}} + +@phdthesis{Galvosas:2003sz, + Author = {Petrik Galvosas}, + Date-Added = {2006-08-29 17:00:39 +0200}, + Date-Modified = {2006-08-29 20:19:27 +0200}, + Keywords = {PFG, ultra-high, diffusion}, + School = {University of Leipzig}, + Title = {PFG NMR-Diffusionsuntersuchungen mit ultra-hohen gepulsten magnetischen Feldgradienten an mikropor{\"o}sen Materialien}, + Url = {http://lips.informatik.uni-leipzig.de:80/pub/2003-6}, + Year = {2003}} + +@article{Galvosas:2001es, + Author = {Galvosas, Petrik and Stallmach, Frank and Seiffert, Gunter and Karger, Jorg and Kaess, Udo and Majer, Gunter}, + Date-Added = {2006-08-29 16:56:32 +0200}, + Date-Modified = {2006-08-29 20:19:27 +0200}, + Journal = {Journal of Magnetic Resonance}, + Keywords = {PFG, ultra-high}, + Number = {2}, + Pages = {260--268}, + Title = {Generation and Application of Ultra-High-Intensity Magnetic Field Gradient Pulses for NMR Spectroscopy}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6WJX-457VFHS-85/2/43c757f8a9cc84818e7e6400dc19023e}, + Volume = {151}, + Year = {2001}} + +@article{Cotts:1989yd, + Author = {Cotts, R. M. and Hoch, M. J. R. and Sun, T. and Markert, J. T.}, + Date-Added = {2006-08-29 16:40:31 +0200}, + Date-Modified = {2006-12-17 22:21:49 +0100}, + Journal = {Journal of Magnetic Resonance (1969)}, + Keywords = {PFG, pulse sequences}, + Number = {2}, + Pages = {252--266}, + Title = {Pulsed Field Gradient Stimulated Echo Methods for Improved NMR Diffusion Measurements in Heterogeneous Systems}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CRGCX0-1X/2/8eb7862763da12f1a7b9693e870a4921}, + Volume = {83}, + Year = {1989}} + +@article{0022-3735-19-9-012, + Abstract = {To restore nuclear magnetic resonance (NMR) signals distorted by read-out gradient transients, it is necessary to know the time shape of the gradient. The authors show that the time shape of the gradient can be evaluated by using the ratio of free induction decay (FID) to its first derivative coming from a small sample placed inside the RF coil. In computer simulation and experiments, the gradients obtained using this approximation of the actual solution agreed well with the true gradients. The advantages to the method proposed here are: no additional apparatus is required to measure the gradient and the method may be utilised even for very small bore magnets without degrading gradient performance. }, + Author = {E Yamamoto and H Kohno}, + Date-Added = {2006-08-29 16:20:26 +0200}, + Date-Modified = {2006-08-29 20:19:27 +0200}, + Journal = {Journal of Physics E: Scientific Instruments}, + Keywords = {PFG, shape}, + Number = {9}, + Pages = {708-711}, + Title = {Gradient time-shape measurement by NMR}, + Url = {http://stacks.iop.org/0022-3735/19/708}, + Volume = {19}, + Year = {1986}} + +@article{stejskal:288, + Author = {E. O. Stejskal and J. E. Tanner}, + Date-Added = {2006-08-29 16:14:30 +0200}, + Date-Modified = {2006-09-04 11:16:51 +0200}, + Journal = {The Journal of Chemical Physics}, + Keywords = {diffusion, NMR}, + Number = {1}, + Pages = {288-292}, + Publisher = {AIP}, + Title = {Spin Diffusion Measurements: Spin Echoes in the Presence of a Time-Dependent Field Gradient}, + Url = {http://link.aip.org/link/?JCP/42/288/1}, + Volume = {42}, + Year = {1965}} + +@article{Holz:2000ma, + Author = {Manfred Holz and Stefan R. Heil and Antonio Sacco}, + Date-Added = {2006-08-29 16:07:39 +0200}, + Date-Modified = {2006-12-17 22:22:57 +0100}, + Doi = {10.1039/b005319h}, + Journal = {Phys. Chem. Chem. Phys.}, + Keywords = {calibration, PFG, diffusion}, + Number = {4740 - 4742}, + Pages = {3}, + Read = {Yes}, + Title = {Temperature-dependent Self-diffusion Coefficients of Water and Six Selected Molecular Liquids for Calibration in Accurate 1H NMR PFG Measurements}, + Url = {http://www.rsc.org/publishing/journals/CP/article.asp?doi=b005319h#}, + Volume = {2}, + Year = {2000}} + +@article{PhysRev.111.1201, + Author = {Simpson, J. H. and Carr, H. Y.}, + Date-Added = {2006-08-29 16:04:25 +0200}, + Date-Modified = {2006-09-04 13:17:32 +0200}, + Doi = {10.1103/PhysRev.111.1201}, + Journal = {Phys. Rev.}, + Keywords = {diffusion, calibration, NMR}, + Month = {Sep}, + Number = {5}, + Numpages = {1}, + Pages = {1201--1202}, + Publisher = {American Physical Society}, + Title = {Diffusion and Nuclear Spin Relaxation in Water}, + Volume = {111}, + Year = {1958}} + +@article{Holz:1991ax, + Author = {Holz, M. and Weingartner, H.}, + Date-Added = {2006-08-29 15:19:20 +0200}, + Date-Modified = {2006-12-17 22:23:15 +0100}, + Journal = {Journal of Magnetic Resonance (1969)}, + Keywords = {calibration, PFG}, + Number = {1}, + Pages = {115--125}, + Title = {Calibration in Accurate Spin-Echo Self-diffusion Measurements using 1H and Less-common Nuclei}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B7GXD-4CV9BT5-18W/2/30df5212540d1990c32f5e11d0e67cdf}, + Volume = {92}, + Year = {1991}} + +@article{Pampel:2006ur, + Author = {Pampel, A. and Engelke, F. and Galvosas, P. and Krause, C. and Stallmach, F. and Michel, D. and Karger, J.}, + Date-Added = {2006-08-29 14:59:44 +0200}, + Date-Modified = {2006-12-17 22:24:25 +0100}, + Journal = {Microporous and Mesoporous Materials}, + Keywords = {MAS, PFG, NMR, Diffusion, Zeolites}, + Number = {1-3}, + Pages = {271--277}, + T2 = {Dedicated to the late Denise Barthomeuf, George Kokotailo and Sergey P. Zhdanov in appreciation of their outstanding contributions to zeolite science}, + Title = {Selective Multi-component Diffusion Measurement in Zeolites by Pulsed Field Gradient NMR}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6TH4-4HC0R8J-2/2/11f8e3996d1393af9d088024b21a329f}, + Volume = {90}, + Year = {2006}} + +@article{Galvosas:2001fi, + Author = {Galvosas, P. and Stallmach, F. and Seiffert, G. and Karger, J.}, + Date-Added = {2006-08-29 14:59:44 +0200}, + Date-Modified = {2006-09-04 13:35:37 +0200}, + Journal = {Magnetic Resonance Imaging}, + Keywords = {PFG,NMR,stability}, + Number = {3-4}, + Pages = {575--575}, + Title = {Overcoming mechanical and electronic instabilities in diffusion measurements with very high PFG-intensities}, + Ty = {JOUR}, + Url = {http://www.sciencedirect.com/science/article/B6T9D-43DK85F-2R/2/dd8b9912ea73115e7fdbbaa26bb7c182}, + Volume = {19}, + Year = {2001}} diff --git a/doc/conf.py b/doc/conf.py index 42d12d7..485bb67 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -21,7 +21,11 @@ release = '0.19' extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.napoleon', + 'sphinxcontrib.bibtex', ] +bibtex_bibfiles = ['bibdesk_db.bib'] +bibtex_bibstyles = ['numeric'] +bibtex_citestyle = 'numeric' templates_path = ['_templates'] exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] diff --git a/doc/devel.rst b/doc/devel.rst new file mode 100644 index 0000000..389628e --- /dev/null +++ b/doc/devel.rst @@ -0,0 +1,186 @@ +.. _advanced: + +###################### +DAMARIS for Developers +###################### + +This chapter is dealing with the internals of DAMARIS. After an introduction of the back end, it is in more detail described how the Tecmag DAC20 driver is operating and how it has been implemented into DAMARIS. The complete source code of DAMARIS is available in a subversion source repository for convenient access at http://www.fkp.physik.tu-darmstadt.de/damaris. + +************ +The Back End +************ + +The front end is responsible for writing experiment description files (job files) in XML format. + +.. figure:: pics/damaris_interaction.svg + :alt: Traversing machine + :width: 100% + +Starting the experiment will execute the back end which will start polling the given spool directory for new XML job files. These numbered files are containing a sequence composed of states, which themselves contain instructions for the experiment, or sub-sequences (which can contain further states or sub-sequences and can be looped). + +A state defines the output (24 bits) of the pulse programmer and can be either empty or contain sub-elements (state atoms), which for example could be an instruction to set a channel on the pulse programmer or set the DAC for a PFG current source. + +The back end examines this XML job files and traverses the state sequence. Encountering a sub-sequence, this is traversed to its end, where the back end jumps out of the sub-sequence and continues where it entered the sub-sequence. This traversing is called *depth-first*, and causes this nested *state tree* to be processed sequentially in order. + +As an example the pulse sequence π-wait-pfg-wait-π-(wait-π-wait-π)n will be explained in depth. Once this pulse sequence is written in the DAMARIS front end, it results in a XML file. + +.. code-block:: xml + :caption: XML job containing a loop + + + + + + + + + + + + + + + + + + + +.. figure:: pics/traversing_example2.png + :alt: Traversing example + :width: 100% + + The XML file represented as a state tree. Elements are numbered in the order of the traversing. The loop is only traversed once, despite that the elements inside the loop will be executed repeatedly in the experiment. + +Each driver in the back end (PTS synthesizer, PFG, etc.) is traversing this tree, searching for elements it is responsible for. The driver then translates these elements in pure states for the pulse programmer, i.e. TTL signals. Then, the next driver is traversing the tree, translating the elements it is responsible for. This is going on until all elements from the tree are translated into states, which are then written in machine code to the pulse programmer and executed. + +.. figure:: pics/traversing_machine.svg + :alt: Traversing machine + :width: 100% + + Part of the state tree where the element of the state dealing with PFG was translated + +Any result obtained by the back end is written to the corresponding XML result file (job filename + .result). + +The DAC driver +============== + +If in a state an *analogout* element with suitable ID is encountered, the DAC driver extracts the integer value for the gradient strength. The integer value is translated to binary representation, and the single bits are transferred to the DAC. Then, the time of the state is shortened by the time needed to transfer the complete data to the DAC. Every pulse necessary for transferring the data is created by the pulse programmer. + +Transferring the data to the DAC is achieved by three lines, notably LE (latch enable), CLK (clock signal) and DATA (data line). Reading in a DAC word goes as follows: LE stays high, a data bit is read in with the falling edge of the clock signal, i.e. CLK high to CLK low. After the last (20th) bit is recorded, LE is going low thus signaling the DAC that the word is complete. + +.. code-block:: c++ + :caption: Main logic of the DAC driver + :linenos: + + // Main logic of the DAC driver + void DAC20::send_word(int value) { + // Set LE high + set_pin(LE, HIGH); + + // Transfer 20 bits + for (int i = 0; i < 20; i++) { + // Set data bit + set_pin(DATA, (value >> i) & 1); + + // Clock falling edge + set_pin(CLK, HIGH); + delay_ns(180); + set_pin(CLK, LOW); + } + + // Set LE low to complete + set_pin(LE, LOW); + } + +This procedure was first tested and further refined in Python. Embedding the driver properly in the DAMARIS back end made it necessary to translate the test program to C++ code. The following files of the back end needed to be modified or created: + +- drivers/pfggen.h +- drivers/Tecmag-DAC20/DAC20.cpp +- drivers/Tecmag-DAC20/DAC20.h + +These three files are the main part of the driver. They contain the main logic for the DAC serial line. + +- machines/hardware.cpp +- machines/hardware.h +- machines/PFGcore.cpp + +Finally, these last files contain the spectrometer setup information, i.e. which frequency synthesizer, ADC card, pulse programmer or temperature controller is used. The resulting PFGcore.exe is the back end which is executed by the front end and has to be specified in the configuration tab. + +.. code-block:: c++ + :caption: PFGcore.cpp which defines the spectrometer hardware + :linenos: + + // PFGcore.cpp + #include "hardware.h" + + int main() { + // Initialize hardware + Hardware hw; + hw.setFrequencySynthesizer(new PTS()); + hw.setADCCard(new ADC200()); + hw.setPulseProgrammer(new PulseBlaster()); + hw.setPFG(new DAC20()); + + // Start the backend + hw.run(); + + return 0; + } + +In the front end the following file needed to be modified to be able to use the PFG conveniently: + +- Experiment.py + +This file contains the functions to create a pulse sequence. The command **set_pfg**, which adds the proper XML element to the state tree, has been added. + +.. code-block:: python + :linenos: + + def set_pfg(self, I_out=None, dac_value=None, length=None, is_seq=0): + """This sets the value for the PFG, it also sets it back automatically. + If you don't wish to do so (i.e. line shapes) set is_seq=1""" + if I_out != None: + print "I_out is deprecated" + if I_out == None and dac_value == None: + dac_value = 0 + if I_out != None and dac_value == None: + dac_value = dac.conv(I_out) + if I_out == None and dac_value != None: + dac_value = dac_value + if I_out != None and dac_value != None: + dac_value = 0 + print "WARNING: You can't set both, I_out and dac_value! dac_value set to 0" + if length == None: + # minimum length + length = 42 * 9e-8 + self.state_list.append(' + + \n' % (repr(length), dac_value)) + if is_seq == 0: + # Set the DAC back to zero if this is not part of a sequence + self.state_list.append(' + + \n' % (repr(42 * 9e-8))) + + + +The conversion factor is 50 A/V. The DAC receives the data from the pulse card after the signals are brought into rectangular shape by the cable driver. The bipolar signal is digitally encoded in 2s-complement, i.e. one bit represents the sign of the integer, thus the range of integer values starts from -pow(2, 19) to pow(2, 19)-1. + +The DAC outputs a voltage according to the DAC word until the DAC receives another value. This behavior is important to the experimenter because if one wants to set a value only for a certain time it is necessary to set the value back to zero. In the DAMARIS front end this is done automatically with **set_pfg**\ (dac_value, length) whereas in the back end it is done at the beginning of each experiment to protect the hardware and to set the DAC into a defined state. +Arbitrary shaping of gradient pulses is also possible by using the command **set_pfg**\ (*dac_value*\ , *length*\ , *isseq*\ =1) which prevents setting the DAC to zero after the given length. Through concatenating subsequently **set_pfg**\ (dac_value, length, isseq=1) commands one can create almost any possible shape and/or background gradients. +Shaping the gradients was not the focus of this work but the general function was tested using an oscilloscope at the current monitor of the PFG current source with the DAC creating a sine wave using several resolutions. + +.. figure:: pics/shapegrad1.png + :alt: Shaped PFG pulse + :width: 500px + + A sin² PFG pulse with 1 ms length. The upper one with 100 μs, the lower one with 3.78 μs resolution + +Theoretical resolution is given by approximately 280A/2**19 = 0.000534 A. Transferring in a 20bit word needs 21 cycles where each clock cycle is 180 ns long. This leads to a time resolution of 3.78 μs. Note that each DAC setting needs 42 instructions which can lead to problems regarding the memory of the PulseBlaster in the case of gradient pulse shaping. In figure above, the lower gradient, the maximum time resolution of 3.78 μs was used, there are 264 steps, each of them with 42 states leading to more than 11,000 instructions for this pulsed field gradient alone. + +An improvement would be the use of loops for repeating patterns in the DAC word. The easiest approach would be counting consecutively ones and zeros and write a loop if a one or a zero is repeated, i.e. so called *run-length compression*. Even better would be searching for general patterns and use the best (in respect to memory, the smallest) instruction set. Another way to save instructions is to save the shape as a subprogram on the pulse programmers memory and recall it when it is needed. This possibility is not yet implemented in the pulse programmer driver. + +Stability of the DAC has been tested by measuring the shifts of resonance frequency in a Field Cycling spectrometer where the DAC controlled the magnetic field. The DAC was very stable and the standard deviation of the frequency shift was about 3 kHz and no drifts were visible except for one outlier which is good compared to the usual 6 kHz with the standard field cycling DAC. Further stability measurements using an Agilent 3440 A high resolution multimeter have been also performed. These measurements lead to the conclusion that the DAC is sufficiently stable and temperature drifts do not occur. + +The offset of the PFG amplifier was adjusted via the offset potentiometer on the DAC board. There is also an offset adjustment possible at the PFG amplifier directly. For adjustment, the signal of water in a sample tube with a 0.5 mm teflon stripe perpendicular to the magnetic field B0 was recorded. First, the PFG power supply has been switched off and the sample was shimmed with the room temperature shims until the longest decay time T*2 of the FID has been achieved. After this, the PFG was switched on and the offset has been adjusted to cause least distortion in the spectrum. + diff --git a/doc/dump_wiki.py b/doc/dump_wiki.py deleted file mode 100644 index 680a33e..0000000 --- a/doc/dump_wiki.py +++ /dev/null @@ -1,177 +0,0 @@ -# -*- coding: iso-8859-1 -*- -""" - MoinMoin - Dump a MoinMoin wiki to static pages - - based on "moin.py export dump" command - -""" - -import sys, os, time, StringIO, codecs, shutil, re, errno - -from MoinMoin import config, wikiutil, Page -from MoinMoin.request import RequestCLI -from MoinMoin.action import AttachFile - -HTML_SUFFIX = ".html" - -page_template = u''' - - - -%(pagename)s - - - - - -
-

%(pagename)s

-%(pagehtml)s -
-
-%(timestamp)s - - -''' - -def _attachment(request, pagename, filename, outputdir): - filename = filename.encode(config.charset) - source_dir = AttachFile.getAttachDir(request, pagename) - source_file = os.path.join(source_dir, filename) - dest_dir = os.path.join(outputdir, "attachments", wikiutil.quoteWikinameFS(pagename)) - dest_file = os.path.join(dest_dir, filename) - dest_url = "attachments/%s/%s" % (wikiutil.quoteWikinameFS(pagename), wikiutil.url_quote(filename)) - if os.access(source_file, os.R_OK): - if not os.access(dest_dir, os.F_OK): - try: - os.makedirs(dest_dir) - except: - print ("Cannot create attachment directory '%s'" % dest_dir) - raise - elif not os.path.isdir(dest_dir): - print ("'%s' is not a directory" % dest_dir) - - shutil.copyfile(source_file, dest_file) - print ('Writing "%s"...' % dest_url) - return dest_url - else: - return "" - - -class PluginScript: #(MoinScript): - """ Dump script class """ - - def __init__(self): - pass - - def mainloop(self): - """ moin-dump's main code. """ - - # Prepare output directory - outputdir=os.path.join(os.curdir,"tutorial-html") - try: - os.mkdir(outputdir) - print "Created output directory '%s'!" % outputdir - except OSError, err: - if err.errno != errno.EEXIST: - print "Cannot create output directory '%s'!" % outputdir - raise - - sys.path.insert(0, os.path.abspath(os.curdir)) - - wikiconfig_template=""" -from MoinMoin.multiconfig import DefaultConfig -class Config(DefaultConfig): - sitename = u'DAMARIS Homepage and Usergroup' - logo_string = u'DAMARIS Logo' - page_front_page = u"Welcome" - interwikiname = 'damaris' - data_dir = '%(pwd)s/wikidata/' - data_underlay_dir = '%(pwd)s/wikiunderlay' - url_prefix = '/damaris/wiki' - theme_default = 'modern' -"""%{"pwd": os.curdir, "underlay": "/home/achim/underlay" } - - config_file = open("wikiconfig.py","w") - print >>config_file, wikiconfig_template - config_file.close() - - # start with wiki entry page - request = RequestCLI(pagename="Welcome") - - # fix url_prefix so we get relative paths in output html - url_prefix = "." - request.cfg.url_prefix = url_prefix - - pages = request.rootpage.getPageList(user='') # get list of all pages in wiki - pages.sort() - - # extract a list of pages to be extracted - # trial session to fat!!! - try: - pages_match = re.compile("^(Tutorial|auxiliary tools|overview|installation|code snippets)") - pages = [page for page in pages if pages_match.match(page)] - except: - print "did not find suitable pages" - raise - - wikiutil.quoteWikinameURL = lambda pagename, qfn=wikiutil.quoteWikinameFS: (qfn(pagename) + HTML_SUFFIX) - - AttachFile.getAttachUrl = lambda pagename, filename, request, addts=0, escaped=0: (_attachment(request, pagename, filename, outputdir)) - - errfile = os.path.join(outputdir, 'error.log') - errlog = open(errfile, 'w') - errcnt = 0 - - page_front_page = wikiutil.getSysPage(request, request.cfg.page_front_page).page_name - page_title_index = wikiutil.getSysPage(request, 'TitleIndex').page_name - page_word_index = wikiutil.getSysPage(request, 'WordIndex').page_name - - navibar_html = '' - for p in [page_front_page, page_title_index, page_word_index]: - navibar_html += ' [%s]' % (wikiutil.quoteWikinameURL(p), wikiutil.escape(p)) - - urlbase = request.url # save wiki base url - for pagename in pages: - # we have the same name in URL and FS - file = wikiutil.quoteWikinameURL(pagename) - print ('Writing "%s"...' % file) - try: - pagehtml = '' - request.url = urlbase + pagename # add current pagename to url base - page = Page.Page(request, pagename) - request.page = page - try: - request.reset() - pagehtml = request.redirectedOutput(page.send_page, request, count_hit=0, content_only=1) - except: - errcnt = errcnt + 1 - print >>sys.stderr, "*** Caught exception while writing page!" - print >>errlog, "~" * 78 - print >>errlog, file # page filename - import traceback - traceback.print_exc(None, errlog) - finally: - timestamp = time.strftime("%Y-%m-%d %H:%M") - filepath = os.path.join(outputdir, file) - fileout = codecs.open(filepath, 'w', config.charset) - logo_html = '' - fileout.write(page_template % { - 'charset': config.charset, - 'pagename': pagename, - 'pagehtml': pagehtml, - 'logo_html': logo_html, - 'navibar_html': navibar_html, - 'timestamp': timestamp, - 'theme': request.cfg.theme_default, - }) - fileout.close() - - # ToDo: insert style sheets and logo - - errlog.close() - if errcnt: - print >>sys.stderr, "*** %d error(s) occurred, see '%s'!" % (errcnt, errfile) - -if __name__=="__main__": - PluginScript().mainloop() diff --git a/doc/index.html b/doc/index.html deleted file mode 100644 index f77cfe1..0000000 --- a/doc/index.html +++ /dev/null @@ -1,84 +0,0 @@ - - - - - python-damaris documentation index - - -

DAMARISDAMARIS -Documentation Index
-

-

Local Resources:

-
-Documentation from DAMARIS wiki:
- -python-damaris source code reference (generated by doxygen)
- -

Internet Resources:

- - - diff --git a/doc/index.rst b/doc/index.rst index 7a58957..86b78f6 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -3,30 +3,36 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. + + +##################### DAMARIS documentation -===================== - -Add your content using ``reStructuredText`` syntax. See the -`reStructuredText `_ -documentation for details. - +##################### .. toctree:: - :maxdepth: 2 + :maxdepth: 3 :caption: Contents: -API Reference -------------- + manual + devel +############# +API Reference +############# + +This API reference is generated from the source code. + +*********** Experiments -~~~~~~~~~~~ +*********** .. automodule:: damaris.experiments.Experiment :members: :undoc-members: +************ Data Objects -~~~~~~~~~~~~ +************ .. automodule:: damaris.data.Accumulation :members: @@ -36,3 +42,7 @@ Data Objects :members: :undoc-members: +.. automodule:: damaris.data.DamarisFFT + :members: + :undoc-members: + diff --git a/doc/manual.rst b/doc/manual.rst new file mode 100644 index 0000000..73ce857 --- /dev/null +++ b/doc/manual.rst @@ -0,0 +1,717 @@ +######################### +DAMARIS for Experimenters +######################### + +**DAMARIS** :cite:`Gadke:2006fk` is the software, established by Achim Gädke, used to control the PFG spectrometer. There are two separate parts: the back end, which controls the hardware and executes the pulse program, and a front end where the pulse program is defined and results are displayed. The programming language used for the scripts in the front end is Python, because it is easy to learn and the programs are easy to maintain. + +The DArmstadt MAgnetic Resonance Instrument Software is an in-house developed open-source spectrometer control software which gives every scientist a very versatile and highly flexible instrumentation tool to operate and design novel and/or complex NMR experiments. By using standard pulse programmers and data acquisition PCI and PCIe computer cards this allows any research group a way to build NMR spectrometers in a very cost effective way. +Using open-source computer software to operate the hardware enables the user to get a very detailed understanding and a high level of control over the measurement data acquisition procedure. Unlike many home-built spectrometers and control software which are used specifically and tied to one spectrometer, DAMARIS was designed from the ground up for a flexible use in many different types of spectrometers. Another major design goal was to make the control hardware characteristics transparent to the spectrometer developer. In our group in Darmstadt DAMARIS is used on 9 different spectrometers ranging from Mechanical and Fast Electronic Field Cycling, Static Field Gradient (SFG) NMR as well as Pulsed Field Gradient (PFG) and 2H spectrometers. It is used successfully to measure multidimensional 2H NMR exchange spectra as well as for using shaped pulses (radio frequency and PFG) in other experiments. Beside the use in Darmstadt, DAMARIS is also in use at the Universities of Dortmund and Düsseldorf for time-domain, SFG and PFG spectrometers. +The front end of DAMARIS is user friendly and the usage is not difficult to learn. There is introductory documentation available [1]. The pulse programs are defined and written in Python which is, again, a very user friendly interpreted programming language. Using a full-fledged programming language with a huge amount of freely available libraries and a very active scientific community is a key advantage of using DAMARIS. The use of the scipy and numpy libraries (similar to Matlab) for numerical analysis and data treatment makes it possible, for example, to pre- or post-process data at single-shot or accumulation level using custom filters. Leveraging Python modules for serial communication permits DAMARIS to control auxiliary hardware like temperature controllers of different make and models (Lakeshore, Cryovac, Oxford Instruments, other RS232, Modbus, and GPIB controlled devices), oscilloscopes, magnet drift compensation controller, microprocessors (Arduino, etc.), step motor/piezo positioning systems, and it is even possible to react to and modify the experiments according to feedback from these devices. + + + +****** +Basics +****** +The basic idea in DAMARIS is the separation of an experiment in three steps: + +- Experiment description where the experiment sequence is described +- Back end executes the sequences obtained from the experiment description +- Results from the back end are processed in the result script + +.. figure:: pics/damaris_description.png + :alt: The DAMARIS front end + :width: 600px + + The DAMARIS front end + +The front end is composed of five tabs (see figure above): Experiment, Result, Display, Log and Configuration. This introduction into DAMARIS will begin with a NMR "Hello World" program, i.e. recording a FID. More elaborated techniques like phase cycling and PFG will be discussed in the :ref:`advanced` section. + +Configuration +============= + +.. figure:: pics/config1.png + :alt: Configuration tab + :width: 600px + + Configuration tab + +The Configuration tab (see figure above) offers a convenient way to setup DAMARIS. +Following is a short description of the options: + +1. Toggle the start of the back end +2. Path to the back end executable, here **PFGcore.exe** +3. Path to the spool directory, where the job files will be written or picked up +4. Delete the job files after execution +5. Filename of the logfile +6. Number of logfiles to keep +7. Toggle the start of the experiment script +8. Toggle the start of the result script +9. Toggle the deletion of results after they have been processed by the result script +10. Filename of the data pool file +11. Write interval after which the data pool is rewritten +12. Compression settings +13. Authors, License and version numbers of used components + +Experiment Script +================= +.. code-block:: python + :caption: Experiment script for recording a FID + :linenos: + + from damaris import Experiment + + def fid_experiment(): + e = Experiment() + e.ttl_pulse(length=1e-6, channel=1) + e.wait(time=1e-6) + e.record(samples=8192, frequency=2e6) + return e.get_state_sequence() + + def experiment(): + return fid_experiment() + +On the first line, the basic Experiment module is imported which loads the methods and commands to control an experiment. Next, a function **fid_experiment** is defined which will contain everything necessary to run a single scan. +The first line inside the function creates an object **e** in which the states will be written by subsequent application of methods to this experiment object. This sequence of states is then passed to the caller. +When the "Execute" button is pressed, the experiment script is scanned for a function called **experiment**. +Thus, to run **fid_experiment**, the **experiment** function has to contain a call to the **fid_experiment**. + +Behind the scenes is the experiment script that writes the state sequence from **fid_experiment**, an XML^1^ file, into the spool directory and the back end is then executed. The back end is simply reads these files, translates the contents to pulse programmer code and stores the generated code into the memory of the pulse card. Finally, the pulse program is executed. Then the results are written by the back end into the spool directory, where they are provided to the result script. In the result script, the function **result** is then executed. + +Result Script +============= +The function **result** in the result tab defines what should be done with the results. Here is a short example how to display the recorded signal: + +.. code-block:: python + :caption: Result script which is displaying the result + :linenos: + + from damaris import get_result + + def result(results): + # get the first result + timesignal = results[0] + # display the signal in the graph + data["Timesignal"] = timesignal + +After pressing the "Execute" button to start the experiment, the Display tab is opened. With the drop down menu right to "Source" under the graph window one can choose which data should be displayed. This list is built dynamically by the data dictionary in the result script, where the key denotes the name to be shown and the value contains the data. In this example we overwrite the data in the key **Timesignal** on every scan with the new result. +There are now two possibilities to export the figure: + +1. Saving the plot as a figure (EPS, PNG, JPEG and more) by pressing the save button in the toolbar below the plot area +2. Saving the data of the plot as CSV file (comma separated values) by pressing the button on the right side of the toolbar under the plot + + +Accumulation +============ + +Sometimes the detected signals intensity is low compared to the noise, and can therefore not be seen. A measure for the quality of the recorded signal is the signal-to-noise ratio (SNR) which is defined as the ratio of signal versus the standard deviation of the noise, i.e. noise strength. +The SNR is improved by measuring the signal many times and averaging the recorded signals, also called accumulation. +In DAMARIS this can be achieved by creating a loop in the experiment script and accumulating the results in the result script. + +.. code-block:: python + :caption: Experiment script showing how to create a loop + :linenos: + + from damaris import Experiment + + def accumulate_experiment(): + e = Experiment() + # define how many scans you want + scans = 10 + for i in range(scans): + e.ttl_pulse(length=1e-6, channel=1) + e.wait(time=1e-6) + e.record(samples=8192, frequency=2e6) + return e.get_state_sequence() + + def experiment(): + return accumulate_experiment() + +.. code-block:: python + :caption: Result script accumulating the data + :linenos: + + from damaris import get_result, Accumulation + + def result(results): + akku = Accumulation(error=True) + for timesignal in results: + akku += timesignal + data["Accumulated"] = akku + + +Phase Cycling +============= + +Artifacts due to channel imbalance in the receiver, inhomogeneity in the RF field and unwanted signals, for example primary echos, can be suppressed or cancelled out by cycling the phases :cite:`Berger:2004vn` of the receiver and the RF pulses and then accumulating the signal. + +.. code-block:: python + :caption: Experiment script for phase cycling + :linenos: + + from damaris import Experiment + + def phase_cycling_experiment(): + e = Experiment() + phases = [0, 90, 180, 270] + for phase in phases: + e.set_phase(phase=phase) + e.ttl_pulse(length=1e-6, channel=1) + e.wait(time=1e-6) + e.record(samples=8192, frequency=2e6) + return e.get_state_sequence() + + def experiment(): + return phase_cycling_experiment() + +New in this script is the **set_description** method and a parameter *run* that is passed to the experiment. The **set_description** method is used to set descriptions and values important to the experimenter or to pass values to the result script. These descriptions are written into the XML job file and stored by the back end into the result file. In this way it is possible to pass values to the result script so the latter can act upon these. In this case the result is either added or subtracted to the accumulation variable. + + +Changing Parameters +=================== + +Now, this script is modified to measure the longitudinal relaxation time T1 by a so called inversion recovery experiment. Therefore the π/2-pulse is preceded by π-pulse both separated by the variable time τ. The FID after the second pulse is recorded. In order to get a good signal, accumulation and phase cycling are implemented. +In the result script, the magnetization will be obtained and, together with the corresponding variable τ, stored in an ASCII file for determination of T1. + +.. code-block:: python + :caption: Experiment script illustrating the use of variables + :linenos: + + from damaris import Experiment, lin_range + + def t1_experiment(): + e = Experiment() + for tau in lin_range(start=1e-3, stop=5e-2, step=1e-3): + e.set_description("tau", tau) + e.ttl_pulse(length=1e-6, channel=1) # 180 degree pulse + e.wait(time=tau) + e.ttl_pulse(length=1e-6, channel=1) # 90 degree pulse + e.wait(time=1e-6) + e.record(samples=8192, frequency=2e6) + return e.get_state_sequence() + + def experiment(): + return t1_experiment() + +.. code-block:: python + :caption: Result script writing the amplitude and corresponding delay time τ between the pulses to a file + :linenos: + + from damaris import get_result + + def result(results): + datafile = open("t1_data.dat", "w") + for timesignal in results: + tau = timesignal.get_description('tau') + # calculate magnetization from timesignal + magnetization = calculate_magnetization(timesignal) + datafile.write("%f %f\n" % (tau, magnetization)) + datafile.close() + + + +Data Handling +============= + +To store the result for further data analysis one has several built-in possibilities in DAMARIS. One can store the results as ASCII file or as HDF5 file. Writing an ASCII file is usable for smaller data-sets and a small number of experiments. +The speed-up in post-processing and analysis is already 24 fold in small data-sets with 32768 points per channel and 25 files on a Athlon XP 2600+ CPU with 512 MB RAM running Debian Sarge Linux. Thus, writing HDF5 with compression enabled is highly recommended. Additionally the HDF files are much much smaller than the ASCII files. Nethertheless we can save data in simple text files: + + +.. code-block:: python + :caption: Part of a result script for saving data into an ASCII file + :linenos: + + def result(results): + f = open('testfile.dat', 'w') + timesignal = results[0] + timesignal.write_to_csv(destination=f) + f.close() + + + +For larger experiments it is advantageous to store data in a HDF5 file. This is the Hierarchical Data Format developed by the NCSA (National Center for Supercomputer Applications) for storing complex tables and big amounts of data in an effective way. It supports grouping of data, annotation and compression. A very convenient way to access HDF files in Python is the pyTables module, which is also used by DAMARIS internally. + + +.. container:: image-container + + .. image:: pics/datapool_root.png + :width: 45% + :alt: First image + + .. image:: pics/datapool_root.png + :width: 45% + :alt: Second image + + .. image:: pics/datapool_data.png + :width: 45% + + .. image:: pics/datapool_table.png + :width: 45% + + + + A sample data pool file, opened with HDFCompass. The data is stored as a table (lower right). + + +After an experiment in DAMARIS has been finished, the results in the data dictionary as well as the experiment and result scripts themselves are written automatically to a HDF file, the so called **data pool**. +In the configuration tab (figure above, 10-12), filename, compression ratio, compression library and write interval can be set up. +The write interval is the time after which the data pool file should be periodically rewritten and is useful in case of hardware or experiment failure. +The results from are stored as 64-bit floating point values in tables which are compressed/decompressed on-the-fly when writing/reading. + +.. note:: + You can select from ultiple compression libraries, but for compatibility reasons *zlib* is highly recommended. Compression levels higher than 3 are typically not beneficial. + +A typical method to already extract data like amplitudes etc. is possible by using the MeasurementResult class. + +.. code-block:: python + :linenos: + + from damaris import MeasurementResult + + def fid(): + # create a measurement object + measurement = MeasurementResult("Magnetization(tau)") + for timesignal in results: + # extract "tau" from the description dictionary + tau = timesignal.get_description('tau') + ... + # get the magnetization from the timesignal + magnetization = sqrt(timesignal.y[0][80:100].mean()**2 + + timesignal.y[1][80:100].mean()**2) + measurement[tau] += magnetization + # provide the magnetization curve + data["Magnetization(tau)"] = measurement + ... + +Essentially, a dictionary "measurement" is created with *tau* as the key. For each new key the current magnetization is added. This dictionary is then added to the data pool. The advantage over the previous listing is that the magnetization vs. τ curve can be directly displayed in order to gain an overview of the running experiment, because the "measurement" dictionary is added to the data pool. In this example, the value also stores statistics from the accumulation. The data dictionary is stored automatically as described before, including the result and experiment scripts, information about the used back end and a timeline of the experiment. + +Note that we can also create a HDF5 file from scratch! In this case experiment and result script are not saved in the resulting file. The advantage is that one can create arbitrary complex structured files at the cost of having a more complicated result script. + +.. code-block:: python + :caption: Result script for saving data in a HDF5 file + :linenos: + + import tables + from damaris import get_result + + def result(results): + hdf = tables.openFile("myexperiment.h5", "w") + # create a group + group = hdf.createGroup("/", "experiment") + # save each result + for i, timesignal in enumerate(results): + hdf.createArray(group, "result_%d" % i, timesignal.get_ydata()) + hdf.close() + + +Fourier Transform Module +======================== + +A module was written for an easy calculation of spectra from time domain data. The Fourier transformation module "DamarisFFT" is based on the **fft** module of **numpy**, an array module for Python. There are no interactive capabilities such as phase correction incorporated yet. The FFT method can be applied directly to the object. The order in which these methods are applied *does* matter. Here are the available methods and a short explanation of their effects (values in italic are default values). +The change is *in-place*, which means if the timesignal is needed later on, a copy of it should be made. + +- **clip(start=**\ *None* **, stop=**\ *None* **)** + Only the data between start and stop is returned. + The start and stop parameters can be either in time or frequency domain. + +- **baseline(lastpart=**\ *0.1* **)** + This method should be applied first as it corrects the baseline of the signal, taking the last part of the signal for determining the correction. + +- **autophase()** + This will try to automatically phase the spectrum to maximize the real signal. Works only reliably at sufficient high SNR (>20) + +- **fft(samples=**\ *None* **)** + This method returns the real and the imaginary part of an FFT of the timesignal. Zero-filling of the timesignal can be done via the **points** keyword. If **points** is bigger than the number of data points, the rest will be filled with zeros (zero-filling/zero-padding). + +- **abs_fft(points=**\ *None* **)** + This method returns an absolute FFT of the timesignal. Zero-filling of the timesignal can be done via the **points** keyword. If **points** is larger than the number of data points, the rest will be filled with zeros (zero-padding). The **zoom** keyword accepts either a tuple with centre frequency and width in Hz. Auto zooming the highest peak can be achieved by setting the centre frequency to *auto*. + +In order to suppress side-lobes, enhance resolution or improve SNR it is common practice in data processing to apply windowing functions to the data. +Several windowing functions are available in the "DaFFT" module. The first two functions, i. e. the exponential and gaussian window function are SNR enhancing windows, while the double exponential window function is resolution enhancing. +The TARF window is both, SNR and resolution enhancing :cite:`Traficante:1987fk`. +All four are commonly used in NMR spectroscopy. The line broadening factor LB is the rate (in Hz) in which the window function decays. The higher the value, the faster the function decays, hence the resulting spectrum will be more "smooth" but the peaks will become wider. + +- **exp_window(line_broadening=**\ *10* **)** + This sets an exponential window over the data, the beginning of the signal is weighted more, where as the tail of the signal gets suppressed. Best results are obtained with line broadening factor set to the peak width: + + .. math:: + f(x)=exp(-tp \cdot LB) + +- **gauss_window(line_broadening=**\ *10* **)** + This sets a gaussian window over the data: + + .. math:: + f(x)=exp(-(tp \cdot LB)^2) + +- **dexp_window(line_broadening=**\ *-10* **, gaussian_multiplicator=**\ *0.3* **, show=**\ *0* **)** + This sets a double-exponential window over the data, which enhances the tail of the FID thus prolonging it and increases the resolution. Note that the line broadening should have a negative value here. The reason is that weighting is supposed to increase from the beginning (exponential part) and then later to decrease again (gaussian part). Another point to mention is that this window is in fact transforming a lorentzian peak in a gaussian peak which has the property of a narrower base: + + .. math:: + f(x)=exp(-tp \cdot LB - GM \cdot tp^2) + +- :meth:`damaris.data.DamarisFFT.DamarisFFT.traf_window`(line_broadening=10 ) + This sets a TRAF window :cite:p:`Traficante:1987fk` over the data: + + .. math:: + f(x)=\frac{exp(-tp \cdot LB))^2}{[exp(-tp \cdot LB))^3 + (exp(-aq\_time \cdot LB)]^3} + +Following standard windowing functions :cite:p:`Butz:1998fr` are available additionally. Note that the whole data will be windowed, not only a subset. Furthermore, these windows are not suitable for FID's or similar signals, because they are symmetric around the middle of the data set and zero at the beginning and the end. + +- :meth:`damaris.data.DamarisFFT.DamarisFFT.hanning_window` +- :meth:`damaris.data.DamarisFFT.DamarisFFT.hamming_window` +- :meth:`damaris.data.DamarisFFT.DamarisFFT.blackman_window` +- :meth:`damaris.data.DamarisFFT.DamarisFFT.bartlett_window` +- :meth:`damaris.data.DamarisFFT.DamarisFFT.kaiser_window` + +To use this methods one has to apply consecutively the methods to an *timesignal* or *accumulation* object: + +.. code-block:: python + :caption: FFT example + :linenos: + + data["FFT"] = timesignal.baseline(0.4).exp_window(line_broadening=100).abs_fft().clip(-1e3, 1e3) + +This applies baseline correction using the last 40% of the timesignal for determination of the signal. Then, an exponential window is applied. From this timesignal an FFT is calculated which is further clipped to view to the data between -1 kHz with 1 kHz width. + + +Good Practices +============== + +- Save often. It can become slow to open a HDF file in append mode and close it again for *each* result, but in case of an error, the file is not completely lost. +- Keep the experiment function simple. Everything necessary for a scan should be contained in a function, the parameters should stay in the **experiment** function. This makes it possible to loop over several parameters easier and, in case of complex experiments, all variables are changed in one place: the call to the function. +- Display if necessary. If the repetition time of subsequent scans is short (several ms) it can slow down the result script notably. The result script will take care of this by not displaying every single shot, but displaying nothing would further speed up the processing of the results. +- Save disk space. If the options "delete results" and "delete jobs" are switched off, the spool directory can get clobbered by several thousand files and in the worst case, one can run out of *inodes*. If it is not possible to delete the files in the directory anymore (rm gives an error "too much arguments") the following command can help deleting the files anyway: + + .. code-block:: bash + + find . -name job\* -exec rm {} \; + + which will delete all files starting with *job* in the current directory. + +- It is a good idea to put a *synchronize()* statement in the experiment script, for example after the 100th accumulation. This will write job files only until the synchronize is requested. Then, the front end will wait writing new job files, until the result script has processed all current results. In big experiments, several ten thousands job of files would be written without this, which can lead to problems with the file system and performance. + + .. code-block:: python + + if accu % 100 == 0: + synchronize() + +- Keep an eye on the logs. In case of errors it is highly recommended to check the log file in the log path (as defined in the configuration tab) *as well* as the "Log" tab for error messages. + + +Tuning and Development +====================== + +When new result scripts are developed, it is an advantage if the actual experiment has not to be repeated for every minor change or tweak in the result script. This can become a very tedious task when the sample has a long T1 relaxation, like water T1 ≈ 3s :cite:`PhysRev.111.1201`. +In order to use this technique, the experiment has to be run once with the option "delete results after processing" turned off. This leads to the result files in the spool directory not being deleted. Starting the experiment again with the option "run back end" switched off, the front end will read the results again like if it would be a new experiment, hence one can test new result scripts quite conveniently. +Developing experiment scripts can be done in a similar manner: the dummy back end (to be set in the configuration tab) can be used to test new experiment scripts without the need to have a spectrometer at hand. + + +Data Processing Outside DAMARIS +=============================== + +For post-processing of the data, several options are available, depending on the format of the data. Most programs can handle ASCII files (gnuplot, Origin, fitsh, etc.), so this is the more flexible format. HDF can be read by pyTables, Matlab, Octave, R, Mathematica and more. + + +Experiment Script Commands +========================== + +Following is a list of available commands in an experiment script. + +- **ttl_pulse(length, channel=**\ *None* **, value=**\ *None* **)** + Gives out *either* a TTL pulse with duration **length** on **channel** (counting from zero), *or* multiple channels given by the binary representation of **value**. + + .. figure:: pics/pins_ttl_bit.png + :alt: Line driver with a decimal value 17 set + :width: 400px + + Line driver with a decimal value 17 set (or 0x11 hexadecimal). In binary, channel 0 and channel 3 are on + + Example: + + .. code-block:: python + + e.ttl_pulse(length=5e-6, channel=1) + e.ttl_pulse(length=3e-6, value=3) + + This example is used to create a RF pulse with a pulse length of 3 μs. The first statement sets the gate pulse (channel 0) of the RF amplifier for 5 μs, while the second statement combines the gate and RF pulse on channels 0 and 1 (2^0 + 2^1 = 3). Hexadecimal representation (number starts with *0x*) is convenient as the numbers are shorter: To set all channels, **value** would be in decimal 16777215 and in hexadecimal 0xffffff. One letter in hexadecimal represents four bits. + +- **ttls(length=None, value=None)** + Same as **ttl_pulse(length, value)** + +- **wait(time)** + Wait specified **time** in seconds. Minimum time is 90 ns, maximum time is essentially unlimited (years). The limit imposed from the pulse programmer is circumvented by the driver. + + Example: + + .. code-block:: python + + e.wait(length=2e-3) + +- **record(samples, frequency, timelength=**\ *None* **, sensitivity=**\ *None* **)** + Records data with given number of **samples**, sampling-frequency **frequency** and **sensitivity** in Volts. + If **timelength** is given, this state will stay the given time. The maximum sampling-frequency is 20 MHz and the onboard memory can hold 8M samples shared by both channels. Sensitivity can be one of 0.2, 0.5, 1, 2, 5 and 10 V. + + Note that multiple record statements can be in a single scan (gated sampling) or in a loop. + + Example: + + .. code-block:: python + + e.record(samples=1024, frequency=2e6, sensitivity=2) + + Records a signal with 1024 data points and 2 MHz sampling-frequency. The sensitivity will be ± 2 V. With a 14bit ADC card this gives a resolution of 0.2 mV. + +- **loop_start(iterations)/loop_end()** + This creates a loop of given number of **iterations** and has to be closed by loop_end(). + Commands inside the loop can not change, i.e. the parameters are the same for each loop run. This loop is created on the pulse programmer, thus saving commands. + + Example: + + .. code-block:: python + + e.loop_start(iterations=10) + e.rf_pulse(channel=3, length=2e-6) + e.wait(time=2e-6) + e.loop_end() + + This loop will create 10 pulses with 2 μs length and 2 μs apart. + +- **set_frequency(frequency, phase, ttls=**\ *0* **)** + Sets the **frequency** and **phase** of the frequency source and optionally further channels. The time needed to set the frequency is 2 μs. + + Example: + + .. code-block:: python + + e.set_frequency(frequency=300.01e6, phase=0) + + The frequency generator will deliver 300.01 MHz. + + .. code-block:: python + + e.set_frequency(frequency=300.01e6, phase=0, ttls=3) + + Same as above, but also sets channel 0 and 1. + +- **set_phase(phase, ttls=**\ *0* **)** + This command can be used to change the phase of the frequency. The *phase* is given in degree. The *ttls* keyword has the same functionality like in the set_frequency command. Setting the phase is done in 0.5 μs. + + Example: + + .. code-block:: python + + e.set_phase(phase=90) + e.record(samples=1024, frequency=2e6, sensitivity=2) + + This would set the receiver phase to 90 degree. + +- **set_pts_local()** + If the frequency source is set to remote control mode, this can be used to set to local mode, thus the frequency of the PTS synthesizer can be changed manually. + +- **set_pfg(length, dac_value, shape=('rec',0), trigger=4, is_seq=**\ *0* **)** + With this command, pulsed field gradients are generated. In order to create arbitrary ramps or shapes, **is_seq** can be set to 1, leading the DAC to keep the current state until a new strength is applied. + The trigger keyword allows to set a trigger line with the start of the gradient pulse. + Certain gradient shapes are predefined: + + - rectangular ('rec') + - sin ('sin') + - sin² ('sin2') + + You can select them by giving the shape keyword a tuple with shape and resolution in s + + Example: + + .. code-block:: python + + e.set_pfg(length=1e-3, dac_value=15040, is_seq=0) + + This would create a 1 ms long PFG pulse with 1 Tm⁻¹ + + .. code-block:: python + + for val in lin_range(start=0, stop=pi, step=pi/50): + gradient = int(sin(val)**2 * 15040) + e.set_pfg(length=1e-3/50, dac_value=gradient, is_seq=1) + + This would create a 1 ms long PFG pulse shaped like half period of a sin² with an amplitude of 1 Tm⁻¹. + + .. code-block:: python + + e.set_pfg(length=1e-3, dac_value=15040, shape=('sin2', 1e-5)) + + This would create a sin² shaped gradient with 1ms length and 100 interpolation points. + +- **set_description(key, value)** + Setting a description is accomplished by this command. It creates an entry **key** with value **value** in the description dictionary. In case of the data being stored in a HDF5 file this dictionary is stored as well. + + Example: + + .. code-block:: python + + e.set_description(key="tau", value=2e-3) + +Following are convenient functions for use in loops. + +- **lin_range(start, stop, step)** This is used for loops. It increases **start** with **step** until **stop** is reached. + + Example: + + .. code-block:: python + + def experiment(): + for tp in lin_range(start=5e-7, stop=10e-6, step=5e-7): + yield pi_pulse(pulselength=tp) + + Starting from 0.5 μs, increase pulse length with 0.5 μs until 10 μs. + +- **log_range(start, stop, stepno)** Divide the range **start** to **stop** logarithmically in **stepno** steps. + + Example: + + .. code-block:: python + + def experiment(): + for t in log_range(start=5e-3, stop=10, stepno=10): + yield inversion_recovery(tau=t) + + Variate the distance τ of the two pulses in the inversion recovery experiment logarithmically from 5 ms to 10 s. The values would be: + ['0.0050', '0.0116', '0.0271', '0.0630', '0.1466', '0.3411', + '0.7937', '1.8469', '4.2975', '10.0000'] + +- **staggered_range(some_range, size=**\ *1* **)** Creates a staggered range from another range, leaving out **size** values in a row and appending the left out later. + + Example: + + .. code-block:: python + + def experiment(): + myrange = log_range(start=5e-3, stop=10, stepno=10) + for tp in staggered_range(myrange, size=2): + yield inversion_recovery(tau=t) + + This is the same as before, but the values are now staggered: 12345678 will become 12563478. Another possibility for achieving something similar is the *shuffle* function. + +- **interleaved_range(some_range, size=**\ *1* **)** Creates an interleaved range from another range, appending every n-th point. + + Example: + + .. code-block:: python + + def experiment(): + myrange = log_range(start=5e-3, stop=10, stepno=10) + for tp in interleaved_range(myrange, size=3): + yield inversion_recovery(tau=t) + + The values are now interleaved: 12345678 will become 14725836. + +- **combine_ranges(*ranges)** With this function it is possible to combine several ranges + + Example: + + .. code-block:: python + + def experiment(): + mylinrange = lin_range(start=1e-3, stop=4.9e-3, step=1e-4) + mylogrange = log_range(start=5e-3, stop=10, stepno=10) + for tp in combine_ranges(mylinrange, mylogrange): + yield inversion_recovery(tau=t) + +Result Script Commands +====================== + +Following is a list of available commands in a result script. These are methods to be applied to a ADC_Result and Accumulation object. An accumulation object needs to be created before any methods can be applied. + +Example: + +.. code-block:: python + + akku = Accumulation(error=True) + akku += timesignal + +- **get_result_by_index(index)** + If several **record** statements occur in an experiment, the results are saved in an array and can be accessed by this method. *Index* starts with 0. + + Example: + + .. code-block:: python + + timesignal.get_result_by_index(1) + + This would return the result of the second record statement. + +- **get_sampling_rate()** + Returns ADC card sampling rate + +- **uses_statistics()** + Returns *False* if the result is a single ADC result and *True* if the result is an accumulation with statistics enabled. + +- **write_to_csv(destination=**\ *sys.stdout* **)** + Writes the result into an ASCII file, destination has to be an open file. The file has to be closed after write_as_csv has been issued otherwise the data is not written to the harddrive. + + Example: + + .. code-block:: python + + f = open('testfile.dat', 'w') + timesignal.write_to_csv(destination=f) + f.close() + +- **write_to_hdf(hdffile, where, name, title, compress=**\ *None* **)** + Writes the data to a HDF5 file **hdffile**. + +- **get_description(key)** + Returns **value** of description **key** as string. Note that in the case of application to an accumulation object, only the common descriptions are stored, leading to a proper set of relevant parameters. + +- **get_xdata()** + Returns a copy of timedata. + +- **set_xdata(pos, value)** + +- **get_ydata(channel)** + Returns a copy of the data from channel **channel** + +- **set_ydata(channel, pos, value)** + +- **get_number_of_channels()** + Returns the number of ADC channels, usually 2 + +- **get_xlabel()/get_ylabel()** + Returns the x/y-axis description in display register + +- **set_xlabel(label)/set_ylabel(label)** + Sets the label of the x/y-axis + +- **get_text(index)** + Returns labels to be plotted (List) + +- **set_text(index, text)** + Sets labels to be plotted + +- **get_title()** + Returns the title of the plot + +- **set_title(title)** + Sets the title of the plot + +- **get_legend()** + Returns the legend of the plot (dictionary) + +- **set_legend(channel, value)** + Sets the legend of the plot + +- **get_xmin()** + Returns minimum of x + +- **get_xmax()** + Returns maximum of x + +- **get_ymin()** + Returns minimum of y + +- **get_ymax()** + Returns maximum of y + + + +.. bibliography:: + diff --git a/doc/pics/config1.png b/doc/pics/config1.png new file mode 100644 index 0000000..158f8d3 Binary files /dev/null and b/doc/pics/config1.png differ diff --git a/doc/pics/damaris_description.png b/doc/pics/damaris_description.png new file mode 100644 index 0000000..99e647c Binary files /dev/null and b/doc/pics/damaris_description.png differ diff --git a/doc/pics/damaris_interaction.svg b/doc/pics/damaris_interaction.svg new file mode 100644 index 0000000..dc3ceba --- /dev/null +++ b/doc/pics/damaris_interaction.svg @@ -0,0 +1,242 @@ + + + +image/svg+xmlback end +front end +RESULTS +JOBS + \ No newline at end of file diff --git a/doc/pics/datapool_data.png b/doc/pics/datapool_data.png new file mode 100644 index 0000000..2fe8930 Binary files /dev/null and b/doc/pics/datapool_data.png differ diff --git a/doc/pics/datapool_dict.png b/doc/pics/datapool_dict.png new file mode 100644 index 0000000..cf67c05 Binary files /dev/null and b/doc/pics/datapool_dict.png differ diff --git a/doc/pics/datapool_root.png b/doc/pics/datapool_root.png new file mode 100644 index 0000000..354b473 Binary files /dev/null and b/doc/pics/datapool_root.png differ diff --git a/doc/pics/datapool_table.png b/doc/pics/datapool_table.png new file mode 100644 index 0000000..62667dd Binary files /dev/null and b/doc/pics/datapool_table.png differ diff --git a/doc/pics/pins_ttl_bit.png b/doc/pics/pins_ttl_bit.png new file mode 100644 index 0000000..3bfd919 Binary files /dev/null and b/doc/pics/pins_ttl_bit.png differ diff --git a/doc/pics/shapegrad1.png b/doc/pics/shapegrad1.png new file mode 100644 index 0000000..901a339 Binary files /dev/null and b/doc/pics/shapegrad1.png differ diff --git a/doc/pics/traversing_example.png b/doc/pics/traversing_example.png new file mode 100644 index 0000000..4395145 Binary files /dev/null and b/doc/pics/traversing_example.png differ diff --git a/doc/pics/traversing_example2.png b/doc/pics/traversing_example2.png new file mode 100644 index 0000000..db7ce8a Binary files /dev/null and b/doc/pics/traversing_example2.png differ diff --git a/doc/pics/traversing_machine.png b/doc/pics/traversing_machine.png new file mode 100644 index 0000000..0205909 Binary files /dev/null and b/doc/pics/traversing_machine.png differ diff --git a/doc/pics/traversing_machine.svg b/doc/pics/traversing_machine.svg new file mode 100644 index 0000000..4e0b5b5 --- /dev/null +++ b/doc/pics/traversing_machine.svg @@ -0,0 +1,983 @@ + + + +image/svg+xml + + +4. Wait +7. Wait + + +1. bit +2. bit +... +3. bit +Pulse Programmer State: Bit ON or OFF +5. PFG pulse on +6. PFG pulse off +1. bit +2. bit +... +3. bit +1. Experiment + \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f9c1dab..8d3e7e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -56,7 +56,8 @@ packages = [ [tool.setuptools.data-files] "share/python3-damaris/images" = ["src/gui/DAMARIS3.png", "src/gui/DAMARIS3.ico"] -"share/python3-damaris/doc" = ["doc/index.html"] -"share/python3-damaris/doc/reference-html" = ["doc/reference-html/*"] -"share/python3-damaris/doc/tutorial-html" = ["doc/tutorial-html/*"] +#"share/python3-damaris/doc" = ["doc/index.html"] +#"share/python3-damaris/doc/reference-html" = ["doc/reference-html/*"] +#"share/python3-damaris/doc/tutorial-html" = ["doc/tutorial-html/*"] + diff --git a/requirements.debian b/requirements.debian index d88c6e5..856a4aa 100644 --- a/requirements.debian +++ b/requirements.debian @@ -1,7 +1,7 @@ #!/bin/bash apt-get -y install libcairo2-dev gir1.2-gtksource-3.0 apt-get -y install python3-dev python3-scipy python3-lmfit python3-matplotlib python3-tables python3-xdg -apt-get -y install debhelper dh-sequence-python3 lsb-release +apt-get -y install debhelper dh-sequence-python3 lsb-release sphinx-common sphinx-rtd-theme-common DEBRELEASE=$(lsb_release -cs) case $DEBRELEASE in "trixie") diff --git a/src/gui/DamarisGUI.py b/src/gui/DamarisGUI.py index b35cc71..209cb1d 100644 --- a/src/gui/DamarisGUI.py +++ b/src/gui/DamarisGUI.py @@ -974,38 +974,14 @@ class DamarisGUI: def documentation_init( self ): self.doc_urls = { - "Python DAMARIS": None, - "DAMARIS Homepage": "http://element.fkp.physik.tu-darmstadt.de/damaris_cms", - "DAMARIS script library":"https://chaos3.fkp.physik.tu-darmstadt.de/diffusion/DSL/", - "DAMARIS backends repo": "https://chaos3.fkp.physik.tu-darmstadt.de/source/damaris/browse/master/backends/", - "DAMARIS frontend repo": "https://chaos3.fkp.physik.tu-darmstadt.de/source/damaris/browse/master/frontends/python-damaris/", - "Python": "http://www.python.org/doc/%d.%d/" % (sys.version_info[:2]), - "numpy/scipy": "http://docs.scipy.org/", - "pytables": "http://www.pytables.org/docs/manual/", + "DAMARIS Manual": "file:///usr/share/doc/python3-damaris/doc/_build/html/index.html", } if os.path.isdir( "/usr/share/doc/python%d.%d-doc/html" % (sys.version_info[ :2 ]) ): - self.doc_urls[ "Python" ] = "file:///usr/share/doc/python%d.%d-doc/html/index.html" % ( + self.doc_urls[ "Python Docs" ] = "file:///usr/share/doc/python%d.%d-doc/html/index.html" % ( sys.version_info[ :2 ]) - if os.path.isdir( "/usr/share/doc/python-tables-doc/html" ): - self.doc_urls[ "pytables" ] = "file:///usr/share/doc/python-tables-doc/html/index.html" - doc_index_url = None - # local installation - installation_base = __file__ - for i in range( 5 ): - installation_base = os.path.dirname( installation_base ) - if os.path.isfile( os.path.join( installation_base, "share", "python-damaris", "doc", "index.html" ) ): - self.doc_urls[ "Python DAMARIS" ] = os.path.join( installation_base, "share", "python-damaris", "doc", - "index.html" ) - elif os.path.isfile( "/usr/share/doc/python-damaris/html/index.html" ): - # check generic debian location - self.doc_urls[ "Python DAMARIS" ] = "file:///usr/share/doc/python-damaris/html/index.html" - else: - - self.doc_urls[ "Python DAMARIS" ] = "https://element.fkp.physik.tu-darmstadt.de/damaris_cms/index.php?id=documentation" - self.doc_browser = None def show_doc_menu( self, widget, data=None ):