odin-1.8.5/0000755000175000017500000000000011735135552007466 500000000000000odin-1.8.5/NEWS0000644000175000017500000000000011322062355010063 00000000000000odin-1.8.5/TODO0000644000175000017500000000061611322062355010071 00000000000000Free memory after simulating large/long sequences Single state machine for methods -> better reporting of messages Check for occurences of SeqVecIter inside loops and unroll if necessary setfreq/setneg for padded ADC on IDEA Add flow compensation to SeqGradEcho Improve homepage: highlight features of ODIN: - List publications which used ODIN Cache simulation steps (operations) for speedup odin-1.8.5/docs/0000755000175000017500000000000011735135552010416 500000000000000odin-1.8.5/docs/homepage/0000755000175000017500000000000011735135552012203 500000000000000odin-1.8.5/docs/homepage/favicon.png0000644000175000017500000000055011322062337014246 00000000000000PNG  IHDR szz/IDATXW 0 QhG\0#;vD@'!FA@$$6BAYxƙinC`b4-8G>X."jHY)N~KB/3H^ePvjϸNPa(є \Yo𸪳Yn=JRrGk3ZgkyOn5 ӛ . "C HK:X=8߈Z ;!ZyIkE\V +Z+ {t{VWsZGg+r_ ٲIENDB`odin-1.8.5/docs/homepage/documentation.wml0000644000175000017500000000076611322062337015516 00000000000000#include "head.wml"

A short tutorial which describes sequence programming with ODIN:

  • odintut.pdf
  • A publication about ODIN (Journal of Magnetic Resonance 170:67-78, 2004) is available for download as PDF:

  • odin.pdf
  • Another publication (Journal of Magnetic Resonance 180:29-38, 2006) which explains the simulation algorithm used within ODIN:

  • magsi.pdf
  • #include "tail.wml" odin-1.8.5/docs/homepage/Makefile.am0000644000175000017500000000337611322062337014160 00000000000000EXTRA_DIST = logo.jpg favicon.png download.wml documentation.wml head.wml index.wml platforms.wml tail.wml LAYOUTDEFINES = -DLEFTPERC=15 -DMIDPERC=65 -DRIGHTPERC=20 if ONLY_LIBS else sequences.wml: echo "#include \"head.wml\"" > sequences.wml echo "The following sequences are available for ODIN and can be used as a template for your own sequence(s):" >> sequences.wml echo "

    " >> sequences.wml for seqfile in ../../sequences/odin*.cpp; do \ seqid=`basename $$seqfile .cpp`; \ echo "$$seqid" >> sequences.wml; \ echo "
    " >> sequences.wml; \ cat $$seqfile | sed -n 'H; $${g; s/\n//g; s/\r/ /g; p}' | sed 's/^.*[^.]set_description(//; s/);.*//; s/\"/ /g; s/[\t ][\t ]*/ /g; s/^[ ]//' >> sequences.wml; \ echo "
    " >> sequences.wml; echo "
    " >> sequences.wml; \ done echo "#include \"tail.wml\"" >> sequences.wml authors.wml: echo "#include \"head.wml\"" > authors.wml echo "Authors:" >> authors.wml cat ../../AUTHORS | awk '{print "

  • "; print; print "
  • "}' >> authors.wml echo "#include \"tail.wml\"" >> authors.wml formats.wml: echo "#include " > formats.cpp echo "int main() {STD_cout << FileIO::autoformats_str();}" >> formats.cpp c++ formats.cpp -o formats -lodindata ./formats | sed s/^.*\(/\/ | sed s/\)/\<\\/li\>/ | sort -u >> formats.wml homepage: formats.wml index.html download.html documentation.html platforms.html sequences.html authors.html endif clean-local: -rm -rf sequences.wml authors.wml formats* *.html ## rule to produce html files from wml files %.html : %.wml head.wml tail.wml wml $(LAYOUTDEFINES) -DVERSION="$(VERSION)" -DDATE="`date +'%b %d %Y'`" $< > $@ odin-1.8.5/docs/homepage/Makefile.in0000644000175000017500000002677411734622602014204 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = docs/homepage DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = logo.jpg favicon.png download.wml documentation.wml head.wml index.wml platforms.wml tail.wml LAYOUTDEFINES = -DLEFTPERC=15 -DMIDPERC=65 -DRIGHTPERC=20 all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/homepage/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/homepage/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am @ONLY_LIBS_FALSE@sequences.wml: @ONLY_LIBS_FALSE@ echo "#include \"head.wml\"" > sequences.wml @ONLY_LIBS_FALSE@ echo "The following sequences are available for ODIN and can be used as a template for your own sequence(s):" >> sequences.wml @ONLY_LIBS_FALSE@ echo "

    " >> sequences.wml @ONLY_LIBS_FALSE@ for seqfile in ../../sequences/odin*.cpp; do \ @ONLY_LIBS_FALSE@ seqid=`basename $$seqfile .cpp`; \ @ONLY_LIBS_FALSE@ echo "$$seqid" >> sequences.wml; \ @ONLY_LIBS_FALSE@ echo "
    " >> sequences.wml; \ @ONLY_LIBS_FALSE@ cat $$seqfile | sed -n 'H; $${g; s/\n//g; s/\r/ /g; p}' | sed 's/^.*[^.]set_description(//; s/);.*//; s/\"/ /g; s/[\t ][\t ]*/ /g; s/^[ ]//' >> sequences.wml; \ @ONLY_LIBS_FALSE@ echo "
    " >> sequences.wml; echo "
    " >> sequences.wml; \ @ONLY_LIBS_FALSE@ done @ONLY_LIBS_FALSE@ echo "#include \"tail.wml\"" >> sequences.wml @ONLY_LIBS_FALSE@authors.wml: @ONLY_LIBS_FALSE@ echo "#include \"head.wml\"" > authors.wml @ONLY_LIBS_FALSE@ echo "Authors:" >> authors.wml @ONLY_LIBS_FALSE@ cat ../../AUTHORS | awk '{print "

  • "; print; print "
  • "}' >> authors.wml @ONLY_LIBS_FALSE@ echo "#include \"tail.wml\"" >> authors.wml @ONLY_LIBS_FALSE@formats.wml: @ONLY_LIBS_FALSE@ echo "#include " > formats.cpp @ONLY_LIBS_FALSE@ echo "int main() {STD_cout << FileIO::autoformats_str();}" >> formats.cpp @ONLY_LIBS_FALSE@ c++ formats.cpp -o formats -lodindata @ONLY_LIBS_FALSE@ ./formats | sed s/^.*\(/\/ | sed s/\)/\<\\/li\>/ | sort -u >> formats.wml @ONLY_LIBS_FALSE@homepage: formats.wml index.html download.html documentation.html platforms.html sequences.html authors.html clean-local: -rm -rf sequences.wml authors.wml formats* *.html %.html : %.wml head.wml tail.wml wml $(LAYOUTDEFINES) -DVERSION="$(VERSION)" -DDATE="`date +'%b %d %Y'`" $< > $@ # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/docs/homepage/index.wml0000644000175000017500000001173111455553535013762 00000000000000#include "head.wml"

    Hello World
    Welcome to the ODIN homepage! ODIN is a C++ software framework to develop and simulate magnetic resonance sequences. It is

  • State-of-the-Art: Contemporary magnetic resonance imaging techniques are available, for example sequence modules for echo-planar imaging and spiral-imaging, parallel imaging with GRAPPA reconstruction, two-dimensional pulses and field-map-based distortion corrections.

  • Easy-to-Use: All common steps, from compiling your sequence to plotting or simulating it, can be performed within a graphical user interface.

  • Hardware Independent: ODIN runs on a variety of operating systems and scanners. Once you develop a sequence, it can be executed/simulated on very different hardware, ranging from a real-time sequence controller to your personal workstation.

  • Truly Object-Oriented: Written in C++ with an object-oriented design, ODIN is very modular, flexible and requires very little code to write: The sequences that come with ODIN are easy to understand and modify.

  • Open Source: ODIN is a free software framework. It contains well-established techniques in magnetic resonance which were documented in scientific publications. It can be used and modified without restrictions.



  • Some Highlights of ODIN

  • Plotting of the sequence timecourse in a graphical user interface.

  • Simulating the spin-physics of the sequence (Bloch-Torrey equations) using a virtual phantom to generate a virtual MR signal. System imperfections (eddy currents, B1 inhomogeneity, noise) can be switched on/off at will during the simulation.

  • Visualization of the k-space trajectory, b-values, eddy currents, etc.

  • Highly-customizable, multi-threaded image reconstruction framework.




  • ODIN Components

    Odin [Screenshot] [Screenshot]
    The control center for developing, testing, visualizing and simulating NMR sequences. It is a front-end to the ODIN libraries, allowing interactive editing, recompiling and dynamic linking of sequence modules.


    Pulsar [Screenshot]
    A graphical user interface for the generation and simulation of RF pulses is provided by the Pulsar program. Parameters of the pulse can be edited interactively and the corresponding excitation profile is displayed simultaneously. A modular approach is used for maximum flexibility: The pulse shape, k-space trajectory and filter function of the pulse are generated by independent functions. They can be combined in many ways, e.g. a box-shaped pulse can be generated using any of the spiral trajectories and any of the filter functions. The functions of the pulse are implemented using a plug-in mechanism (abstract C++ base classes where the functions are implemented in the derived classes). Thus new pulse shapes, trajectories and filter functions can be added easily by defining new function classes.


    MiView [Screenshot]
    A command line driven data viewer that supports the following formats: #include "formats.wml"
    Display properties (contrast, brightness) can be adjusted. The value of regions and single points can be retrieved and scan-line profiles can be generated interactively.



    Geoedit [Screenshot]
    A lightweight geometry editor that exports the selected geometry parameters to the ODIN sequence development framework.



    Many Useful Command-Line Utilities


    The main functionality of ODIN can be found in a couple of libraries:

    tjutils
    This library contains various helper classes and functions that are not specific to MR.

    odinpara
    Library to handle MR parameters, such as system properties, scan geometry, sequence parameters. Input/output of parameters is achieved via JCAMP-DX file format.

    odinseq
    This library contains the interface for sequence programming. It also contains the hardware specific driver routines.

    odindata
    The Blitz++ library is used for handling multidimensional arrays in ODIN. In addition, many MR-specific routines (FFT, phase correction) were added and placed in this library.

    #include "tail.wml" odin-1.8.5/docs/homepage/tail.wml0000644000175000017500000000336511456021426013576 00000000000000

    Contact
    If you have any questions, bug-reports or improvements, if you need professional support with ODIN, or if you know how to make a better web page than this, please do not hesitate to contact me (Thies Jochimsen). or post your request on the mailing list.

    Licensing
    ODIN is published under the terms of the GNU General Public License.

    Disclaimer
    ODIN is a framework for research purposes only. It is not certified for clinical use. Hence, it cannot replace approved solutions from commercial manufacturers.

    Get ODIN at SourceForge.net. Fast, secure and Free Open Source software downloads

    Last update: $(DATE)

    odin-1.8.5/docs/homepage/logo.jpg0000644000175000017500000003324411322062337013563 00000000000000JFIFC    $.' ",#(7),01444'9=82<.342C  2!!22222222222222222222222222222222222222222222222222"R !1"AQaq2#6BRSbu37Ut$&CTr%4Ec9!1AQq"a2BR#3Dbr ?unwP3j\Y=5䥵6?8O~9i݂W&1tVܤdmAVc /XH?`L(Cye2P-yGIC9ω'8UEޫ,o`DZIl BS ˋZgk)dYq 㒜dGQCvӲ.au3 RT1s.ݲ^fl!*}Rއd$$< 9h K+vi.{r)Hpx QNׄnȇ H +r]9c9zZðfHdE_Q[|< ]zչ"A)NC>ڒO_ [v歌a[R\}X-e ݑŽSVXJTT#r؜v*ڜArW jq1eEOU׈H-JmuU6wg~e'*P Qg.smmr (%8R;; lEޒZǔsɧmQi[Ha%k)Sox~|?c\'qARۀ I:(p"mCO,SJjiJxβUr0%*JQZG r>S/j&\.R\侅TpA8Pč9/a%ieΚӠ);ʎ\'pAXHȌ,Ðv4d䁁lKr_IQ[i)\8ʱL=v5.0(mT#Ǭz AuA nKx e'sT4tg*R!r +zG-We%)8t"Jj TV~BZQڀJAXuf\\RۥԁaCo*%dp@qRErYy]JgĞ9Nq86&2VXPG( >]}նT𲁱 (mYҏ?4؊KTe6 X#n>|tD#byJCAš/{8S !`!>rssé:^)z@u=rx@yڀbkeӅ>cZR< 0G=:(( (((iڔӹd'!# d >dRuj'؈LT8RzX<4AEPQ@QEQEEPQ@QEQEIXMIrM rI HJ$ w"aRmT|Y?ÚrTpz=BϤ:*ҡbr2rv ϖd rMnPJ v*>u+ A!QR׻#`c<ӎr:kץKluLjyUj~G性߽Lg~]쫬|F['fH2F WI6Q7j)%%2Z$X8NH< M8)i'sSyIl`;vۃq^%IRJ=Ǚy.+0E_Xp ڱpN3zn۩C{V_ʑnUk-n$) rc@xƥ/+zMǭ%-Y'y%IH\D;`^˨PSnnI~d tQEQEEPyәPR!E+JI0yhQEQJǎ(ܵg$x O TGx$'rTiP I 8=FoEMTFm gj\JIIQE*.HYCIܠ,ㄤ@%El- B$,nI#H>Q[( ,$pHG>q*m)KR Gjie:* 'МҀ(SڑW P[ҝ*Z;Jp 1ESیh (RH 8 (( (+"Y&%}̦B_vkKJ{Ql冢.FZO·+7M-ZOֱz9o"(( (((( (_.M%[(F8$r( CtL i@qORBHW v`\zfK#ut Bq{X$ɨfim%)1Mw5D.rAaݝ )' Cӑnjq*+jG\5Ԅ)@'4=Y4*) =Q^o9+##8ԕ6J!rhee@EL^&҃~FDy(qAgx U\莨G2( &ИTB9O5-xP|*P<|85%DSԕ( v4@ =#Gh!!VVG8LrqYFl-'<橎zD-D; d΀iFIP[ 4/_t(R 죃<˱q[N*{kfa%GӱTiZi:5%c2ZH'xEVm~0% ! ecq@]UWˑ^O*Rv%)E) p@rv W([][S[[)QJ()%%$Fr1wEuEynۆ7c\/p.nSy?|M$r 4QnPv=qEHq `Er8?Z*$I!#'PӴXY JSqاs;2r7c?v(;z[7~on7mߟƴdNP8;V}s4P < HN(( ((B҄$j8JR2IƏa Q*m A#ᔜ|+{"jԄBGҴ8o3B)*I +2OR:c ߟf1 (( (((>.ա Cӝ/,$xP{To!`E\R^ҬjG$sۀy$_iܥd~O| ^q|ª"]Qwz(Zprj$:2? f-7 A|':FCO6S=;l9 QKg(=1ceWVFU&;$Vĕp8$1SnZ\s@tsWmd yjXS) GߚBq>(~_ڲJ@@} % ޡZetn %;R:Gn cQ|Qv @uDIJp)W@䒬3uVRu)n[7|!a_$/N,?P@7bMLjiSm}8*EhSkR`;)k:B$@ҕEbP7~ˎ-eC¿ӷY!~=SeF p)$3i Qt*+8۽F=Ugԋ%CSVv$wr?J8MnJ}R~+CN#Kod:JVVx)>6e uՔ499#|J`0J\6F8CןE9.Cm2]=E+yj% soR C*i\H8H%N_J}8JI@+"0 \̜@5=W!COfwhX` Bh h褥:bJҔ,+12~NƓEߚƕe!o{g~9uǑ>bZd\5dMla pCQWٽ )qYuJ'>tjfkHu+nPL/?Rᙡa /w nCe)JU+ 2a|5%_JΪ!U@BQHpj.<| 8ڀ/ʔk{!cΚKGXVM0(`ySl^dl%0T7 T+:h8Rr>Bcߢp#?]"A$l#˱:6Sn!HZIJ! sT_ \%Vn8ǞA@Wh+;]Şs#E3!JR%+O$Oa™4 (''E{pg+dM}2{$c~ԅEPQ@QEQEYVձm*La={IUg #)[/_uKR.[ϘOEuX?̆yejMEg{JhbgcAO=%6RMn|,i'Oxzfk5MxݿRʕf<@bjHqCnZ`ݢ){]Jin7|ۿmQJ@`ڎj:Am܆ DxT>DzdTxf,$.4TzOum}BkwN]@?"^:t:zn3*?H"-ڼ5%5AվƯr+a&婔Q"j:m ԯymP?q}{Bm(uIH=󏇗jF_dєe<]A E3\ۓ',:@0 UlE7+TBForWb=*rof7K'/+_TG[3{VKua8AQJR 8J/?ˮ?zOU^1t dcS+R 'G~-?NIw(ŷgf5$DӘ*#ʡktzu.M.$=>ךk"U7^Htʎ}NܘvS!iqJ $Uga,ri} 犋T}2K-$ PPn-!CpEkE(EJ$O&EEPQ@QEQEKDef8$u3O' F8*Kiڒ4LPRlR"ckifvzR4TVN@J"\8J (UqhP85*ܒgq7 Z Ҳ |$IфP ,4yԒ7 ^HgjO98"ҞJ(/(Hޱ>c( “H˿aM+RdU'GP: B2pBzZӱGrx# ϗ5s*ݵ -(vFem0|O\PI$}3]#ئjϭ=J5 '9F~|+اòo"N^sSx>sr֠ E$g3^C c][rg<|^lt:ӪCRA)RT0A Z7ŗAAMNi P5?aޓꊑc4םv0-W"S𡱟W }؄ͧSҞs;|i~-ύic]%>8 HCpEZ%׷\"2oL-$@|mt?^hx9ch!>WB~pw3 dvZCCj!yHAWH}{+{3#IsS\XS(SEhX”Lp=r~<: ^S7%Dmx㨉)?tUsrڜXX+FOmGWc+jwF_Pyj: $Umk?rZNBj?UtC(X͂s?rˌ9GgOD+rv8'U%+ac<,#o+!GݧF|'딟ljZi|c:P@y>_Ux+: $U25N?oW죦):+4\_GܯI@oObGeiEZ6'VP Q>EEPNEqLI'3Pu$]iH9(NI+F'6ưڼpG8O?Pϭ02 ސ[ߺK-Ε-?BOT%NL[ny.((Py"%ӒP$2O`*َHpe Itjp~SO,XO'VS+)RAݬs LB=lvG̨Eҩ.$@ y5'PWMnv}+Z 2Q<$? {;T.mJU%QF?Q_Zu* sF "6RCIZRNl6,N1m|,Vu{X"[%1O~00@°y#~{S41َ1\vS%ny/[Ƌmab}R{xj_Vޕa:V=k.-1uM ~{O|aG*;wIu{LN ʝUm۵ddNNB^G]*8999nYˬDUlb7G+ j,::JwH_9=AN3;$ e^G§IXm|~U_"3ρ5޸ڗON̓rVϑXܵДB%|x Xڥcgjy δU j[;Mun4ؙҎ6u7 Qp?WǑE.]wrgDwuگ&jѮm˸&P7*Jr eXʡu6~j \a<ԇ)'$rĶ]M@m &Jq6x̳%׵vO?Bm~}`o]Ptd^ƅic (4oF )rҕzALcvDTش'МuFǺËj;a)HYY6o|~ߥQӸ$^}V;ŌAM.u֘ÛUA]m?X56;74\05\H}.N yx|<}*tJ6O/훳r| 6\yҖNXKw|V]_jB{P] "gE.t៏>*)hV3yʀix|Ɯ&?bZ#>R1>]{,lIWvJNVmȶ3hB-u=wջOAMS˲eKS^BfH*>c%"ߩ!mt;  >Y%7Nߙ'igY5:N [^DgO .gS@D2FGqViv؜c:.֌.bG\`p~S.Eu-p3Oo:^!~3J[\̕ 1s6XnWěAldUIh%XG>ٚ~Ѧ L=C( *ی7UEz^i~E`8ۏz) eO{syNߒUgm}i$KjXq~xt t*HV1ʣ:2v17RD#cǯ8cXt4'NLί[L)Gn6Wd瓔mۥƸB:jdߧڔ?GLV[Tt)' w(Iʏ3&u5UKz1j W_w~o߷j{g{Sz4eO{|y.قzZ\8. o{h&J|KbBݾdPЧiTO%{Պ<0!2S-ZJS#+ Kvfɱg=x{Jƫn'A>ݻo?/j%m+q_5XV zZpԨŗ)qmIm$ǟoDŽE^gԡc*m( *cXoۤbl}[0Tpx^Ut;}2[?|+ei5KUԟ?~o;*^|:ѭvx6sK}䥐#'W#A5~ನr1NWW; >{zZ_;P}O*cnRzv5=W*QVҨڈBҩ8%w.OURSڶ%G\,-t3R[i*AN@9I0~u3J=fttoW(nCi8?{Hj}[X0Aˊ|,::JwH_9=AN34tZUn.^śoʭ}ةOP֠Gum-x #GBRTd^FN*Ȕ|1QP5u %0e?yFս8P0sqڹGxivmom-pevzNP]j$@Jh6o s% >T+;{6eܣ{65&^\qsRXP-Zm-Please note that the scanner-specific plugins (drivers) have been removed from ODIN to avoid potential conflicts of interest between the scanners manufacturers and the authors of ODIN.


    Supported Spectrometers / Scanners:

  • Bruker MEDSPEC with Paravision 3
  • Siemens NUMARIS4 (VA15 - VA35, VB12 - VB17)
  • GE Signa/Epic (Code Generator)
  • Drivers (plugins) for these platforms are not included in the ODIN distribution, but are available upon request to research sites.

    Tested Operating Systems / Compilers:

  • Debian GNU/Linux 3.0 - 5.0
  • Red Hat Enterprise Linux 3/4
  • Windows NT4/XP/Vista (Using MinGW)
  • MacOS X 10.4 (Tiger), 10.5 (Leopard)
  • VxWorks
  • (ODIN uses the autoconf, automake and libtool. Thus, it should compile on any recent UNIX/Linux operating system.)

    Supported Image/Data Formats: #include "formats.wml"

    #include "tail.wml" odin-1.8.5/docs/homepage/head.wml0000644000175000017500000000572611456021426013551 00000000000000 ODIN - Object Oriented Development Interface for NMR


    Navigation

    Introduction

    Platforms

    Download

    Documentation

    Sequences

    Manual

    Browse Code

    Mailing List

    Authors




    Search:



    Screenshots:







    More
    odin-1.8.5/docs/homepage/download.wml0000644000175000017500000000421511455553535014461 00000000000000#include "head.wml"

    Live CD
    Try ODIN without installation! This Live CD based on Knoppix contains a recent version of ODIN. Just download the ISO image, write it to CD, and boot from it.


    Source Code
    Please take a look at the INSTALL file for instructions on how to compile ODIN for your platform.

    Latest release (ChangeLog):

  • odin-$(VERSION).tar.gz
  • Previous releases and additional stuff:

  • All files
  • Latest source code:
    Checking out the latest source code using Subversion is possible with the command

    svn checkout https://od1n.svn.sourceforge.net/svnroot/od1n/trunk/odin
    
    Use the command
    ./bootstrap
    in the checkout to generate the configure script.


    Windows Binaries
    The Windows distribution of ODIN contains everything that is necessary to compile/run sequences (3rd party libraries, MinGW compiler), just install the following package:

  • odin-$(VERSION).exe

  • Debian/Ubuntu packages
    An official debian package is available here. ODIN is part of NeuroDebian. As a nice feature, NeuroDebian provides virtual machines to run ODIN without a Debian/Ubuntu installation.


    Virtual Samples
    The archive contains more virtual samples which can be used to simulate ODIN sequences.

  • samples.tar.gz

  • #include "tail.wml" odin-1.8.5/docs/Makefile.am0000644000175000017500000000003511322062337012360 00000000000000SUBDIRS = homepage tutorials odin-1.8.5/docs/Makefile.in0000644000175000017500000004077711734622602012416 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = docs DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = homepage tutorials all: all-recursive .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done check-am: all-am check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f Makefile distclean-am: clean-am distclean-generic distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \ install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am check check-am clean clean-generic clean-libtool \ ctags ctags-recursive distclean distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-pdf install-pdf-am \ install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs installdirs-am maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags tags-recursive \ uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/docs/tutorials/0000755000175000017500000000000011735135552012444 500000000000000odin-1.8.5/docs/tutorials/main.tex0000644000175000017500000007167111363773554014055 00000000000000\documentclass{article} %\usepackage{pslatex} % math font does not work \usepackage{latexsym} %\usepackage[german,american]{babel} \usepackage{amsbsy} \usepackage{amsmath} \usepackage[dvips]{graphicx} \usepackage{epsfig} \usepackage{wrapfig} \usepackage{graphics} \usepackage{graphicx} %\usepackage{umlaut} \usepackage{makeidx} \usepackage{fancyhdr} \usepackage{psfrag} \usepackage{amsfonts} \usepackage{cite} \usepackage{index} %\usepackage{doublespace} \usepackage{eurosym} \usepackage{xspace} \usepackage{ulem} \usepackage{moreverb} % more space on page %\addtolength{\voffset}{-1.5cm} \addtolength{\textheight}{3.0cm} \addtolength{\hoffset}{-1.0cm} \addtolength{\textwidth}{2.0cm} % More compact headings \usepackage[compact]{titlesec} % Lamport's page style: \pagestyle{fancy} \addtolength{\headwidth}{\marginparsep} \addtolength{\headwidth}{\marginparwidth} %\renewcommand{\chaptermark}[1]{\markboth{#1}{}} \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} \fancyhf{} \fancyhead[LE,RO]{\bfseries\thepage} \fancyhead[LO]{\bfseries\rightmark} \fancyhead[RE]{\bfseries\leftmark} \fancypagestyle{plain}{ \fancyhead{} \renewcommand{\headrulewidth}{0pt} } % Arial font, either one of these lines works \renewcommand{\rmdefault}{phv}\renewcommand{\sfdefault}{phv} %\usepackage{helvet} \renewcommand{\familydefault}{\sfdefault} \newcommand{\refsec}[1]{section \ref{#1}} \newcommand{\reffig}[1]{Fig. \ref{#1}} % keywords \newcommand{\keyword}[1]{\emph{#1}\index[ind]{#1}} \newcommand{\srckeyword}[1]{\keyword{\tt#1\normalfont}} % Notations, Math symbols \newcommand{\symb}[2]{\index[not]{#1: #2}} % definitions of abbreviations \newcommand{\abbrev}[2]{#1 (#2)\symb{#2}{#1}} % definitions of abbreviations \newcommand{\keywordabbrev}[2]{\emph{#1} (#2)\index[ind]{#1}\symb{#2}{#1}} % figure and table caption \newcommand{\tjcaption}[3]{\caption[#1]{\label{#2} \small #3 \normalsize \\$\quad$\\ }} \newcommand{\TE}{T\!E} \newcommand{\TR}{T\!R} \newcommand{\kspace}{$k$-space~} \newcommand{\grad}{\ensuremath{^{\circ}}} \input{lineno} \makeindex \newindex{not}{ndx}{nnd}{List of Abbreviations} \newindex{ind}{idx}{ind}{Index} %\shortindexingon %\proofmodetrue \begin{document} \normalem %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \author{Thies H. Jochimsen} \title{Short Tutorial for ODIN, the Object-oriented Development Interface for NMR} \maketitle %\Huge %This is work in progress! %\normalsize \tableofcontents \newpage %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\section{Using ODIN} %\subsection{Graphical User Interface} %\subsection{Command-Line Interface} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \section{Sequence Programming} \subsection{Introduction} % In this step-by-step tutorial, we will discover how to program a \abbrev{magnetic resonance}{MR} sequence with ODIN. % As a representative example, a \abbrev{fast spin-echo}{FSE} sequence (also termed turbo spin echo or RARE sequence) will be implemented in this tutorial to introduce ODIN's sequence programming interface and to highlight the benefits of using a truly object-oriented approach for sequence development. % To fully appreciate this tutorial, you should be familiar with the concepts of \abbrev{object-oriented programming}{OOP} (data encapsulation, inheritance, polymorphism), and in particular, with OOP programming in C++. % Before going into detail, here is the full source code of the FSE sequence: \listinginput{1}{sequence_listing.cpp} %listing with line numbers from moreverb package This code can be compiled by saving it to a file with extension .cpp and open it in the ODIN user interface by File$\rightarrow$Open. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{The MR sequence is a C++ class} % Because each MR sequence is an entity with local data (sequence parameters, sequence objects) and functions to operate on this data (initialization, execution, simulation), it is obvious to bundle this structure in a C++ class. % This is exactly how sequences are implemented in ODIN: You create a class that is derived from the base class of all sequences, \srckeyword{SeqMethod}. This is done in \LINENOclass. % Please note that instead of using the term sequence, the term \keyword{method} is often used instead within ODIN to emphasize that the sequence as whole is addressed instead of single sequence objects. Three remarks: First, the \verb|#include| statement in \LINENOinclude integrates all headers necessary for sequence programming. % Second, the macro \srckeyword{METHOD\_CLASS} must be used as the class label for every sequence.\footnote{It will be replaced by a unique string each time the sequence is compiled within the ODIN user interface so that each time it is linked into the process space, a unique symbol is available.} % Third, the macro \srckeyword{ODINMETHOD\_ENTRY\_POINT} in \LINENOentrypoint expands to some extra code required by ODIN and must be at the end of each sequence file. Next, we need a public constructor that accepts a string as a single argument and passes this string to \verb|SeqMethod| as done in \LINENOconstructor. % This constructor is necessary to be able to create an instance of the class while giving it a unique label which is used throughout the ODIN framework to refer to this sequence. % The wicked \srckeyword{STD\_string} is equivalent to \verb|std::string| for internal reasons.\footnote{Some ancient systems have none or a broken C++ standard library and no namespaces. Thus, the macros starting with \tt{}STD\_\normalfont~ are used instead of \tt{}std::\normalfont~ so that ODIN can replace them by its own implementations, if necessary.} Finally, to complete our skeleton of the sequence, we must implement a bunch of virtual functions as shown in \LINENOvirtual. % The purpose of these functions is: \begin{tabular}{l l} & \\ \srckeyword{method\_pars\_init} & Initialize sequence parameters \\ \srckeyword{method\_seq\_init} & Initialize sequence objects and create sequence layout \\ \srckeyword{method\_rels} & (Re)calculate sequence timings \\ \srckeyword{method\_pars\_set} & Final preparations before executing the sequence \\ & \\ \end{tabular} \noindent The ODIN framework will call these functions during initialization/preparation of the sequence. In order to realize our custom sequence, we have to implement these functions. Hence, in the remainder of this tutorial, we will fill these functions with the appropriate code to program our FSE sequence. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Sequence Parameters and Their Initialization} % In the following, the term \keyword{sequence parameters} refers to properties that modify the layout, and hence, the resolution, timing, etc.~of the sequence. Examples are the \abbrev{echo time}{$\TE$}, the \abbrev{repetition time}{$\TR$} and the \abbrev{field of view}{FOV}. % A number of pre-defined sequence parameters are available within the sequence class. They can be accessed via the following pointers and contain the specified class of parameters: \begin{tabular}{l l l} & & \\ Pointer label: & Pointing to type: & Description: \\ \srckeyword{commonPars} & \srckeyword{SeqPars} & Common MR parameters (e.g. $\TE$, $\TR$) \\ \srckeyword{geometryInfo} & \srckeyword{Geometry} & Geometry parameters (e.g. FOV) \\ \srckeyword{systemInfo} & \srckeyword{System} & System settings (e.g. field strength) \\ & & \\ \end{tabular} \noindent Single parameters of these \keyword{parameter blocks} can be retrieved and modified with appropriate \verb|get_| and \verb|set_| methods, as we will see later. % We will also refer to these global objects as \keyword{proxies} because the hide platform specific stuff behind a common interface. % Please refer to the online manual for a list of available member functions. If you write a custom sequence, you probably want to be able to define and use an extra set of parameters. % As it turns out, this is pretty easy in ODIN, all you have to do is to declare the parameter as a (private) member of your method class and tell ODIN that this is a new sequence parameter. % For example, we will need an extra parameter, \verb|Shots|, in our FSE sequence for the number of excitations for each image. % Thus, we first add the parameter as a member to our class (\LINENOshotsdecl). % \srckeyword{JDXint} is the type of our new parameter and makes \verb|Shots| behave exactly like a built-in \verb|int|.\footnote{There are many other types emulating built-in types, such as \tt{}JDXfloat\normalfont~ and \tt{}JDXdouble\normalfont. Composite types are also available, such as \tt{}JDXstring\normalfont, \tt{}JDXcomplex\normalfont~ and arrays. Please refer to the online manual for a complete list.} % Next, we can assign a default value to the parameter in \verb|method_pars_init| (\LINENOshotsdefault). % To register the parameter so that it is recognized by ODIN, for example to display it in the \abbrev{graphical user interface}{GUI}, we must call the function \srckeyword{append\_parameter} in \verb|method_pars_init| of our sequence (\LINENOshotsappend). % After compiling the method, you will see a field with the new parameter on the right-hand side of the ODIN GUI. % As we will see later, the parameter can be used exactly like a regular \verb|int| in our method code. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Designing the Sequence} % In this section, we will create all the sequence objects required for our FSE sequence. The term \keyword{sequence objects} refers to all basic elements of an MR sequence, such as RF pulses, gradient pulses and periods of data acquisitions. % In ODIN, these sequence objects are data members of the sequence class. % In addition, we will see how these sequence objects are combined into sequence containers and used together with sequence loops to form the whole sequence. \subsubsection{RF Pulses} % As the FSE sequence is basically a \abbrev{Carr-Purcell-Meiboom-Gill}{CPMG} sequence, we will need an excitation pulse and a refocusing pulse. % The excitation pulse \verb|exc| is declared in \LINENOexcdecl. It is of type \srckeyword{SeqPulsar} because it uses the same functions as the Pulsar program to calculate pulses. % The pulse is initialized in \LINENOexcinit by using the constructor of the specialized pulse class \srckeyword{SeqPulsarSinc}\footnote{ The following goes on behind the scenes: First, a temporary (unnamed) object of type \tt{}SeqPulsarSinc\normalfont~ is created with the given parameters. Next, the assignment operator of \tt{}SeqPulsar\normalfont~ is called. Because \tt{}SeqPulsarSinc\normalfont~ is derived from \tt{}SeqPulsar\normalfont, all data members of \tt{}SeqPulsar\normalfont~ of the temporary object are copied over to \tt{}exc\normalfont, thereby initializing \tt{}exc\normalfont.}. Several parameters are passed to the constructor: The first assigns a label to the object created. It is convenient to use the same label as that used in source code. The label will be used to refer to the sequence object, for example when plotting the sequence. Next, the constructor expects the slice thickness which is simply taken from the global geometry proxy pointed to by \verb|geometryInfo|. The third parameter is set to \verb|true|, to automatically add a rephasing gradient to the excitation pulse. Finally, we specify the pulse duration (4th parameter) and the flip angle (5th parameter). In an FSE sequence, it is usually a good idea to use the same pulse shape for excitation and refocusing, except for the flip angle. % Thus, for the refocusing pulse \verb|refoc| (declared in \LINENOrefocdecl) we make use of the assignment operator of \verb|SeqPulsar| to create a copy of \verb|exc| and change only those properties which differ (\LINENOrefocinit): % First, the label is changed to \verb|refoc|. Then, the rephasing gradient pulse is removed because it is not necessary for a refocusing pulse. Next, the phase is set to 90\grad (CPMG condition) and the flip angle is changed. Finally, the pulse type is set to \srckeyword{refocusing}\footnote{ This has no direct effect on the sequence time course, but makes calculation gradient moments (e.g. \kspace analysis) possible in the plotting GUI.}. \subsubsection{Gradient Pulses} % For phase encoding, i.e scanning of lines in \kspace, two gradient pulses with variable strength are required to create a linear phase prior to data acquisition and to rewind this phase after acquisition. % We could use the class \srckeyword{SeqGradVector} to achieve this, but then we would have to calculate the gradient strengths ourselves to cover a certain FOV for a certain resolution. Since we are lazy, and ODIN provides a convenient class \srckeyword{SeqGradPhaseEnc} to achieve just that, we will use it to declare both objects (\LINENOpedecl). % The initialization of the first phase encoding gradient \verb|pe1| in \LINENOpeinit requires some explanation: % After specifying the label, resolution (matrix size) and FOV, the channel of the gradient pulse is set to \verb|phaseDirection|\footnote{ This is one of the three possible channels \srckeyword{readDirection}, \srckeyword{phaseDirection} and \srckeyword{sliceDirection} which correspond to the three orthogonal directions in the logical patient coordinate system, which usually differs from the coordinate system spanned by the three gradient coils if the imaging plane is tilted. }. % Next, the maximum gradient strength is set to 1/4 of that possible with the available gradient hardware. The duration of the gradient pulse will then be calculated to achieve the desired phase encoding. % The argument \srckeyword{centerOutEncoding} specifies that instead of linear encoding (scanning \kspace from one edge to the other in sequential order), the central lines are acquired first and then moving outwards from the center. % Finally, the last two arguments are used to separate the phase encoding lines into \verb|Shots| interleaves by using \srckeyword{interleavedSegmented} as the \keyword{reordering scheme}. We will see later how iterate through the phase encoding interleaves and shots by sequence loops. % In \LINENOpecopy, the phase rewinder \verb|pe2| is initialized by making it a copy of \verb|pe1| and inverting its polarity. To suppress free-induction signal of the refocusing pulses, a pair of spoiler gradients is required around each refocusing pulse. % This fairly simple constant gradient pulse of type \srckeyword{SeqGradConstPulse} is declared in \LINENOspoilerdecl and initialized in \LINENOspoilerinit with 1/2 of the maximum gradient strength and 1 ms duration. \subsubsection{Data Acquisition} To sample one line in \kspace between two refocusing pulses in our FSE sequence, an acquisition period has to be created together with a simultaneous read gradient. % We could create this composite object ourselves by using a simple acquisition of type \srckeyword{SeqAcq} and a trapezoidal gradient \srckeyword{SeqGradTrapez}, but again, ODIN provides a convenient composite class to achieve this, namely \srckeyword{SeqAcqRead} which is an acquisition together with a gradient pulse of the same duration. % The object \verb|read| of this type is declared in \LINENOreaddecl and initialized in \LINENOreadinit. % As usual, the first argument to the constructor of \verb|SeqAcqRead| is the object's label. Then, the sweep width (sampling frequency) is specified together with the matrix size in read direction (number of sampling points) and the desired FOV. The desired gradient channel for the gradient is the \verb|readDirection|. This is a good place to explain the concept of \keyword{Interface base classes}, sometimes called \keyword{interface classes}: % An Interface base class is a class which provides a set of (mostly virtual) member function. This class cannot be instantiated, i.e. no object of this class can be created, but it serves as a base class to concrete implementations of this set of member functions (the interface). % For example the class \verb|SeqAcqRead| implements two interfaces, namely \srckeyword{SeqAcqInterface}, which is the base class for all acquisition classes, and \srckeyword{SeqGradInterface}, which is the base class for all classes with one or more gradient pulses. % In this way, all acquisition (or gradient) objects share a common interface. For instance, the member function \srckeyword{get\_acquisition\_start} is reimplemented in each acquisition class to return the duration from the start of the sequence object to the beginning of the actual acquisition (this is necessary for proper timing calculations, see below). % The implementation of this function can be very different, depending on the concrete acquisition class used: % \verb|SeqAcq| will return the duration to trigger the digitizer, and \verb|SeqAcqRead| will also consider the duration of the gradient ramp of the read gradient. % However, the programming interface is the same in both cases which makes it easy to remember the member functions and, more importantly, allows \keyword{polymorphism}: If different acquisition types should be supported within one sequence, member functions can be called via a pointer (or reference) to type \verb|SeqAcqInterface| instead of several \verb|if|-statements. In order to start sampling at one edge of \kspace in read direction, we also need a pre-dephasing gradient pulse. % Again, we could create this ourselves using a \verb|SeqGradConstPulse| object, but there is a more convenient class \srckeyword{SeqAcqDeph} which can be employed. It is declared in \LINENOdephdecl. After the obligatory label as the first argument to the constructor (\LINENOdephinit), a reference to an object derived from \verb|SeqAcqInterface| is expected for which the dephaser will be created. % As we have seen above, the object \verb|read| is derived from \verb|SeqAcqInterface| and can therefore be used as the second argument so that a suitable pre-dephaser will be created. % The last argument \verb|spinEcho| specifies that the pre-dephaser will have the same polarity as the read gradient which is suitable for spin-echo (and, therefore, CPMG) acquisition. \subsubsection{Sequence Containers and Delays} % Having initialized all our basic sequence elements, we now start to group them together to build the whole MR sequence. % For this purpose, \keyword{sequence containers} of type \srckeyword{SeqObjList} are used: For example, we will group the objects within one refocusing interval together in \LINENOechopartinit and assign this composite object to \verb|echopart| (declared in \LINENOechopartdecl) so that we can loop over this part of the sequence later. % As you can see, sequence objects are concatenated by using the + operator. However, just concatenating objects is not enough for our FSE sequence, we must also fulfill CPMG timing constraints. % Therefore, the \keyword{sequence delay} \verb|echodelay| of type \srckeyword{SeqDelay} (declared in \LINENOechodelaydecl and initialized in \LINENOechodelayinit\footnote{Although setting the label is not crucial, it helps debugging as this label shows up in all visualizations of the sequence.}) is used to insert certain waiting periods into the sequence. % We will calculate the duration of this delay later together with the duration of other delay objects. % For now, we just create the basic layout of the sequence. It is also convenient to group the preparation phase into the object \verb|prep| (\LINENOprepdecl) as shown in \LINENOprepinit. % Here, the delay \verb|prepdelay| (\LINENOprepdelaydecl, \LINENOprepdelayinit) will be used to achieve CPMG timing. % Again, we use the + operator to concatenate sequence objects. But since \verb|spoiler| and \verb|deph| are on different gradient channels, they can be played out simultaneously. This is exactly what the / operator does: It makes sequence objects simultaneous, if possible. Otherwise, it will generate an error message. \subsubsection{Sequence Loops} % Next, we will build the sequence part of one shot, that is, the preparation part \verb|prep| followed by a loop over \verb|echopart| (the sequence part of one echo). % In ODIN, loops are possible with the class \srckeyword{SeqObjLoop}, which is, like \verb|SeqObjList|, a container to hold other sequence objects in sequential order. In the following, this contents will be called the \keyword{kernel} of the loop. % In addition, \verb|SeqObjLoop| allows looping over the kernel to repeat its execution. % At each iteration, properties of so-called \keyword{sequence vectors} can be changed. These sequence vectors are all classes derived from \srckeyword{SeqVector}. % Thereby, a loop can be employed as follows: % First, a loop object is declared in \LINENOecholoopdecl. Then, to iterate over a kernel \verb|kern| while iterating properties of \verb|vec1|, \verb|vec2|, ..., the basic syntax is\footnote{This syntax becomes possible by overloading the ( ) and [ ] operator of \tt{}SeqObjLoop\normalfont.} \begin{verbatim} echoloop ( kern ) [vec1][vec2]... \end{verbatim} % In our sequence, this syntax is used in \LINENOoneshotinit to iterate over \verb|echopart| while iterating the values of \verb|pe1| and \verb|pe2|. Here iterating simply means to change the strength of the phase encoding gradient so that different lines in \kspace are scanned at each echo, according to the encoding and reordering scheme specified above. But we are not done yet because we have only build the sequence for one shot. % Thus, we need another loop \verb|shotloop| (\LINENOshotloopdecl) to iterate over the different shots. % At each of these iterations, \verb|pe1| and \verb|pe2| have to be aware that the next interleave of phase encoding steps has to be used. % For this purpose, each sequence vector has a \keyword{reordering vector}. Whenever a certain reordering scheme is used (as done above by the constructor of \verb|SeqGradPhaseEnc| or by the function \srckeyword{set\_reorder\_scheme}), the reordering vector is used to iterate over the set of modified arrangements of the values of the vector, for example over the interleaves, if \verb|interleavedSegmented| is used as the reordering scheme. % The reordering vector, just like every other vector, can be attached to a loop to iterate over it. % It can be retrieved from its parent vector by the function \srckeyword{get\_reorder\_vector}. % This is done in \LINENOsetsequence: The reordering vectors of \verb|pe1| and \verb|pe2| are attached to the loop \verb|shotloop| while repeating \verb|oneshot|. % A padding delay \verb|relaxdelay| (\LINENOrelaxdelaydecl, \LINENOrelaxdelayinit) is also added which we use later to adjust the correct $\TR$. Within the same line, the function \srckeyword{set\_sequence} of the base class \verb|SeqMethod| is used to specify the whole sequence, i.e. to tell the ODIN framework what to use when plotting/executing/simulating our sequence. % Using this function is usually the last step in \verb|method_seq_init|. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{(Re)Calculating Sequence Timings} In the previous section, we have created the basic layout of the sequence, but ignored the timing constraints of our FSE sequence. % This will be done now, namely in the member function \verb|method_rels| of our method class\footnote{Using a separate member function for timing calculations, which are usually fast compared to all the initialization stuff in \tt{}method\_seq\_init\normalfont, has the advantage that, if only timing settings of the sequence change, \tt{}method\_rels\normalfont~ is the only function to be called. }. % First, we will calculate the minimum $\TE$ possible which is equivalent to the CPMG refocusing interval. % This either limited by the minimum duration possible with our preparation (\LINENOminTEprep), or by the refocusing interval (\LINENOminTEecho). % Here, the functions \srckeyword{get\_duration} and \srckeyword{get\_magnetic\_center} return the duration of the corresponding sequence object\footnote{ The container \tt{}echopart\normalfont~ is a sequence object itself whereby \tt{}get\_duration\normalfont~ returns the total duration of the concattenated objects it contains.} and the time point of the center of the pulse relative to its beginning, respectively. % Next, we calculate the maximum of both in \LINENOminTE and set the global $\TE$ (in \verb|commonars|) to this value (\LINENOsetTE). Here, the second argument \srckeyword{noedit} indicates that the parameter cannot be edited by the user, it will be indicated as such in the GUI. % Finally, we adjust the duration of the padding delays to match the calculated $\TE$ in \LINENOprepdelayset and \LINENOechodelayset using the \srckeyword{set\_duration} function. A similar technique is used to set the minimum $\TR$ possible and adjust the corresponding padding delay (\LINENOsetTR). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \subsection{Image Reconstruction} The sequence is now complete and could be executed on the scanner, but image reconstruction would fail because ODIN does not know where to put each line, which was acquired with the \verb|read| object, in \kspace. We have to inform ODIN explicitely that the vector object \verb|pe1| was responsible for phase encoding. This is done in \LINENOrecoline. The first argument of \srckeyword{set\_reco\_vector} is of type \srckeyword{recoDim} which is an enum used to specify so-called \keyword{reconstruction dimensions}. These can be, for instance: % \begin{itemize} \item Phase encoding step (\srckeyword{line}) \item Slice index (\srckeyword{slice}) \item Echo number (\srckeyword{echo}) \item User-defined index (\srckeyword{userdef}) \end{itemize} % The second argument is a vector object which was responsible to iterate through this dimension. % For example, if we would add multi-slice excitation, we would add a frequency list to \verb|exc| (using \srckeyword{set\_freqlist}) and then use \verb|exc| as the slice vector. After execution of the sequence, the complex data of the acquired NMR signal is stored on disk in the so-called \abbrev{scan directory}{scandir} in the order it was acquired. This is achieved by using the native mechanisms (e.g. on Bruker and GE) or by a custom reconstruction routine which does nothing but dumping the raw data to the hard drive (e.g. on Siemens). % However, just storing the raw data would not be enough to reconstruct an image. Extra information like the one above (location of each acquisition in \kspace) is required. Therefore, an extra file \srckeyword{recoInfo}, which contains this information in human-readable ASCII format, is stored together with the raw data in the scandir. % The file is a serialized version of the class \srckeyword{RecoPars}, which means that on object of this type can read/write the file and queried subsequently for its values. Finally, the program \srckeyword{odinreco}, which is part of ODIN will retrieve all information from \verb|recoInfo| and generate image data. It is executed in the scandir on the command line with \begin{verbatim} odinreco \end{verbatim} to create the reconstructed image data. Please refer to the online manual for further documentation how to fine tune the reconstruction. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\subsection{Sequence Internals} %In this section, the internal layout of the example sequence will be described, %i.e. how the sequence objects used are composed of other more basic sequence objects. %\subsubsection{Excitation pulse} % %We will start with the excitation pulse \verb|exc|: It is of type \srckeyword{SeqPulsarSinc} %which is derived from \srckeyword{SeqPulsar} (class for representing arbitrary RF pulses). %In the constructor of \srckeyword{SeqPulsarSinc}, various pulse parameters (shape, filter, ...) %of \srckeyword{SeqPulsar} are set so that a sinc-shaped pulse is generated. %The class \srckeyword{SeqPulsar} has two base classes: \srckeyword{SeqPulsNdim} %and \srckeyword{OdinPulse}. The latter contains the logic to calculate %RF and gradient waveforms for frequency and/or spatially selective pulses. %It has a number of \verb|set|/\verb|get| functions to set pulse specific %parameters. % %Since \srckeyword{OdinPulse} is a bass class of \srckeyword{SeqPulsar}, these %\verb|set|/\verb|get| functions are all available in \srckeyword{SeqPulsar} %to specify all details of a pulse in the method. % %However, \srckeyword{OdinPulse} does not know how to insert itself into the sequence. %Therefore, the second base class \srckeyword{SeqPulsNdim} contains sub-objects %to play out the calculated RF and gradient shapes in the sequence: % %In essence, it contains an atomic RF object \srckeyword{SeqPuls} and three %atomic \srckeyword{SeqGradWave} to play out the gradient waveform(s). %The class \srckeyword{SeqPuls} will talk to the actual scanner hardware via %the driver plugin for RF (the member \verb|pulsdriver|). % %This member is a wrapper which has a pointer-like syntax. %With this 'pointer', a driver interface \srckeyword{SeqPulsDriver} is accessible. %The actual object behind this interface is the an implementation of \srckeyword{SeqPulsDriver} %of the current platform. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \newpage \addcontentsline{toc}{section}{\numberline{}Index} \printindex[ind] \newpage \addcontentsline{toc}{section}{\numberline{}List of Abbreviations} \printindex[not] \end{document} odin-1.8.5/docs/tutorials/Makefile.am0000644000175000017500000000217611322062337014416 00000000000000EXTRA_DIST = main.tex if ONLY_LIBS else sequence_listing.cpp: sequence.cpp cat sequence.cpp | sed s/\\/\\/.*// > sequence_listing.cpp lineno.tex: main.tex lineno.awk sequence_listing.cpp cat sequence.cpp | awk -f ./lineno.awk > lineno.tex main.ndx: main.tex lineno.tex sequence_listing.cpp latex main.tex && latex main.tex && latex main.tex main.ind: main.idx makeindex main.idx main.nnd: main.ndx makeindex main.ndx mv main.ilg main.nlg mv main.ind main.nnd main.dvi: main.tex lineno.tex sequence_listing.cpp main.nnd main.ind latex main.tex && latex main.tex && latex main.tex main.ps: main.dvi dvips main -o main.ps main.2.ps: main.ps psnup -2 main.ps main.2.ps main.pdf: main.ps ps2pdf main.ps main.pdf Makefile.sequence: genmakefile sequence > Makefile.sequence sequence: Makefile.sequence sequence.cpp make -f Makefile.sequence test: sequence ./test.sh endif clean-local: if test -f Makefile.sequence ; then make -f Makefile.sequence clean ; fi -rm -rf Makefile.sequence sequence_listing.cpp lineno.tex *.toc *.ind *.idx *.ilg *.glo *.ndx *.nlg *.nnd *.lof *.bbl *.blg *.dvi *.log *.ps *.pdf *.aux *.out odin-1.8.5/docs/tutorials/Makefile.in0000644000175000017500000002574611734622602014443 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = docs/tutorials DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = main.tex all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu docs/tutorials/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu docs/tutorials/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am @ONLY_LIBS_FALSE@sequence_listing.cpp: sequence.cpp @ONLY_LIBS_FALSE@ cat sequence.cpp | sed s/\\/\\/.*// > sequence_listing.cpp @ONLY_LIBS_FALSE@lineno.tex: main.tex lineno.awk sequence_listing.cpp @ONLY_LIBS_FALSE@ cat sequence.cpp | awk -f ./lineno.awk > lineno.tex @ONLY_LIBS_FALSE@main.ndx: main.tex lineno.tex sequence_listing.cpp @ONLY_LIBS_FALSE@ latex main.tex && latex main.tex && latex main.tex @ONLY_LIBS_FALSE@main.ind: main.idx @ONLY_LIBS_FALSE@ makeindex main.idx @ONLY_LIBS_FALSE@main.nnd: main.ndx @ONLY_LIBS_FALSE@ makeindex main.ndx @ONLY_LIBS_FALSE@ mv main.ilg main.nlg @ONLY_LIBS_FALSE@ mv main.ind main.nnd @ONLY_LIBS_FALSE@main.dvi: main.tex lineno.tex sequence_listing.cpp main.nnd main.ind @ONLY_LIBS_FALSE@ latex main.tex && latex main.tex && latex main.tex @ONLY_LIBS_FALSE@main.ps: main.dvi @ONLY_LIBS_FALSE@ dvips main -o main.ps @ONLY_LIBS_FALSE@main.2.ps: main.ps @ONLY_LIBS_FALSE@ psnup -2 main.ps main.2.ps @ONLY_LIBS_FALSE@main.pdf: main.ps @ONLY_LIBS_FALSE@ ps2pdf main.ps main.pdf @ONLY_LIBS_FALSE@Makefile.sequence: @ONLY_LIBS_FALSE@ genmakefile sequence > Makefile.sequence @ONLY_LIBS_FALSE@sequence: Makefile.sequence sequence.cpp @ONLY_LIBS_FALSE@ make -f Makefile.sequence @ONLY_LIBS_FALSE@test: sequence @ONLY_LIBS_FALSE@ ./test.sh clean-local: if test -f Makefile.sequence ; then make -f Makefile.sequence clean ; fi -rm -rf Makefile.sequence sequence_listing.cpp lineno.tex *.toc *.ind *.idx *.ilg *.glo *.ndx *.nlg *.nnd *.lof *.bbl *.blg *.dvi *.log *.ps *.pdf *.aux *.out # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odin/0000755000175000017500000000000011735135551010416 500000000000000odin-1.8.5/odin/odindialog_tree.cpp0000644000175000017500000000260211322062346014163 00000000000000#include "odindialog_tree.h" #include "odincomp.h" TreeDialog::TreeDialog(QWidget *parent, const char* caption, const svector& column_labels) : GuiDialog(parent,caption,false) { grid=new GuiGridLayout(GuiDialog::get_widget(), 1, 1); root=new GuiListView(GuiDialog::get_widget(), column_labels, 400, 400, 0, true); grid->add_widget( root->get_widget(), 0, 0 ); } TreeDialog::~TreeDialog() { delete root; delete grid; } void TreeDialog::display_node(const SeqClass* thisnode, const SeqClass* parentnode, int treelevel, const svector& columntext) { Log odinlog("TreeDialog","display_node"); GuiListItem* item=0; if(lastitemmap.size()) { // sub-node GuiListItem* parentitem=nodemap[parentnode]; GuiListItem* lastitem=lastitemmap[parentitem]; ODINLOG(odinlog,normalDebug) << "columntext=" << columntext.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "parentnode/parentitem/lastitem=" << (void*)parentnode << "/" << parentitem << "/" << lastitem << STD_endl; item=new GuiListItem(parentitem, lastitem, columntext); ODINLOG(odinlog,normalDebug) << "item=" << item << STD_endl; lastitemmap[parentitem]=item; } else { // top-level node item=new GuiListItem(root,columntext); ODINLOG(odinlog,normalDebug) << "(root)item=" << item << STD_endl; } lastitemmap[item]=0; // insert dummy element at beginning nodemap[thisnode]=item; } odin-1.8.5/odin/odindialog_pulsar.cpp0000644000175000017500000000421211322062346014531 00000000000000#include "odindialog_pulsar.h" #include "odincomp.h" #include PulsarDialog::PulsarDialog(const STD_list& pulses, const STD_string& pulsarcmd, STD_list& subprocs, const STD_string& tmpdir, const STD_string& systemInfoFile, QWidget *parent) : GuiDialog(parent,"Pulsar Pulses",false), pulsar_cmd(pulsarcmd), procs(subprocs), tmp_dir(tmpdir), systemInfo_file(systemInfoFile) { grid=new GuiGridLayout(GuiDialog::get_widget(), 2, 1); svector collabel; collabel.resize(3); collabel[0]="Pulse (Click to view in Pulsar)"; collabel[1]="Duration["+STD_string(ODIN_TIME_UNIT)+"]"; collabel[2]="Properties"; pulsar_list=new GuiListView (GuiDialog::get_widget(), collabel, 200, 300, this); grid->add_widget( pulsar_list->get_widget(), 0, 0 ); for(STD_list::const_iterator it=pulses.begin(); it!=pulses.end(); ++it) { collabel[0]=(*it)->get_label(); collabel[1]=ftos((*it)->get_Tp()); collabel[2]=(*it)->get_properties(); GuiListItem* pulse_item=new GuiListItem(pulsar_list, collabel); pulse_map[pulse_item]=(*it); } pb_done = new GuiButton( GuiDialog::get_widget(), this, SLOT(emitDone()), "Done" ); grid->add_widget( pb_done->get_widget(), 1, 0, GuiGridLayout::Center ); // connect( pb_done->get_widget(), SIGNAL(clicked()), this,SLOT(emitDone()) ); GuiDialog::show(); } void PulsarDialog::clicked(GuiListItem* item) { Log odinlog("PulsarDialog","clicked"); ODINLOG(odinlog,normalDebug) << "item=" << item << STD_endl; if(item) { STD_string plsfile(tmp_dir+"pulsar.pls"); pulse_map[item]->write(plsfile); STD_string cmdstring("\""+pulsar_cmd+"\" -noedit -s \""+systemInfo_file+"\" \""+plsfile+"\""); ODINLOG(odinlog,normalDebug) << "cmdstring=" << cmdstring << STD_endl; Process proc; proc.start(cmdstring); procs.push_back(proc); } } void PulsarDialog::emitDone() { GuiDialog::done(); } PulsarDialog::~PulsarDialog() { for(STD_map::const_iterator it=pulse_map.begin(); it!=pulse_map.end(); ++it) { delete it->first; } delete pulsar_list; delete pb_done; delete grid; } odin-1.8.5/odin/odindialog_debug.cpp0000644000175000017500000000413411322062346014314 00000000000000#include #include // for connecting signals #include "odindialog_debug.h" DebugDialog::DebugDialog(QWidget *parent) : GuiDialog(parent, "Debugging/Tracing Options",false) { #ifdef ODIN_DEBUG int mapsize=LogBase::global->components.size(); grid = new GuiGridLayout( GuiDialog::get_widget(), mapsize+1, 2 ); STD_map::const_iterator it; svector debuglevels; debuglevels.resize(numof_log_priorities); for(int i=0; icomponents.begin();it!=LogBase::global->components.end();++it) { QLabel* ql=new QLabel(GuiDialog::get_widget()); ql->setText(it->first.c_str()); grid->add_widget( ql, row, 0, GuiGridLayout::Center ); GuiComboBox* cb = new GuiComboBox( GuiDialog::get_widget(), debuglevels ); log_component_fptr fp=it->second; cb->set_current_item(fp(ignoreArgument)); grid->add_widget( cb->get_widget(), row, 1, GuiGridLayout::Center ); connect( cb->get_widget(), SIGNAL(activated(int)),this, SLOT(levelChanged(int)) ); debugenums.push_back(cb); row++; } pb_done = new GuiButton( GuiDialog::get_widget(), this, SLOT(emitDone()), "Done" ); grid->add_widget( pb_done->get_widget(), mapsize, 1, GuiGridLayout::Center ); // connect( pb_done->get_widget(), SIGNAL(clicked()), this,SLOT(emitDone()) ); GuiDialog::show(); #endif } DebugDialog::~DebugDialog() { #ifdef ODIN_DEBUG for(STD_list::const_iterator dbgit=debugenums.begin();dbgit!=debugenums.end();++dbgit) delete (*dbgit); delete pb_done; delete grid; #endif } void DebugDialog::levelChanged(int) { #ifdef ODIN_DEBUG STD_map::const_iterator it=LogBase::global->components.begin(); for(STD_list::const_iterator dbgit=debugenums.begin();dbgit!=debugenums.end();++dbgit) { LogBase::set_log_level(it->first.c_str(),logPriority((*dbgit)->get_current_item())); ++it; } #endif } void DebugDialog::emitDone() { #ifdef ODIN_DEBUG GuiDialog::done(); emit finished(); #endif } odin-1.8.5/odin/odindialog_pulsar.h0000644000175000017500000000361111322062346014200 00000000000000/*************************************************************************** odindialog_pulsar.h - description ------------------- begin : Mon Oct 10 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_PULSAR_H #define ODINDIALOG_PULSAR_H #include #include #include class SeqPulsar; // forward declaration class PulsarDialog : public QObject, public GuiDialog, public GuiListViewCallback { Q_OBJECT public: PulsarDialog(const STD_list& pulses, const STD_string& pulsarcmd, STD_list& subprocs, const STD_string& tmpdir, const STD_string& systemInfoFile, QWidget *parent); ~PulsarDialog(); private slots: void emitDone(); private: // overloading virtual function of GuiListViewCallback void clicked(GuiListItem* item); GuiGridLayout* grid; GuiListView* pulsar_list; GuiButton* pb_done; STD_map pulse_map; STD_string pulsar_cmd; STD_list& procs; STD_string tmp_dir; STD_string systemInfo_file; }; #endif odin-1.8.5/odin/odindebugger.cpp0000644000175000017500000000164311322062346013475 00000000000000#include "odindebugger.h" #include "odincomp.h" #include "odinconf.h" #ifdef HAVE_UNISTD_H #include #endif /////////////////////////////////////////////////////////////////////////////// bool OdinDebugger::attach() { Log odinlog("OdinDebugger","attach"); int mypid=-1; #ifdef HAVE_UNISTD_H mypid=getpid(); #endif if(mypid<=0) return false; #ifdef HAVE_GDB_XTERM STD_string batfile("c"); // continue cmd for gdb STD_string batfname(OdinConf::get_tmpdir()+SEPARATOR_STR+"gdb.bat."+itos(mypid)); ::write(batfile,batfname); STD_string cmd("xterm -geometry 80x10+0+0 -e 'gdb -x "+batfname+" odin "+itos(mypid)+"'"); ODINLOG(odinlog,normalDebug) << "Running command " << cmd << STD_endl; return debugger_proc.start(cmd); #else ODINLOG(odinlog,errorLog) << "gdb or xterm is missing" << STD_endl; return false; #endif } bool OdinDebugger::detach(){ return debugger_proc.kill(); } odin-1.8.5/odin/odindebugger.h0000644000175000017500000000242111322062346013135 00000000000000/*************************************************************************** logger.h - description ------------------- begin : Fri Nov 11 21:30:11 CEST 2003 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OdinDebugger_H #define OdinDebugger_H #include ///////////////////////////////////////////// class OdinDebugger { public: OdinDebugger() {} bool attach(); bool detach(); private: Process debugger_proc; }; #endif odin-1.8.5/odin/odincomp.h0000644000175000017500000000223611322062346012313 00000000000000/*************************************************************************** odincomp.h - description ------------------- begin : Sun Oct 3 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINCOMP_H #define ODINCOMP_H // for debugging ODIN component class OdinComp { public: static const char* get_compName(); }; #endif odin-1.8.5/odin/odinconf.h0000644000175000017500000000570011455553540012311 00000000000000/*************************************************************************** odinconf.h - description ------------------- begin : Fri Nov 11 21:30:11 CEST 2003 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OdinConf_H #define OdinConf_H #include #include #include #include /////////////////////////////////////////////////////////////////// #define DEFAULT_METH_ROOT "odin-methods" /////////////////////////////////////////////////////////////////// class QWidget; // forward declaration /////////////////////////////////////////////////////////////////// struct OdinConf : public JcampDxBlock { OdinConf(const STD_string& label="unnamedOdinConf", bool ignore_environment = false); JDXfileName sourcecode; JDXfileName editor; JDXfileName browser; JDXfileName methroot; JDXfileName smpfile; JDXfileName protfile; JDXfileName compiler; // Set once on startup, do not include in file JDXfileName linker; // Set once on startup, do not include in file JDXstring compiler_flags; JDXstring extra_includes; JDXstring extra_libs; JDXstringArr selectedMethods; JDXbool attachDebugger; bool init(QWidget* parent); svector get_method_compile_chain() const; // helper functions static STD_string get_binprefix(); static STD_string get_homedir(); static STD_string get_seqexamplesdir(); static STD_string get_samplesdir(); static STD_string get_coilsdir(); static STD_string get_confdir(); static STD_string get_tmpdir(); static STD_string get_manual_location(); bool display_html(const STD_string& location, STD_list& subprocs); bool open_ascfile(const STD_string& filename, STD_list& subprocs); static STD_string get_installdir(); #ifndef USING_WIN32 static bool start_proc(const STD_string& program, const STD_string& filename, STD_list& subprocs); #endif private: static STD_string get_registryvalue(const STD_string& keyname, const STD_string& valuename); static STD_string get_datadir(); static bool ignore_env; // for clean start in IDEA }; #endif odin-1.8.5/odin/odindialog_idea.cpp0000644000175000017500000012276211322062346014140 00000000000000#include "odindialog_idea.h" #include "odincomp.h" #include "odindialog_process.h" #include #include //////////////////////////////////////////////////////////////////////////////////////// // Helper functions bool select_alternative(JDXfileName& result, const STD_list& alternatives, QWidget *parent=0) { Log odinlog("","select_alternative"); if(parent && alternatives.size()>1) { // Ask with dialog if parent is provided JDXenum alts; alts.set_label("Alternatives"); for(STD_list::const_iterator it=alternatives.begin(); it!=alternatives.end(); ++it) alts.add_item(*it); JcampDxBlock block("Select Alternative"); block.append(alts); new JDXwidgetDialog(block,1,parent,true); result=alts.operator STD_string(); } else { for(STD_list::const_iterator it=alternatives.begin(); it!=alternatives.end(); ++it) { result=*it; bool exists=result.exists(); ODINLOG(odinlog,normalDebug) << "exists(" << result << ")=" << exists << STD_endl; if(exists) return true; result=""; } } return false; } void select_idea_include_dirs(STD_string& result, const STD_list& possible_dirs, const IdeaOpts& opts) { JDXfileName testdir; testdir.set_dir(true); STD_string ideadir_slash=opts.get_ideadir_slash(); for(STD_list::const_iterator it=possible_dirs.begin(); it!=possible_dirs.end(); ++it) { testdir=ideadir_slash+SEPARATOR_STR+(*it); if(testdir.exists()) { result+=" -I"+ideadir_slash+"/"+(*it); // use forward slashes for includes } } } svector match_in_dir(const STD_string& dir, const STD_string& match) { svector result; svector dirs=browse_dir(dir, true,true); for(unsigned int i=0; i odinlog("IdeaOpts","set_defaults"); STD_list possible_arch; possible_arch.push_back(conf.get_installdir()+SEPARATOR_STR+"src"+SEPARATOR_STR+PACKAGE+"-"+VERSION+".tar.gz"); select_alternative(arch,possible_arch); STD_list possible_ideadirs; JDXfileName midearoot("C:/MIDEA"); midearoot.set_dir(true); if(midearoot.exists()) { // VB* svector mideadirs=match_in_dir("C:/MIDEA", "n4_"); for(unsigned int i=0; i possible_seqdirs; possible_seqdirs.push_back(ideadir+SEPARATOR_STR+"n4/pkg/MrServers/MrImaging/seq"); possible_seqdirs.push_back(ideadir+SEPARATOR_STR+"n4/comp/Application/seq"); select_alternative(seqdir,possible_seqdirs); odin2idea_label="odin"; STD_list possible_icedirs; possible_icedirs.push_back(ideadir+SEPARATOR_STR+"n4/pkg/MrServers/MrIcePrograms"); // pre VB15 possible_icedirs.push_back(ideadir+SEPARATOR_STR+"n4/pkg/MrServers/MrVista/Ice/IceIdeaFunctors"); // VB15 possible_icedirs.push_back(seqdir); // fallback select_alternative(icedir,possible_icedirs); vxworks_heap_size=3; debug_vxworks_host=false; JDXfileName ccpentium(ideadir+"/n4_fsp/tornado/i86/host/x86-win32/bin/ccpentium.exe"); if(ccpentium.exists()) vxworks_cpu.set_actual("PENTIUM"); else vxworks_cpu.set_actual("PPC750"); make_jobs=numof_cores(); make_clean=true; } ///////////////////////////////////////////////////////////////////////////// STD_string IdeaOpts::get_vxworks_postfix() const { STD_string result; if(tolowerstr(vxworks_cpu).find("pentium")!=STD_string::npos) result="pentium"; else result="ppc"; return result; } STD_string IdeaOpts::get_vxworks_ext() const { STD_string result; if(tolowerstr(vxworks_cpu).find("pentium")!=STD_string::npos) result="i86"; else result="ppc"; return result; } STD_string IdeaOpts::get_vxworks_Makefile() const { STD_string result; if(tolowerstr(vxworks_cpu).find("pentium")!=STD_string::npos) result="MakI86.txt"; else result="MakPpc3.txt"; return result; } ///////////////////////////////////////////////////////////////////////////// IdeaDialog::IdeaDialog(QWidget *parent, IdeaOpts& opts, const OdinConf& conf) : GuiDialog(parent,"Compile ODIN for IDEA",true), opts_cache(opts), conf_cache(conf) { Log odinlog("IdeaDialog","IdeaDialog"); grid=new GuiGridLayout(GuiDialog::get_widget(), 2, 3); optswidget=new JDXwidget(opts,2,GuiDialog::get_widget()); connect(optswidget,SIGNAL(valueChanged()),this,SLOT(update())); grid->add_widget( optswidget, 0, 0, GuiGridLayout::Default, 1, 3 ); pb_cancel = new GuiButton( GuiDialog::get_widget(), this, SLOT(cancel()), "Cancel" ); grid->add_widget( pb_cancel->get_widget(), 1, 0, GuiGridLayout::Center ); pb_defaults = new GuiButton( GuiDialog::get_widget(), this, SLOT(defaults()), "Defaults" ); grid->add_widget( pb_defaults->get_widget(), 1, 1, GuiGridLayout::Center ); pb_compile = new GuiButton( GuiDialog::get_widget(), this, SLOT(compile()), "Compile" ); grid->add_widget( pb_compile->get_widget(), 1, 2, GuiGridLayout::Center ); update(); // initialize on startup GuiDialog::show(); } void IdeaDialog::cancel() { GuiDialog::cancel(); } void IdeaDialog::defaults() { opts_cache.set_defaults(conf_cache, GuiDialog::get_widget()); update(); // update other parameters optswidget->updateWidget(); emit changed(); } void IdeaDialog::compile() { emit changed(); do_compile(); GuiDialog::done(); } void IdeaDialog::error_msg(const STD_string& msg) { message_question(msg.c_str(), "Error Compiling ODIN for IDEA", GuiDialog::get_widget(), false, true); } int IdeaDialog::find_in_alternatives(const STD_string& findstr, const STD_list& alternatives) { JDXfileName fname; if(!select_alternative(fname, alternatives)) { error_msg("Cannot find file containing "+findstr); return -1; } else { STD_string str; if(load (str, fname)<0) { error_msg("Cannot load file "+fname); return -1; } else { if(str.find(findstr)!=STD_string::npos) { return 1; } } } return 0; } STD_string IdeaDialog::hosttarget(bool debug, const STD_string& build_includes, const STD_string& global_conf, const STD_string& mprefix, const STD_string& make_install) const { STD_string flags; STD_string target; if(debug) {flags=opts_cache.hostd_flags; target="hostd";} else {flags=opts_cache.host_flags; target="host";} STD_string win_cxx_mgwpath=mgwpath(opts_cache.win_cxx); STD_string confstr; confstr+=" LD="+mgwpath(opts_cache.msvcdir)+"/VC98/Bin/link.exe"; confstr+=" CXX="+win_cxx_mgwpath; confstr+=" CXXFLAGS=\""+flags+" "+build_includes+"\""; confstr+=" CC="+win_cxx_mgwpath; confstr+=" CFLAGS=\""+flags+"\""; confstr+=" ../../${ARCHNAME}/configure "+global_conf; confstr+=" --prefix="+opts_cache.get_odindir_slash()+"/"+target; if(debug) confstr+=" --enable-debug"; else confstr+=" ${DEBUGOPT}"; confstr+=" --with-extra-odinseq-include-path=-I"+opts_cache.get_ideadir_slash()+"/SWF_extern/SDK/include"; // Since VB15 code compiles only with the SDK provided by IDEA, and ODIN compiles only with VC++ SDK, we need a separate include path for odinseq where IDEA code is included STD_string result; result+="configure-"+target+":\n"; result+=mprefix+"cd "+target+"/build && "+confstr+"\n"; result+=mprefix+"cat "+target+"/build/libtool | sed s/\\\\.libs/libs/g > "+target+"/build/libtool.tmp\n"; // dot in .libs confuses lib.exe in MinGW result+=mprefix+"mv "+target+"/build/libtool.tmp "+target+"/build/libtool\n\n"; result+="build-"+target+":\n"; result+=mprefix+"cd "+target+"/build && "+make_install+"\n\n"; result+="build-"+target+"-clean: build-"+target+"\n"; result+=mprefix+"rm -rf "+target+"/build\n\n"; return result; } STD_string IdeaDialog::errcodes_src(const STD_string& msgfile) { STD_string str=dos2unix(msgfile); STD_string blockbegin("MessageId:"); STD_string blockend("#define"); STD_string result; STD_string txt; do { txt=extract(str, blockbegin, blockend); if(txt!="") { STD_string errcode=shrink(extract(txt, "", "*/")); STD_string msg=extract(txt, "MessageText:", ""); msg=replaceStr(msg, "/*", ""); msg=replaceStr(msg, "*/", ""); msg=justificate(msg,0,false,1000); msg=replaceStr(msg, "\n", ""); result+="if(code=="+errcode+") return \""+msg+"\";\n"; str=rmblock(str, blockbegin, blockend, true, true, false); } } while(txt!=""); return result; } void IdeaDialog::do_compile() { Log odinlog("IdeaDialog","do_compile"); JDXfileName msys_bin(conf_cache.get_installdir()+SEPARATOR_STR+"msys"+SEPARATOR_STR+"bin"); JDXfileName make(msys_bin+"/make.exe"); if(!make.exists()) { error_msg("Cannot find make program "+make); return; } if(createdir(opts_cache.odindir.c_str())) { error_msg("Cannot create target directory "+opts_cache.odindir); return; } if(copyfile(opts_cache.arch.c_str(), (opts_cache.odindir+SEPARATOR_STR+opts_cache.arch.get_basename()).c_str())) { error_msg("Cannot copy "+opts_cache.arch+" to target directory "+opts_cache.odindir); return; } // Parse IDEA error codes JDXfileName msgfile; STD_list msgfile_alternatives; msgfile_alternatives.push_back(opts_cache.ideadir+"/n4/x86/delivery/include/Measurement/Sequence/libRT/libRTmsg.h"); // pre VA25 msgfile_alternatives.push_back(opts_cache.ideadir+"/n4/x86/delivery/include/MrServers/MrMeasSrv/SeqIF/libRT/libRTmsg.h"); // VA25 and later if(!select_alternative(msgfile, msgfile_alternatives)) { error_msg("Cannot find file for IDEA error codes"); return; } STD_string msgfilestr; if(load(msgfilestr,msgfile)<0) { error_msg("Cannot load file for IDEA error codes"); return; } STD_string msgsrc=errcodes_src(msgfilestr); STD_string msgsrc_fname="idea_errcodes.cpp"; if(write(msgsrc,opts_cache.odindir+SEPARATOR_STR+msgsrc_fname)<0) { error_msg("Cannot write file for IDEA error codes"); return; } STD_string makestr="\""+mgwpath(make)+"\""; STD_string make_install=makestr+" install"; if(opts_cache.make_jobs>1) { make_install="MAKEFLAGS=\"-j "+itos(opts_cache.make_jobs)+"\" "+makestr+" -e install"; } STD_string makefile; JDXfileName shell=msys_bin+SEPARATOR_STR+"sh.exe"; if(!shell.exists()) { error_msg("Cannot find shell "+shell); return; } makefile+="SHELL = \""+mgwpath(shell)+"\"\n\n"; makefile+="SETPATH = PATH=\""+mgwpath(msys_bin)+"\":$$PATH;\n\n"; STD_string mprefix="\t${SETPATH} "; makefile+="SUBDIRS = vxworks host hostd\n\n"; makefile+="ARCHNAME = "+replaceStr(opts_cache.arch.get_basename(),".tar.gz","")+"\n\n"; makefile+="ODIN2IDEA_LABEL = "+opts_cache.odin2idea_label+"\n"; makefile+="ODIN2IDEADIR_MGWPATH = "+mgwpath(opts_cache.seqdir)+"/${ODIN2IDEA_LABEL}\n"; makefile+="ODIN2IDEADIR_SLASH = "+replaceStr(opts_cache.seqdir,"\\","/")+"/${ODIN2IDEA_LABEL}\n\n"; makefile+="ICEODINDIR = \""+mgwpath(opts_cache.icedir)+"/IceOdin\"\n\n"; makefile+="DEBUGOPT = "; if(!opts_cache.debug_vxworks_host) makefile+="# "; // just comment out if release is enabled makefile+="--enable-debug\n\n"; STD_string global_conf="--enable-only-idea-plugin --enable-ideasupport --disable-cmdline --disable-threads --disable-unit-test --enable-static --disable-shared"; STD_string odindir_slash=opts_cache.get_odindir_slash(); // use forward slashes for includes STD_string build_includes="-I"+odindir_slash+"/${ARCHNAME}"; makefile+="all: build\n\n"; // default: recompile odin makefile+="unpack:\n"; makefile+=mprefix+"tar -xvzf ${ARCHNAME}.tar.gz\n"; makefile+=mprefix+"cp "+msgsrc_fname+" ${ARCHNAME}/platforms/IDEA_n4/odinseq_idea/\n"; makefile+=mprefix+"mkdir -p /tmp\n"; // hacking configure: // 1) default file extension for C++ source code since .cc somehow fails with autoconf 2.59 ... // 2) replace limits.h (which fails on VB15) by stdlib.h as header for GCC sanity check makefile+=mprefix+"cat ${ARCHNAME}/configure | sed s/ac_ext=cc/ac_ext=cpp/ | sed s/limits.h/stdlib.h/g> ${ARCHNAME}/configure.tmp\n"; makefile+=mprefix+"mv ${ARCHNAME}/configure.tmp ${ARCHNAME}/configure\n"; STD_string mpcu_postfix=opts_cache.get_vxworks_postfix(); STD_string vxworks_cxx=opts_cache.vxworks_dir+"/bin/cc"+opts_cache.get_vxworks_postfix()+".exe"; STD_string gcc=mgwpath(conf_cache.get_installdir()+"/bin/g++"); makefile+=mprefix+"mkdir -p bin\n"; STD_string vxworks_path_slash=replaceStr(opts_cache.vxworks_path,"\\","/"); // create *wrapper.exe STD_map tools; tools["ld"]=tools["ar"]=tools["ranlib"]=tools["cpp"]=tools["nm"]=""; // add entries, nm is just for debugging purpose for(STD_map::iterator it=tools.begin(); it!=tools.end(); ++it) { STD_string tool=it->first; makefile+=mprefix+"echo \"tool=\\\""+replaceStr(opts_cache.vxworks_dir+"/bin/"+tool+mpcu_postfix+".exe","\\","/")+"\\\";\" > ${ARCHNAME}/replacements/toolwrapper_config.h\n"; if(opts_cache.vxworks_path!="") makefile+=mprefix+"echo \"toolpath=\\\""+vxworks_path_slash+"\\\";\" >> ${ARCHNAME}/replacements/toolwrapper_config.h\n"; makefile+=mprefix+gcc+" ${ARCHNAME}/replacements/toolwrapper.cpp -o bin/"+tool+"wrapper.exe\n"; it->second=mgwpath(opts_cache.odindir)+"/bin/"+tool+"wrapper.exe"; } // create cxxwrapper.exe makefile+=mprefix+"echo \"cxx=\\\""+replaceStr(vxworks_cxx,"\\","/")+"\\\";\" > ${ARCHNAME}/replacements/cxxwrapper_config.h\n"; if(opts_cache.vxworks_path!="") makefile+=mprefix+"echo \"cxxpath=\\\""+vxworks_path_slash+"\\\";\" >> ${ARCHNAME}/replacements/cxxwrapper_config.h\n"; makefile+=mprefix+gcc+" ${ARCHNAME}/replacements/cxxwrapper.cpp -o bin/cxxwrapper.exe\n"; tools["cxx"]=mgwpath(opts_cache.odindir)+"/bin/cxxwrapper.exe"; // create build dirs makefile+=mprefix+"for dir in ${SUBDIRS}; do mkdir -p $$dir/build; done\n\n"; STD_string vxworks_cxxflags=opts_cache.vxworks_flags+" "+opts_cache.vxworks_opts+" "+build_includes; STD_string vxworks_cppflags=opts_cache.vxworks_flags; // only defines // configure/build vxworks STD_string confstr; confstr+=" LD="+tools["ld"]; confstr+=" AR="+tools["ar"]; confstr+=" RANLIB="+tools["ranlib"]; confstr+=" CXX="+tools["cxx"]; confstr+=" CXXFLAGS=\""+vxworks_cxxflags+"\""; confstr+=" CXXCPP=\""+tools["cpp"]+" "+vxworks_cppflags+"\""; confstr+=" CC="+tools["cxx"]; confstr+=" CFLAGS=\""+vxworks_cxxflags+"\""; confstr+=" CPP=\""+tools["cpp"]+" "+vxworks_cppflags+"\""; confstr+=" ../../${ARCHNAME}/configure --host="+mpcu_postfix+"-wrs-vxworks "+global_conf; confstr+=" --enable-custom-heap="+itos(opts_cache.vxworks_heap_size)+" --disable-filehandling"; confstr+=" ${DEBUGOPT} --prefix="+odindir_slash+"/vxworks"; makefile+="configure-vxworks:\n"; makefile+=mprefix+"cd vxworks/build && "+confstr+"\n\n"; makefile+="build-vxworks:\n"; makefile+=mprefix+"cd vxworks/build && "+make_install+"\n\n"; makefile+="build-vxworks-clean: build-vxworks\n"; makefile+=mprefix+"rm -rf vxworks/build\n\n"; // configure/build host(d) makefile+=hosttarget(true, build_includes, global_conf, mprefix, make_install); makefile+=hosttarget(false, build_includes, global_conf, mprefix, make_install); // targets for all makefile+="debug:\n"; makefile+=mprefix+"echo $$PATH\n"; makefile+=mprefix+"echo $$SHELL\n\n"; makefile+="clean:\n"; makefile+=mprefix+"rm -rf ${SUBDIRS} ${ARCHNAME} bin build_complete_tag\n\n"; makefile+="configure: configure-vxworks configure-hostd configure-host\n\n"; makefile+="build: build-vxworks build-hostd build-host\n"; makefile+=mprefix+"touch build_complete_tag\n\n"; makefile+="build-clean: build-vxworks-clean build-hostd-clean build-host-clean\n"; makefile+=mprefix+"touch build_complete_tag\n\n"; makefile+="rebuild: unpack configure build\n\n"; makefile+="rebuild-clean: clean unpack configure build-clean\n\n"; // Set up IDEA sequence makefile+="ideaseq:\n"; makefile+=mprefix+"mkdir -p ${ODIN2IDEADIR_MGWPATH}\n"; makefile+=mprefix+"echo \"\\\""+replaceStr(conf_cache.get_installdir(),"\\","/")+"/bin/odin.exe\\\" -m \\\"${ODIN2IDEADIR_SLASH}\\\"\" > ${ODIN2IDEADIR_MGWPATH}/odin.bat\n"; // copying files makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/odin2idea.cpp ${ODIN2IDEADIR_MGWPATH}\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/tjdx4idea.h ${ODIN2IDEADIR_MGWPATH}\n"; makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/makefile.trs | sed s/ODIN2IDEA_TAG/${ODIN2IDEA_LABEL}/ > ${ODIN2IDEADIR_MGWPATH}/makefile.trs\n"; // find location of IDEA libs JDXfileName idea_libdir; svector n4_delis=match_in_dir(opts_cache.ideadir, "n4_deli_"); if(n4_delis.size()) { idea_libdir=n4_delis[0]+"/x86/delivery/lib"; // VA 25 } else { idea_libdir=opts_cache.ideadir+"/n4_prod/x86/prod/lib"; // default (e.g. VA15) } // Create libs_host(d).txt which contains all libs found in the directory where IDEA libs are stored makefile+=mprefix+"rm -f ${ODIN2IDEADIR_MGWPATH}/libs_host.txt ${ODIN2IDEADIR_MGWPATH}/libs_hostd.txt\n"; makefile+=mprefix+"for file in "+mgwpath(idea_libdir)+"/*d.lib; do \\\n"; makefile+="\t bname=`basename $$file d.lib`; \\\n"; makefile+="\t if test -f "+mgwpath(idea_libdir)+"/$${bname}.lib; then \\\n"; makefile+="\t echo \"LDLIBS += \"$${bname}.lib >> ${ODIN2IDEADIR_MGWPATH}/libs_host.txt; \\\n"; makefile+="\t echo \"LDDLLS += \"$${bname}.dll >> ${ODIN2IDEADIR_MGWPATH}/libs_host.txt; \\\n"; makefile+="\t echo \"LDLIBS += \"$${bname}d.lib >> ${ODIN2IDEADIR_MGWPATH}/libs_hostd.txt; \\\n"; makefile+="\t echo \"LDDLLS += \"$${bname}d.dll >> ${ODIN2IDEADIR_MGWPATH}/libs_hostd.txt; \\\n"; makefile+="\t fi; \\\n"; makefile+="\tdone\n"; // find location of IDEA includes STD_list possible_includepaths; // pre VA25 possible_includepaths.push_back("n4/comp"); possible_includepaths.push_back("n4/comp/STLport"); possible_includepaths.push_back("n4_extsw/x86/extsw/MedCom/versant/5_2_2/NT/h"); possible_includepaths.push_back("n4/comp/Measurement/Sequence"); possible_includepaths.push_back("n4/comp/Measurement/Sequence/libSBB"); possible_includepaths.push_back("n4/comp/Measurement/PerAns/PerProxies"); possible_includepaths.push_back("n4/comp/Measurement/MeasPatient"); possible_includepaths.push_back("n4/comp/Application/seq"); possible_includepaths.push_back("n4/comp/ExamUI/ExamDb/Protocol/UILink/StdProtRes"); possible_includepaths.push_back("n4/comp/Common/STL"); // VA25 and later possible_includepaths.push_back("n4/pkg"); possible_includepaths.push_back("n4/pkg/STLport"); possible_includepaths.push_back("n4_extsw/x86/extsw/MedCom/versant/vds605/h"); possible_includepaths.push_back("n4/pkg/MrServers/MrMeasSrv/SeqIF"); possible_includepaths.push_back("n4/pkg/MrServers/MrMeasSrv/MeasPatient"); possible_includepaths.push_back("n4/pkg/MrServers/MrImaging/libSBB"); possible_includepaths.push_back("n4/pkg/MrServers/MrPerAns/PerProxies"); possible_includepaths.push_back("n4/pkg/MrServers/MrImaging/seq"); possible_includepaths.push_back("n4/pkg/MrServers/MrProtSrv/MrProtocol/UILink/StdProtRes"); possible_includepaths.push_back("n4/pkg/MrCommon/MrCFramework/STL"); JDXfileName testdir; testdir.set_dir(true); STD_string idea_includes; for(STD_list::const_iterator it=possible_includepaths.begin(); it!=possible_includepaths.end(); ++it) { testdir=opts_cache.ideadir+SEPARATOR_STR+(*it); if(testdir.exists()) { idea_includes+=" "+opts_cache.get_ideadir_slash()+"/"+(*it); } } makefile+=mprefix+"rm -f ${ODIN2IDEADIR_MGWPATH}/idea_includes.txt\n"; makefile+=mprefix+"for include in "+idea_includes+"; do \\\n"; makefile+="\t echo \"CPPFLAGS_LOCAL += -I$${include}\" >> ${ODIN2IDEADIR_MGWPATH}/idea_includes.txt; \\\n"; makefile+="\tdone\n"; STD_string idea_defines; // checking iPAT (parallel imaging) capability JDXfileName testfile(opts_cache.ideadir+"/n4/pkg/MrServers/MrImaging/seq/common/iPAT/iPAT.h"); if(testfile.exists()) idea_defines="-DHAVE_iPAT"; // checking whether standard STL header 'vector' is available (which is the case on VB13) testfile=opts_cache.ideadir+"/n4_opensource/STLport/stlport/vector"; if(testfile.exists()) idea_defines+=" -DHAVE_STL_VECTOR"; // Checking for MultiByteToWideChar in MrProt.h STD_list possible_mrprot; possible_mrprot.push_back(opts_cache.ideadir+"/n4/comp/Measurement/Sequence/Prot/MrProt.h"); possible_mrprot.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrProtSrv/MrProt/MrProt.h"); int retval=find_in_alternatives("MultiByteToWideChar",possible_mrprot); if(retval<0) return; if(retval>0) idea_defines+=" -DHAVE_MULTIBYTETOWIDECHAR"; // Checking whether we have study index STD_list possible_measpatient; possible_measpatient.push_back(opts_cache.ideadir+"/n4/comp/Measurement/MeasPatient/MeasPatient.h"); possible_measpatient.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrMeasSrv/MeasPatient/MeasPatient.h"); retval=find_in_alternatives("uiStudyIndex",possible_measpatient); if(retval<0) return; if(retval>0) idea_defines+=" -DHAVE_STUDYINDEX"; // Checking whether we have INC_16 STD_list possible_seqdefines; possible_seqdefines.push_back(opts_cache.ideadir+"/n4/comp/Measurement/Sequence/SeqDefines.h"); possible_seqdefines.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrProtSrv/MrProt/SeqDefines.h"); retval=find_in_alternatives("INC_16",possible_seqdefines); if(retval<0) return; if(retval>0) idea_defines+=" -DHAVE_INC_16"; // Assume new Linux-based Ice reco is there if IceConfigurators are present STD_string icecmd="MakeIcePrg"; testfile=opts_cache.ideadir+"/n4/pkg/MrServers/MrVista/Config/IceConfigurators"; if(testfile.exists()) { idea_defines+=" -DHAVE_ICE_CONFIGURATOR"; icecmd="mi"; } // checking whether libGTR is there testfile=opts_cache.ideadir+"/n4/x86/delivery/lib/libGTR.lib"; bool has_libgtr=testfile.exists(); // Creating batch script for Makefiles makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/MakSeq.bat | \\\n"; makefile+="\tsed s/_VXWORKS_EXT_TAG_/"+opts_cache.get_vxworks_ext()+"/g \\\n"; makefile+="\t> ${ODIN2IDEADIR_MGWPATH}/MakSeq.bat\n"; // creating VA*/VB12 Makefile for vxworks makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/"+opts_cache.get_vxworks_Makefile()+" | \\\n"; makefile+="\tawk -v repl=${ODIN2IDEA_LABEL} '{gsub(\"_ODIN2IDEA_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\"`cat ${ODIN2IDEADIR_MGWPATH}/idea_includes.txt`\" '{gsub(\"_IDEA_INCLUDES_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\""+odindir_slash+"/vxworks\" '{gsub(\"_ODINDIR_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\""+idea_defines+"\" '{gsub(\"_CPPFLAGS_TAG_\",repl); print; }' \\\n"; makefile+="\t> ${ODIN2IDEADIR_MGWPATH}/"+opts_cache.get_vxworks_Makefile()+"\n"; // creating VA*/VB12 Makefiles for host(d) STD_string idea_libdir_backslash=replaceStr(idea_libdir,"\\","\\\\\\\\"); // double protect backslash from shell makefile+=mprefix+"for HOSTLETTER in \"d\" \"\" ; do \\\n"; makefile+="\t cat ${ARCHNAME}/platforms/IDEA_n4/MakHost.txt | \\\n"; makefile+="\t awk -v repl=\"$$HOSTLETTER\" '{gsub(\"_DEBUGLETTER_TAG_\",repl); print; }' | \\\n"; makefile+="\t awk -v repl=${ODIN2IDEA_LABEL} '{gsub(\"_ODIN2IDEA_TAG_\",repl); print; }' | \\\n"; makefile+="\t awk -v repl=\""+idea_defines+"\" '{gsub(\"_CPPFLAGS_TAG_\",repl); print; }' | \\\n"; makefile+="\t awk -v repl=\""+idea_libdir_backslash+"\" '{gsub(\"_IDEA_LIBDIR_TAG_\",repl); print; }' | \\\n"; if(has_libgtr) makefile+="\t awk '{gsub(\"#REM_IF_HAS_LIBGTR \",\"\"); print; }' | \\\n"; makefile+="\t awk -v repl=\"`cat ${ODIN2IDEADIR_MGWPATH}/libs_host$${HOSTLETTER}.txt`\" '{gsub(\"_IDEA_HOST_LIBS_TAG_\",repl); print; }' | \\\n"; makefile+="\t awk -v repl=\"`cat ${ODIN2IDEADIR_MGWPATH}/idea_includes.txt`\" '{gsub(\"_IDEA_INCLUDES_TAG_\",repl); print; }' | \\\n"; makefile+="\t awk -v repl=\""+odindir_slash+"/host$${HOSTLETTER}\" '{gsub(\"_ODINDIR_TAG_\",repl); print; }' \\\n"; makefile+="\t > ${ODIN2IDEADIR_MGWPATH}/MakHost$${HOSTLETTER}.txt; \\\n"; makefile+="\tdone\n"; // creating Makefile for VB13 makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/odin.mk | \\\n"; makefile+="\tawk -v repl=${ODIN2IDEA_LABEL} '{gsub(\"_ODIN2IDEA_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\"`cat ${ODIN2IDEADIR_MGWPATH}/idea_includes.txt`\" '{gsub(\"_IDEA_INCLUDES_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\""+idea_defines+"\" '{gsub(\"_CPPFLAGS_TAG_\",repl); print; }' | \\\n"; makefile+="\tawk -v repl=\""+odindir_slash+"\" '{gsub(\"_ODINDIR_TAG_\",repl); print; }' \\\n"; makefile+="\t> ${ODIN2IDEADIR_MGWPATH}/${ODIN2IDEA_LABEL}.mk\n\n"; // Set up Ice STD_string iceodindir="\""+mgwpath(opts_cache.icedir)+"/IceOdin\""; makefile+="ice:\n"; makefile+=mprefix+"mkdir -p ${ICEODINDIR}\n"; // makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/Ice/IceOdin.evp | sed s/ODINRECO_FLAG/false/ > ${ICEODINDIR}/IceOdin.evp\n"; // makefile+=mprefix+"cat ${ARCHNAME}/platforms/IDEA_n4/Ice/IceOdin.evp | sed s/ODINRECO_FLAG/true/ > ${ICEODINDIR}/IceOdinOnline.evp\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/Ice/IceOdin.evp ${ICEODINDIR}\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/Ice/*.h ${ICEODINDIR}\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/Ice/*.cpp ${ICEODINDIR}\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/Ice/MakeRelease.X86 ${ICEODINDIR}\n\n"; makefile+=mprefix+"cp ${ARCHNAME}/platforms/IDEA_n4/Ice/Makefile.imk ${ICEODINDIR}\n\n"; STD_string makefilename=opts_cache.odindir+SEPARATOR_STR+"Makefile"; write(makefile, makefilename); STD_string msg=justificate("A Makefile to build and install ODIN for IDEA has been stored under "+makefilename+". Execute this Makefile now?"); if(!message_question(msg.c_str(), "Execute Makefile?", GuiDialog::get_widget(),true)) return; // set environment variables which would be set by cygwin.bat otherwise #ifdef USING_WIN32 /* STD_string oldpath=secure_getenv("PATH"); if(oldpath.find(cygnus_bin) != 0) { // add only if cygnus_bin is not already 1st entry STD_string path="PATH="+cygnus_bin+";"+oldpath; ODINLOG(odinlog,normalDebug) << "oldpath/path=" << oldpath << "/" << path << STD_endl; _putenv(path.c_str()); } */ _putenv("MAKE_MODE=UNIX"); #endif STD_string target="rebuild"; if(opts_cache.make_clean) target+="-clean"; if(!execute_make(make,target)) return; msg=justificate("Congratulations! You have sucessfully compiled ODIN for IDEA. Includes and libraries have been installed under "+opts_cache.odindir); message_question(msg.c_str(), "Build complete", GuiDialog::get_widget()); if(!execute_make(make,"ideaseq")) return; msg=justificate("An IDEA sequence '"+opts_cache.odin2idea_label+"' which holds the ODIN methods has been " "installed under "+opts_cache.seqdir+". " "You can now open the SDE shell and change to the newly " "created sequence by using the 'cs' command. " "Then type 'odin' to start the ODIN graphical user interface. " "After creating/editing your ODIN methods, you can create the " "DLLs via the 'Siemens' menu."); message_question(msg.c_str(), "Sequence setup complete", GuiDialog::get_widget()); if(!execute_make(make,"ice")) return; msg=justificate("An ICE reconstruction 'IceOdin' which writes the raw data to disk has been " "installed under "+opts_cache.icedir+". " "You can now use the ICE shell to compile the ICE " "reconstruction using the command '"+icecmd+"'."); message_question(msg.c_str(), "ICE setup complete", GuiDialog::get_widget()); } bool IdeaDialog::execute_make(const STD_string& make, const STD_string& target) { Log odinlog("IdeaDialog","execute_make"); svector cmd_chain; cmd_chain.resize(1); cmd_chain[0]="\""+make+"\" -C "+opts_cache.odindir+" "+target; ProcessDialog makedlg(GuiDialog::get_widget()); int waitstate=makedlg.execute_cmds(cmd_chain,false); // log to console bool status=(!waitstate); ODINLOG(odinlog,normalDebug) << "status / waitstate = " << status << " / " << waitstate << STD_endl; if(!status && waitstate!=-2) { error_msg("Make "+target+" failed"); return false; } if(waitstate==-2) { // code for cancel return false; } return true; } void IdeaDialog::update() { Log odinlog("IdeaDialog","update"); // check for space characters if(opts_cache.odindir.find(" ") != STD_string::npos) { error_msg("Please do not use space characters in installation path, otherwise compilation fails"); } // set compilers and path of tools opts_cache.win_cxx=opts_cache.msvcdir+"/VC98/Bin/cl.exe"; STD_list vxworks_dir_alternatives; vxworks_dir_alternatives.push_back(opts_cache.ideadir+"/n4_fsp/tornado/i86/host/x86-win32"); vxworks_dir_alternatives.push_back(opts_cache.ideadir+"/n4_fsp/tornado/ppc/host/x86-win32"); select_alternative(opts_cache.vxworks_dir, vxworks_dir_alternatives); STD_list vxworks_path_alternatives; vxworks_path_alternatives.push_back(opts_cache.vxworks_dir+"/lib/gcc-lib/powerpc-wrs-vxworks/cygnus-2.7.2-960126"); vxworks_path_alternatives.push_back(opts_cache.vxworks_dir+"/bin"); // for VB12 select_alternative(opts_cache.vxworks_path, vxworks_path_alternatives); STD_string global_includes; STD_string global_defines; // set includes STD_list possible_includepaths; possible_includepaths.push_back("n4/x86/delivery/include"); // pre VA25 possible_includepaths.push_back("n4/comp"); possible_includepaths.push_back("n4/comp/Measurement/Sequence/libRT"); possible_includepaths.push_back("n4/comp/Measurement/Sequence/libSBB"); // for fSBBECGFillTimeRun possible_includepaths.push_back("n4/comp/Measurement/Sequence/SeqBuffer"); possible_includepaths.push_back("n4/comp/Measurement/Sequence/Prot"); // for MrProt.h // VA25/VB* possible_includepaths.push_back("n4/pkg"); possible_includepaths.push_back("n4/pkg/MrServers/MrMeasSrv/SeqIF/libRT"); possible_includepaths.push_back("n4/pkg/MrServers/MrImaging/libSBB"); // for fSBBECGFillTimeRun possible_includepaths.push_back("n4/pkg/MrServers/MrMeasSrv/SeqIF/SeqBuffer"); possible_includepaths.push_back("n4/pkg/MrServers/MrProtSrv/MrProt"); // for MrProt.h possible_includepaths.push_back("n4/x86/delivery/include/MrServers/MrMeasSrv/SeqIF/libRT"); // for libRTmsg.h select_idea_include_dirs(global_includes, possible_includepaths, opts_cache); // extra includes for VxWorks JDXfileName vxworks_target_includes; vxworks_target_includes.set_dir(true); STD_list vxworks_target_includes_alternatives; vxworks_target_includes_alternatives.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrMPCUSystem/Tornado_i86/target/h"); vxworks_target_includes_alternatives.push_back(opts_cache.ideadir+"/n4_fsp/tornado/ppc/target/h"); select_alternative(vxworks_target_includes, vxworks_target_includes_alternatives); // checking for presence of sGRAD_PULSE_ARB class in sGRAD_PULSE.h STD_list sGRAD_PULSE_h_alternatives; sGRAD_PULSE_h_alternatives.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrMeasSrv/SeqIF/libRT/sGRAD_PULSE.h"); sGRAD_PULSE_h_alternatives.push_back(opts_cache.ideadir+"/n4/comp/Measurement/Sequence/libRT/sGRAD_PULSE.h"); int retval=find_in_alternatives("sGRAD_PULSE_ARB",sGRAD_PULSE_h_alternatives); if(retval<0) return; if(retval>0) global_defines+="-DHAVE_sGRAD_PULSE_ARB"; // checking for presence of FFTScale in MrCoilSelect.h STD_list MrCoilSelect_h_alternatives; MrCoilSelect_h_alternatives.push_back(opts_cache.ideadir+"/n4/comp/Measurement/Sequence/CoilSelect/MrCoilSelect.h"); MrCoilSelect_h_alternatives.push_back(opts_cache.ideadir+"/n4/pkg/MrServers/MrProtSrv/MrProt/CoilSelect/MrCoilSelect.h"); retval=find_in_alternatives("FFTScale",MrCoilSelect_h_alternatives); if(retval<0) return; if(retval>0) global_defines+=" -DHAVE_MRCOILSELECT_FFTSCALE"; opts_cache.vxworks_flags=global_includes+" -I"+replaceStr(vxworks_target_includes,"\\","/")+" "+global_defines+" -DVXWORKS -DCPU="+opts_cache.vxworks_cpu.JDXenum::operator STD_string(); opts_cache.vxworks_opts="-ansi"; if(tolowerstr(opts_cache.vxworks_cpu).find("pentium")!=STD_string::npos) { opts_cache.vxworks_opts+=" -O1"; // -O2 causes the compiler to enter inifinite loop ... opts_cache.vxworks_opts+=" -mcpu=pentium -march=pentium -fvolatile -nostdlib -fno-builtin -fno-defer-pop -malign-double"; } else { opts_cache.vxworks_opts+=" -O2"; } STD_list possible_hostall_includepaths; possible_hostall_includepaths.push_back("n4/comp/STLport"); // VA* path possible_hostall_includepaths.push_back("n4_opensource/STLport/stlport"); // VB* path, if this path is absent, the MSVC iostream would be used which fails possible_hostall_includepaths.push_back("n4_extsw/x86/extsw/MedCom/include"); // VA* path possible_hostall_includepaths.push_back("n4/x86/extsw/MedCom/include"); // VB* path STD_string hostall_idea_includes; select_idea_include_dirs(hostall_idea_includes, possible_hostall_includepaths, opts_cache); STD_string hostall_defines=global_defines+" -DWIN32 -D_AFXDLL -DCSA_HAS_DLL -D_MBCS -DAFX_NOVTABLE= -D_RWTOOLSDLL -D_UNICODE -DUNICODE -DO_DLL_PCLASS_ONLY -D_CONSOLE -D_WINDLL -DACE_HAS_DLL"; STD_string hostall_includes=global_includes+" "+hostall_idea_includes; STD_string hostall_opts="-nologo -Z7 -O2 -GR -GX -G5 -GF"; opts_cache.hostd_flags=hostall_defines+" "+hostall_includes+" "+hostall_opts+" -MDd"; opts_cache.host_flags= hostall_defines+" "+hostall_includes+" "+hostall_opts+" -MD"; optswidget->updateWidget(); emit changed(); } IdeaDialog::~IdeaDialog() { delete pb_compile; delete optswidget; delete grid; } //////////////////////////////////////////////////////////////////////////////////////// IdeaMethodDialog::IdeaMethodDialog(const STD_string& methdir, sarray& selectedMethods, const STD_string& install_prefix, const IdeaOpts& ideaopts, QWidget *parent) : GuiDialog(parent,"Select Methods",false), selMeth(selectedMethods), methrootdir(methdir), install_dir(install_prefix), ideaopts_cache(ideaopts) { Log odinlog("IdeaMethodDialog","IdeaMethodDialog"); svector subdirs(browse_dir(methdir,true,true)); ODINLOG(odinlog,normalDebug) << "subdirs=" << subdirs.printbody() << STD_endl; grid = new GuiGridLayout( GuiDialog::get_widget(), 3, 1 ); svector collabel; collabel.resize(1); collabel[0]="Method"; method_list=new GuiListView (GuiDialog::get_widget(), collabel, 100, 300); for(unsigned int i=0; iadd_widget( method_list->get_widget(), 0, 0 ); pb_make = new GuiButton( GuiDialog::get_widget(), this, SLOT(make()), "Make" ); grid->add_widget( pb_make->get_widget(), 1, 0, GuiGridLayout::Center ); pb_cancel = new GuiButton( GuiDialog::get_widget(), this, SLOT(emitDone()), "Cancel" ); grid->add_widget( pb_cancel->get_widget(), 2, 0, GuiGridLayout::Center ); GuiDialog::show(); } IdeaMethodDialog::~IdeaMethodDialog() { for(STD_list::iterator dirit=method_checks.begin();dirit!=method_checks.end();++dirit) { delete (*dirit); } delete method_list; delete pb_make; delete pb_cancel; delete grid; } void IdeaMethodDialog::make() { Log odinlog("IdeaMethodDialog","make"); STD_list methlist; for(STD_list::const_iterator dirit=method_checks.begin();dirit!=method_checks.end();++dirit) { if((*dirit)->is_checked()) methlist.push_back((*dirit)->get_text()); } if(!methlist.size()) { message_question("Please select at least one method", "No Method(s) Selected", GuiDialog::get_widget(),false,true); return; } selMeth.resize(methlist.size()); unsigned int index=0; for(STD_list::const_iterator it=methlist.begin(); it!=methlist.end(); ++it) { selMeth[index]=(*it); ODINLOG(odinlog,normalDebug) << "selMeth[" << index << "]=" << (*it) << STD_endl; SeqMakefile mf(selMeth[index],install_dir); STD_string methdir=methrootdir+SEPARATOR_STR+selMeth[index]+SEPARATOR_STR; svector cmd_chain; cmd_chain=mf.get_odin4idea_method_compile_chain(methdir, ideaopts_cache.odindir, ideaopts_cache.vxworks_path, ideaopts_cache.get_vxworks_cxx(), ideaopts_cache.vxworks_flags+" "+ideaopts_cache.vxworks_opts, ideaopts_cache.win_cxx, ideaopts_cache.hostd_flags, ideaopts_cache.host_flags); ProcessDialog makedlg(GuiDialog::get_widget()); int waitstate=makedlg.execute_cmds(cmd_chain); bool status=(!waitstate); ODINLOG(odinlog,normalDebug) << "status / waitstate = " << status << " / " << waitstate << STD_endl; if(!status && waitstate!=-2) { message_question("An error occured during method compilation", "Make Failed", GuiDialog::get_widget(),false,true); this->emitDone(); return; } index++; } unsigned int imeth; STD_string methods_decls,methods_inits,methods_objs; for(imeth=0; imethemitDone(); return; } void IdeaMethodDialog::emitDone() { GuiDialog::done(); } odin-1.8.5/odin/odincomp.cpp0000644000175000017500000000020611322062346012641 00000000000000#include "odincomp.h" #include const char* OdinComp::get_compName() {return "Odin";} LOGGROUNDWORK(OdinComp) odin-1.8.5/odin/odinconf.cpp0000644000175000017500000003062411455553540012647 00000000000000#include "odinconf.h" #include "odincomp.h" #include #include // for message_question #include #ifdef USING_WIN32 #include #include #include #endif OdinConf::OdinConf(const STD_string& label, bool ignore_environment) : JcampDxBlock(label), sourcecode("","SourceCode",true,notBroken,hidden), editor(DEFAULT_EDITOR,"SourceCodeEditor",true,notBroken), browser(DEFAULT_BROWSER,"WebBrowser",true,notBroken), methroot(get_homedir()+SEPARATOR_STR+DEFAULT_METH_ROOT+SEPARATOR_STR,"MethodsRootDir",true,notBroken), smpfile(get_samplesdir(),"SampleFile",true,notBroken), protfile(get_homedir(),"ProtocolFile",true,notBroken), compiler(CXX,"Compiler",true,notBroken), linker(CXX,"Linker",true,notBroken), compiler_flags(CXXFLAGS,"CompilerOptions",true,notBroken), extra_includes("","ExtraIncludes",true,notBroken), extra_libs("","ExtraLibraries",true,notBroken), selectedMethods(sarray(0),"SelectedMethods",true,notBroken), attachDebugger(false,"AttachDebugger") { Log odinlog("OdinConf","OdinConf"); ignore_env=ignore_environment; sourcecode.set_defaultdir(get_homedir()); sourcecode.set_suffix("cpp"); methroot.set_dir(true); #ifdef USING_WIN32 // compiler=WIN_CXX; // linker=WIN_LD; #else editor.set_defaultdir("/usr/bin"); browser.set_defaultdir("/usr/bin"); #endif protfile.set_parmode(hidden); JcampDxBlock::append(sourcecode); JcampDxBlock::append(methroot); JcampDxBlock::append(smpfile); JcampDxBlock::append(protfile); if(!ignore_env) { JcampDxBlock::append(compiler_flags); JcampDxBlock::append(extra_includes); JcampDxBlock::append(extra_libs); } #ifdef HAVE_GDB_XTERM JcampDxBlock::append(attachDebugger); #endif JcampDxBlock::append(editor); JcampDxBlock::append(browser); JcampDxBlock::append(selectedMethods); } bool OdinConf::init(QWidget* parent) { Log odinlog("OdinConf","init"); #ifdef USING_WIN32 #ifdef USING_GCC // Assume MinGW STD_string instprefix(get_installdir()); compiler=instprefix+SEPARATOR_STR+"bin"+SEPARATOR_STR+"g++"; linker=STD_string(compiler); // the same for GCC // Try to find and use notepad2 STD_string notepad2_fname=instprefix+SEPARATOR_STR+"bin"+SEPARATOR_STR+"notepad2.exe"; if(filesize(notepad2_fname.c_str())>0) editor=notepad2_fname; #else // Assume Visual C++ 6 STD_string keyname("SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup\\Microsoft Visual C++"); STD_string valname("ProductDir"); STD_string vcreg(get_registryvalue(keyname,valname)); // retrieve VC++ installation path from registry ODINLOG(odinlog,normalDebug) << "vcreg=" << vcreg << STD_endl; STD_string msg; if(vcreg=="") { msg=justificate("Visual C++ 6.0 is required for compiling ODIN sequences. I cannot find the path of the Visual C++ installation under the registry key-value pair "+keyname+"-"+valname+". Please install Visual C++ 6.0 and re-install ODIN."); message_question(msg.c_str(), "Cannot find Visual C++", parent, false, true); return false; } else { STD_string compiler_fname=vcreg+SEPARATOR_STR+"bin"+SEPARATOR_STR+"cl.exe"; if(filesize(compiler_fname.c_str())<=0) { msg=justificate("Visual C++ 6.0 is installed but I cannot find the compiler cl.exe under the path "+compiler_fname+". Please make sure that it is installed together with Visual C++ 6.0 and re-install ODIN."); message_question(msg.c_str(), "Cannot find Visual C++ Compiler", parent, false, true); return false; } else { compiler=compiler_fname; // and set it as the initial value, if found ODINLOG(odinlog,normalDebug) << "compiler=" << compiler << STD_endl; } STD_string linker_fname=vcreg+SEPARATOR_STR+"bin"+SEPARATOR_STR+"link.exe"; if(filesize(linker_fname.c_str())<=0) { msg=justificate("Visual C++ 6.0 is installed but I cannot find the linker link.exe under the path "+linker_fname+". Please make sure that it is installed together with Visual C++ 6.0 and re-install ODIN."); message_question(msg.c_str(), "Cannot find Visual C++ Linker", parent, false, true); return false; } else { linker=linker_fname; // and set it as the initial value, if found ODINLOG(odinlog,normalDebug) << "linker=" << linker << STD_endl; } extra_includes="-I\""+vcreg+SEPARATOR_STR+"Include\""; // and set it as the initial value, if found extra_libs="/LIBPATH:\""+vcreg+SEPARATOR_STR+"lib\" "; } vcreg=get_registryvalue("SOFTWARE\\Microsoft\\VisualStudio\\6.0\\Setup","VsCommonDir"); if(vcreg!="") { editor=vcreg+SEPARATOR_STR+"MSDev98"+SEPARATOR_STR+"Bin"+SEPARATOR_STR+"msdev.exe"; } #endif #endif return true; } svector OdinConf::get_method_compile_chain() const { Log odinlog("OdinConf","get_method_compile_chain"); STD_string methlabel(sourcecode.get_basename_nosuffix()); ODINLOG(odinlog,normalDebug) << "methlabel=" << methlabel << STD_endl; if(methlabel=="") return svector(); SeqMakefile mf(methlabel,get_installdir(),compiler,compiler_flags,linker,extra_includes,extra_libs); return mf.get_method_compile_chain(false,true); // Only shared object } STD_string OdinConf::get_registryvalue(const STD_string& keyname, const STD_string& valuename) { Log odinlog("OdinConf","get_registryvalue"); STD_string result; #ifdef USING_WIN32 HKEY reghandle=0; LONG openresult=RegOpenKeyEx(HKEY_LOCAL_MACHINE,keyname.c_str(),0,KEY_READ,®handle); ODINLOG(odinlog,normalDebug) << "reghandle/openresult=" << reghandle << "/" << openresult << STD_endl; if(reghandle) { if(openresult==ERROR_SUCCESS) { unsigned char buff[ODIN_MAXCHAR]; DWORD buffsize=ODIN_MAXCHAR-1; buff[0]='\0'; LONG queryresult=RegQueryValueEx(reghandle,valuename.c_str(),NULL,NULL,buff,&buffsize); ODINLOG(odinlog,normalDebug) << "buffsize/queryresult=" << buffsize << "/" << queryresult << STD_endl; if(queryresult==ERROR_SUCCESS && buffsize<(ODIN_MAXCHAR-1)) { buff[buffsize]='\0'; result=(const char *)buff; } else ODINLOG(odinlog,normalDebug) << "unable to get registry value " << valuename << STD_endl; } else ODINLOG(odinlog,normalDebug) << "unable to open registry key " << keyname << STD_endl; LONG closeresult=RegCloseKey(reghandle); ODINLOG(odinlog,normalDebug) << "closeresult=" << closeresult << STD_endl; } else ODINLOG(odinlog,normalDebug) << "unable to get handle for registry key " << keyname << ", openresult=" << openresult << STD_endl; #endif ODINLOG(odinlog,normalDebug) << "result(" << keyname << "\\" << valuename << ")=" << result << STD_endl; return result; } STD_string OdinConf::get_installdir() { Log odinlog("OdinConf","get_installdir"); JDXfileName result; // create normalized file name STD_string reg; if(!ignore_env) reg=get_registryvalue("SOFTWARE\\Odin","Install_Dir"); if(reg!="") result=reg; else result=INSTALL_PREFIX; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } STD_string OdinConf::get_binprefix() { Log odinlog("OdinConf","get_binprefix"); STD_string result; // default: empty string -> use PATH #ifdef USING_WIN32 result=get_installdir()+SEPARATOR_STR+"bin"+SEPARATOR_STR; // Append separator (won't work with JDXfileName) so that prefix can either be directory or empty #endif ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } STD_string OdinConf::get_homedir() { Log odinlog("OdinConf","get_homedir"); JDXfileName result(secure_getenv("HOME")); #ifdef USING_WIN32 result=secure_getenv("USERPROFILE"); // the windows 'home' directory #endif if(result=="") ODINLOG(odinlog,warningLog) << "Cannot determine homedir" << STD_endl; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } STD_string OdinConf::get_datadir() { Log odinlog("OdinConf","get_datadir"); JDXfileName result=get_installdir()+SEPARATOR_STR+"share"+SEPARATOR_STR+"odin"; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } STD_string OdinConf::get_seqexamplesdir() { Log odinlog("OdinConf","get_seqexamplesdir"); JDXfileName result=get_datadir()+SEPARATOR_STR+"sequences"; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } STD_string OdinConf::get_samplesdir() { Log odinlog("OdinConf","get_samplesdir"); JDXfileName result=get_datadir()+SEPARATOR_STR+"samples"; return result; } STD_string OdinConf::get_coilsdir() { Log odinlog("OdinConf","get_coilsdir"); JDXfileName result=get_datadir()+SEPARATOR_STR+"coils"; return result; } STD_string OdinConf::get_confdir() { Log odinlog("OdinConf","get_confdir"); STD_string confdir(get_homedir()+SEPARATOR_STR+".odin"); ODINLOG(odinlog,normalDebug) << "confdir=" << confdir << STD_endl; createdir(confdir.c_str()); return confdir; } STD_string OdinConf::get_tmpdir() { Log odinlog("OdinConf","get_tmpdir"); JDXfileName tmpdir(get_confdir()+SEPARATOR_STR+"tmp"); createdir(tmpdir.c_str()); return tmpdir; } STD_string OdinConf::get_manual_location() { Log odinlog("OdinConf","get_manual_location"); STD_string wwwloc("http://od1n.sourceforge.net/manual/html/"); STD_string instloc(get_installdir()+SEPARATOR_STR+"share"+SEPARATOR_STR+"doc"+SEPARATOR_STR+"odin"+SEPARATOR_STR+"manual"+SEPARATOR_STR+"html"+SEPARATOR_STR); STD_string result=wwwloc; if(filesize((instloc+"index.html").c_str())>0) result="file://"+instloc; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } #ifdef USING_WIN32 bool open_file_in_win32(const STD_string& location, const STD_string& prog) { Log odinlog("OdinConf","open_file_in_win32"); const char* args[4]; STD_string exe; if(prog=="") { args[0]="rundll32.exe"; args[1]="url.dll,FileProtocolHandler"; args[2]=location.c_str(); args[3]=0; } else { args[0]=prog.c_str(); args[1]=location.c_str(); args[2]=0; args[3]=0; } int spawnpid=_spawnvp( _P_NOWAIT, args[0], args); if (spawnpid == -1) { if(errno==E2BIG) ODINLOG(odinlog,errorLog) << "exe to big" << STD_endl; if(errno==EINVAL) ODINLOG(odinlog,errorLog) << "mode invalid" << STD_endl; if(errno==ENOENT) ODINLOG(odinlog,errorLog) << "file not found" << STD_endl; if(errno==ENOEXEC) ODINLOG(odinlog,errorLog) << "exe not found" << STD_endl; if(errno==ENOMEM) ODINLOG(odinlog,errorLog) << "no mem" << STD_endl; } return true; } #endif #ifdef MACOS bool open_file_in_macos(const STD_string& location, STD_list& subprocs) { Log odinlog("OdinConf","open_file_in_macos"); return OdinConf::start_proc("open", location, subprocs); } #endif bool OdinConf::display_html(const STD_string& location, STD_list& subprocs) { Log odinlog("OdinConf","display_html"); bool result=true; #ifdef USING_WIN32 result=open_file_in_win32(location,""); #else #ifdef MACOS result=open_file_in_macos(location, subprocs); #else result=OdinConf::start_proc(browser, location, subprocs); #endif #endif if(!result) { STD_string msg=justificate("Cannot open URL "+location+" using "+browser+". Please change the browser under Preferences->Settings."); message_question(msg.c_str(), "Browser not found", 0, false, true); } return result; } bool OdinConf::open_ascfile(const STD_string& filename, STD_list& subprocs) { Log odinlog("OdinConf","open_ascfile"); bool result=true; #ifdef USING_WIN32 result=open_file_in_win32(filename,editor); #else #ifdef MACOS result=open_file_in_macos(filename, subprocs); #else result=OdinConf::start_proc(editor, filename, subprocs); #endif #endif if(!result) { STD_string msg=justificate("Cannot open ASCII file "+filename+" using "+editor+". Please change the editor under Preferences->Settings."); message_question(msg.c_str(), "Editor not found", 0, false, true); } return result; } #ifndef USING_WIN32 bool OdinConf::start_proc(const STD_string& program, const STD_string& filename, STD_list& subprocs) { Log odinlog("OdinConf","start_proc"); bool result=true; STD_string cmd(program+" \""+STD_string(filename)+"\""); Process proc; result=proc.start(cmd); sleep_ms(1000); // wait for error int retval=0; bool finished=proc.finished(retval); if(finished && retval) result=false; if(!finished) subprocs.push_back(proc); return result; } #endif bool OdinConf::ignore_env; odin-1.8.5/odin/main.cpp0000644000175000017500000000161211322062346011757 00000000000000#include "odin.h" #include "odinview.h" int main(int argc, char *argv[]) { // do this here so we do not have to query X server in order to get usage for manual if(hasHelpOption(argc, argv)) {OdinView::usage();exit(0);} bool has_debug_cmdline=isCommandlineOption(argc,argv,"-d",false); // Do this here before -d option is removed from argv GuiApplication a(argc, argv); // debug handler will be initialized here Log odinlog("","main"); ODINLOG(odinlog,normalDebug) << "GuiApplication::argc/argv()=" << GuiApplication::argc() << "/" << GuiApplication::argv() << STD_endl; Odin* odin =new Odin(); odin->initOdin(&a,has_debug_cmdline); int result=a.start(odin->get_widget()); ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; Static::destroy_all(); // free resources ODINLOG(odinlog,normalDebug) << "destroy_all done" << STD_endl; return result; } odin-1.8.5/odin/odinplot_vtk.cpp0000644000175000017500000000705511322062346013556 00000000000000#include "odinplot_vtk.h" #include "odincomp.h" #ifdef VTKSUPPORT #include #include #include #include #include #include #include #include #include #include #include #include #include #endif VtkMagnPlotter::VtkMagnPlotter() { renderer=0; renWin=0; iren=0; magnArrow=0; magnMapper=0; magnActor=0; magnGradActor=0; axes=0; axesTubes=0; axesMapper=0; axesActor=0; } void VtkMagnPlotter::start() { Log odinlog("VtkMagnPlotter","start"); #ifdef VTKSUPPORT magnArrow=vtkArrowSource::New(); magnMapper = vtkPolyDataMapper::New(); magnMapper->SetInput(magnArrow->GetOutput()); magnActor = vtkActor::New(); magnActor->SetMapper(magnMapper); magnActor->GetProperty()->SetColor(1,1,1); magnGradActor = vtkActor::New(); magnGradActor->SetMapper(magnMapper); magnGradActor->GetProperty()->SetColor(1,1,50); // Axes axes = vtkAxes::New(); // axes->SetOrigin(bounds[0], bounds[2], bounds[4]); // axes->SetScaleFactor(0.01); axesTubes = vtkTubeFilter::New(); axesTubes->SetInput(axes->GetOutput()); axesTubes->SetRadius(axes->GetScaleFactor()/100.0); axesTubes->SetNumberOfSides(6); axesMapper = vtkPolyDataMapper::New(); axesMapper->SetInput(axesTubes->GetOutput()); vtkActor *axesActor = vtkActor::New(); axesActor->SetMapper(axesMapper); // Create the usual rendering stuff renderer = vtkRenderer::New(); renWin = vtkRenderWindow::New(); renWin->AddRenderer(renderer); renderer->AddActor(magnActor); magnGradActor_added=false; renderer->AddActor(axesActor); // renderer->SetBackground(1,1,1); renderer->GetActiveCamera()->Roll(-120.0); // renderer->GetActiveCamera()->Azimuth(120.0); renderer->GetActiveCamera()->Elevation(-70.0); renderer->GetActiveCamera()->Zoom(0.25); renWin->SetSize(500,500); #else ODINLOG(odinlog,errorLog) << "vtk support is disabled, recompile with --enable-vtksupport" << STD_endl; #endif } void VtkMagnPlotter::plot_vector(float M[3], float* dM) { #ifdef VTKSUPPORT double Mnorm=norm3(M[0],M[1],M[2]); double heightAngle=180.0/PII*acos(secureDivision(M[2],Mnorm)); double azimuthAngle=180.0/PII*atan2(M[1],M[0]); magnActor->SetScale(Mnorm); magnActor->SetOrientation(0.0,heightAngle-90.0,azimuthAngle); if(dM) { // add magnGradActor if we have MagnGrads if(!magnGradActor_added) { renderer->AddActor(magnGradActor); magnGradActor_added=true; } // magnGradActor->SetOrigin(M[0],M[1],M[2]); Mnorm=norm3(dM[0],dM[1],dM[2]); heightAngle=180.0/PII*acos(secureDivision(dM[2],Mnorm)); azimuthAngle=180.0/PII*atan2(dM[1],dM[0]); magnGradActor->SetScale(0.02*Mnorm); magnGradActor->SetOrientation(0.0,heightAngle-90.0,azimuthAngle); } if(renWin) renWin->Render(); #endif } void VtkMagnPlotter::interact() { #ifdef VTKSUPPORT if(!iren) iren = vtkRenderWindowInteractor::New(); iren->SetRenderWindow(renWin); // interact with data if(iren) iren->Start(); #endif } VtkMagnPlotter::~VtkMagnPlotter() { #ifdef VTKSUPPORT if(axes) axes->Delete(); if(axesTubes) axesTubes->Delete(); if(axesMapper) axesMapper->Delete(); if(axesActor) axesActor->Delete(); if(magnArrow) magnArrow->Delete(); if(magnMapper) magnMapper->Delete(); if(magnActor) magnActor->Delete(); if(renderer) renderer->Delete(); if(iren) iren->Delete(); if(renWin) renWin->Delete(); #endif } odin-1.8.5/odin/odindialog_progress.cpp0000644000175000017500000000205711322062346015074 00000000000000#include "odindialog_progress.h" #include "odincomp.h" ProgressDisplayDialog::ProgressDisplayDialog(QWidget *parent, bool modal) : GuiProgressDialog(parent, modal, 0), counter(0) { // Non-percent display by default } void ProgressDisplayDialog::finish() { GuiProgressDialog::hide(); } void ProgressDisplayDialog::init(unsigned int nsteps, const char* txt) { Log odinlog("ProgressDisplayDialog","init"); ODINLOG(odinlog,normalDebug) << "nsteps/txt=" << nsteps << "/" << txt << STD_endl; if(txt) GuiProgressDialog::set_text(txt); GuiProgressDialog::set_total_steps(nsteps); GuiProgressDialog::reset(); GuiProgressDialog::show(); // Show dialog at this point, necessary for Bruker dialogs counter=0; } void ProgressDisplayDialog::increase(const char*) { counter++; // GuiProgressDialog expects [0...nsteps] GuiProgressDialog::set_progress( counter ); } bool ProgressDisplayDialog::refresh() { GuiApplication::process_events(); if(GuiProgressDialog::was_cancelled()) { throw OdinCancel(); return true; } return false; } odin-1.8.5/odin/odindialog_new.h0000644000175000017500000000304311322062346013462 00000000000000/*************************************************************************** odindialog_new.h - description ------------------- begin : Mon Oct 10 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_NEW_H #define ODINDIALOG_NEW_H #include #include class NewMethDialog : public QObject, public GuiDialog { Q_OBJECT public: NewMethDialog(QWidget *parent, JcampDxBlock& files); ~NewMethDialog(); public: void updateWidget(); signals: void valueChanged(); private slots: void done(); void cancel(); void emit_valueChanged(); private: GuiGridLayout* grid; GuiButton* pb_done; GuiButton* pb_cancel; JDXwidget* fileswidget; }; #endif odin-1.8.5/odin/odindialog_new.cpp0000644000175000017500000000237611322062346014025 00000000000000#include "odindialog_new.h" #include "odincomp.h" #include NewMethDialog::NewMethDialog(QWidget *parent, JcampDxBlock& files) : GuiDialog(parent,"Please select a template and a name for the new method",true) { Log odinlog("NewMethDialog","NewMethDialog"); grid=new GuiGridLayout(GuiDialog::get_widget(), 2, 2); fileswidget=new JDXwidget(files,1,GuiDialog::get_widget()); connect(fileswidget,SIGNAL(valueChanged()),this,SLOT(emit_valueChanged())); grid->add_widget( fileswidget, 0, 0, GuiGridLayout::Default, 1, 2 ); pb_cancel = new GuiButton( GuiDialog::get_widget(), this, SLOT(cancel()), "Cancel" ); grid->add_widget( pb_cancel->get_widget(), 1, 0, GuiGridLayout::Center ); pb_done = new GuiButton( GuiDialog::get_widget(), this, SLOT(done()), "Done" ); grid->add_widget( pb_done->get_widget(), 1, 1, GuiGridLayout::Center ); // GuiDialog::show(); } void NewMethDialog::updateWidget() { fileswidget->updateWidget(); } void NewMethDialog::done() { GuiDialog::done(); } void NewMethDialog::cancel() { GuiDialog::cancel(); } void NewMethDialog::emit_valueChanged() { emit valueChanged(); } NewMethDialog::~NewMethDialog() { delete pb_done; delete pb_cancel; delete fileswidget; delete grid; } odin-1.8.5/odin/odinplot.h0000644000175000017500000002104611363773556012354 00000000000000/*************************************************************************** odinplot.h - description ------------------- begin : Mon Jul 26 2004 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OdinPlot_H #define OdinPlot_H #include #include #include #include #include #include #include "odinplot_vtk.h" #define MIN_HEIGHT_PER_CHAN 120 #define MIN_WIDTH_PER_CHAN 1000 #define CLOSEST_CURVE_MAX 30 #define PLOT_SYMBOLS_MAX_RANGE 10 #define MAX_HIGHRES_INTERVAL 1000.0 #define MAX_MARKER_INTERVAL 400.0 #define MAX_START_RANGE 10000 #define MAGN_PLOT_PAGE_DURATION 20.0 class RangeWidget; // forward declaration ///////////////////////////////////////////////////////////// class PlotView : public QWidget, public SeqSimFeedbackAbstract { Q_OBJECT public: PlotView(const char* method, const STD_string& nucleus, GuiMainWindow* parent); ~PlotView(); const SeqTimecourseData* get_timecourses(); const SeqTimecourseData* get_kspace_trajs(); bool simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter); public slots: void replot(); void mouseMovedInPlot0(const QMouseEvent& e) {mouseMovedInPlot(0,e);} void mouseMovedInPlot1(const QMouseEvent& e) {mouseMovedInPlot(1,e);} void mouseMovedInPlot2(const QMouseEvent& e) {mouseMovedInPlot(2,e);} void mouseMovedInPlot3(const QMouseEvent& e) {mouseMovedInPlot(3,e);} void mouseMovedInPlot4(const QMouseEvent& e) {mouseMovedInPlot(4,e);} void mouseMovedInPlot5(const QMouseEvent& e) {mouseMovedInPlot(5,e);} void mouseMovedInPlot6(const QMouseEvent& e) {mouseMovedInPlot(6,e);} void mouseMovedInPlot7(const QMouseEvent& e) {mouseMovedInPlot(7,e);} void mouseMovedInPlot8(const QMouseEvent& e) {mouseMovedInPlot(8,e);} void mousePressedInPlot0(const QMouseEvent& e) {mousePressedInPlot(0,e);} void mousePressedInPlot1(const QMouseEvent& e) {mousePressedInPlot(1,e);} void mousePressedInPlot2(const QMouseEvent& e) {mousePressedInPlot(2,e);} void mousePressedInPlot3(const QMouseEvent& e) {mousePressedInPlot(3,e);} void mousePressedInPlot4(const QMouseEvent& e) {mousePressedInPlot(4,e);} void mousePressedInPlot5(const QMouseEvent& e) {mousePressedInPlot(5,e);} void mousePressedInPlot6(const QMouseEvent& e) {mousePressedInPlot(6,e);} void mousePressedInPlot7(const QMouseEvent& e) {mousePressedInPlot(7,e);} void mousePressedInPlot8(const QMouseEvent& e) {mousePressedInPlot(8,e);} void mouseReleasedInPlot0(const QMouseEvent& e) {mouseReleasedInPlot(0,e);} void mouseReleasedInPlot1(const QMouseEvent& e) {mouseReleasedInPlot(1,e);} void mouseReleasedInPlot2(const QMouseEvent& e) {mouseReleasedInPlot(2,e);} void mouseReleasedInPlot3(const QMouseEvent& e) {mouseReleasedInPlot(3,e);} void mouseReleasedInPlot4(const QMouseEvent& e) {mouseReleasedInPlot(4,e);} void mouseReleasedInPlot5(const QMouseEvent& e) {mouseReleasedInPlot(5,e);} void mouseReleasedInPlot6(const QMouseEvent& e) {mouseReleasedInPlot(6,e);} void mouseReleasedInPlot7(const QMouseEvent& e) {mouseReleasedInPlot(7,e);} void mouseReleasedInPlot8(const QMouseEvent& e) {mouseReleasedInPlot(8,e);} void autoscalePlot0() {autoscale_y(0);} void autoscalePlot1() {autoscale_y(1);} void autoscalePlot2() {autoscale_y(2);} void autoscalePlot3() {autoscale_y(3);} void autoscalePlot4() {autoscale_y(4);} void autoscalePlot5() {autoscale_y(5);} void autoscalePlot6() {autoscale_y(6);} void autoscalePlot7() {autoscale_y(7);} void autoscalePlot8() {autoscale_y(8);} void rescalePlot0(double val) {rescale_y(0,val);} void rescalePlot1(double val) {rescale_y(1,val);} void rescalePlot2(double val) {rescale_y(2,val);} void rescalePlot3(double val) {rescale_y(3,val);} void rescalePlot4(double val) {rescale_y(4,val);} void rescalePlot5(double val) {rescale_y(5,val);} void rescalePlot6(double val) {rescale_y(6,val);} void rescalePlot7(double val) {rescale_y(7,val);} void rescalePlot8(double val) {rescale_y(8,val);} void update_x_axes(); void autoscale_x(); void hide_and_show(); void set_rect_zoom_tool() {set_zoom_tool(rect);} void set_hort_zoom_tool() {set_zoom_tool(horizontal);} void set_vert_zoom_tool() {set_zoom_tool(vertical);} void change_toolbar(); void plot_all(); void osci(); void print(); void save(); void close(); void changeMode(int newmode); void settingsChanged(); void save_closest_curve_data(); void save_current_channel_data(); signals: void setMessage(const char* text); void closeMe(); private: friend class PlotWindow; double get_x(int iplot, int x_pixel); double get_y(int iplot, int y_pixel); void mouseMovedInPlot (int iplot, const QMouseEvent& e); void mousePressedInPlot (int iplot, const QMouseEvent& e); void mouseReleasedInPlot(int iplot, const QMouseEvent& e); void set_range_and_update_x_axes(double min, double max, bool discard_scrollbar=false); void autoscale_all_y(); void autoscale_y(int iplot); void rescale_y(int iplot, double val); void get_plot_label(int iplot, STD_string& label, STD_string& unit) const; void set_plot_labels(bool extra_space=false); void set_curve_pens(bool thick_lines=false); void create_baseline(); void add_plotcurve(const Curve4Qwt& curve); void create_plotcurves(); void add_marker(const Marker4Qwt& marker); void add_tc_marker(const TimecourseMarker4Qwt& marker); void create_markers(); void create_plotcurves_and_markers(); bool create_timecourses(timecourseMode type); void create_timecourse_markers(); void plot_timecourses(timecourseMode type); SeqPlotDataAbstract* plotdata; double totaldur; STD_string nuc; int plot_pressed,x_pressed,y_pressed; static int lastplot_old; double baseline_x[2]; double baseline_y[2]; long curveid_baseline[numof_plotchan]; int closest; int lastplot_closest; int lastcurve_closest; int iplot_cache; GuiToolBar* chan_toolbar; GuiToolBar* zoom_toolbar; GuiToolBar* settings_toolbar; GuiComboBox* plotmode; timecourseMode oldmode; GuiGridLayout* grid; GuiPlot* plotter[numof_plotchan]; GuiWheel* wheel[numof_plotchan]; GuiToolButton* plotflag[numof_plotchan]; // GuiButton* autoscalebutton[numof_plotchan]; GuiToolButton* oscibutton; GuiToolButton* printbutton; GuiToolButton* savebutton; GuiToolButton* closebutton; RangeWidget* x_range; GuiPrinter* printer; GuiToolButton* plotAxes; GuiToolButton* plotMarkers; GuiToolButton* plotGrid; enum zoomMode {rect=0, horizontal, vertical, numof_zoomModes}; void set_zoom_tool(zoomMode mode); GuiToolButton* zoomflag[numof_zoomModes]; long markid_vertzoom; long markid_hortzoom; STD_map curves_map[numof_plotchan]; long timecourse_curve_id[numof_tcmodes][numof_plotchan]; // Stuff for osci JDXenum TriggerType; JDXdouble TriggerWidth; JDXdouble RefreshRate; VtkMagnPlotter* active_magplot; long markid_magplot; int ipage; void plot_vector(double timepoint, float M[3], float* dM); // implementing virtual function of SeqSimFeedbackAbstract }; //////////////////////////////////////// class PlotWindow : public QObject, public GuiMainWindow { Q_OBJECT public: PlotWindow(const char* method, const STD_string& nucleus, QWidget *parent); ~PlotWindow(); const SeqTimecourseData* get_timecourses() {return view->get_timecourses();} const SeqTimecourseData* get_kspace_trajs() {return view->get_kspace_trajs();} bool simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter) {return view->simulate(fidfile,samplefile,progmeter);} public slots: void statusBarMessage(const char* text); void close(); private: PlotView* view; }; #endif odin-1.8.5/odin/odindialog_kspace.cpp0000644000175000017500000000616511322062346014502 00000000000000#include #include #include "odindialog_kspace.h" #include "odincomp.h" KspaceDialog::KspaceDialog(QWidget *parent, float kmax, unsigned int nadc) : GuiDialog(parent,"k-Space",false), k0(kmax), progcount(0), canceled(false) { Log odinlog("KspaceDialog","KspaceDialog"); ODINLOG(odinlog,normalDebug) << "kmax/nadc=" << kmax << "/" << nadc << STD_endl; grid=new GuiGridLayout(GuiDialog::get_widget(), 3, 1); int pixsize=KSPACE_INPLANE_SIZE+2*KSPACE_BORDER_SIZE+2*KSPACE_THROUGHPLANE_SIZE; kspace_pixmap_buff=new QPixmap(pixsize, pixsize); kspace_pixmap_buff->fill(_ARRAY_BACKGROUND_COLOR_); painter=new GuiPainter(kspace_pixmap_buff); painter->setPen(_ARRAY_GRID_COLOR_); int rectoffset=KSPACE_BORDER_SIZE+KSPACE_THROUGHPLANE_SIZE; painter->drawRect(rectoffset, rectoffset, KSPACE_INPLANE_SIZE, KSPACE_INPLANE_SIZE); painter->setPen(_ARRAY_GRID_COLOR_, 1, true); painter->moveTo(rectoffset,rectoffset+KSPACE_INPLANE_SIZE/2); painter->lineTo(rectoffset+KSPACE_INPLANE_SIZE,rectoffset+KSPACE_INPLANE_SIZE/2); painter->moveTo(rectoffset+KSPACE_INPLANE_SIZE/2,rectoffset); painter->lineTo(rectoffset+KSPACE_INPLANE_SIZE/2,rectoffset+KSPACE_INPLANE_SIZE); painter->end(); kspace_label=new QLabel(GuiDialog::get_widget()); kspace_label->setPixmap(*kspace_pixmap_buff); grid->add_widget( kspace_label, 0, 0, GuiGridLayout::Center ); progbar=new GuiProgressBar (GuiDialog::get_widget(), nadc); progbar->set_min_width(pixsize); grid->add_widget( progbar->get_widget(), 1, 0, GuiGridLayout::Center ); pb_cancel = new GuiButton( GuiDialog::get_widget(), this, SLOT(cancel()), "Cancel/Close" ); grid->add_widget( pb_cancel->get_widget(), 2, 0, GuiGridLayout::Center ); GuiDialog::show(); } KspaceDialog::~KspaceDialog() { delete pb_cancel; delete kspace_label; delete kspace_pixmap_buff; delete progbar; delete grid; delete painter; } void KspaceDialog::draw_point(float kx, float ky, float kz) { Log odinlog("KspaceDialog","draw_point"); ODINLOG(odinlog,normalDebug) << "kx/ky/kz=" << kx << "/" << ky << "/" << kz << STD_endl; painter->begin(kspace_pixmap_buff); int xpos=kpos2index(kx); int ypos=kpos2index(ky); float relz=secureDivision(-kz,k0); // draw high kz in the foreground xpos+=int(relz*KSPACE_THROUGHPLANE_SIZE+0.5); ypos-=int(relz*KSPACE_THROUGHPLANE_SIZE+0.5); // Start in lower left corner painter->setPen(_ARRAY_FOREGROUND_COLOR1_, 1, false, -relz); // Make foreground brighter painter->drawRect(xpos-KSPACE_POINT_SIZE/2, ypos-KSPACE_POINT_SIZE/2, KSPACE_POINT_SIZE, KSPACE_POINT_SIZE); painter->end(); painter->repaint(kspace_label); progress(); } void KspaceDialog::repaint() { painter->repaint(kspace_label); } void KspaceDialog::progress() { progcount++; progbar->set_progress(progcount); GuiApplication::process_events(); if(canceled) throw OdinCancel(); } void KspaceDialog::cancel() { canceled=true; hide(); } int KspaceDialog::kpos2index(float kpos) const { float relpos=secureDivision(kpos,k0); return KSPACE_BORDER_SIZE+KSPACE_THROUGHPLANE_SIZE+int(0.5*(relpos+1.0)*KSPACE_INPLANE_SIZE); } odin-1.8.5/odin/odinview.h0000644000175000017500000000763311455553540012345 00000000000000/*************************************************************************** odinview.h - description ------------------- begin : Sun Sep 28 21:30:11 CEST 2003 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OdinView_H #define OdinView_H #include #include #include #include "odinconf.h" #include "odindebugger.h" #include "odinmethod.h" #include "odinplot.h" #define ODIN_MINWIDTH 600 #define MESSAGES_HEIGHT 200 #define IMAGEVIEWER "miview" class ProgressDisplayDialog; // forward declaration class NewMethDialog; // forward declaration class IdeaOpts; // forward declaration class OdinView : public QWidget, public OdinMethodCallback { Q_OBJECT public: OdinView(QWidget *parent); ~OdinView(); void initOdinView(GuiToolBar* action_toolbar, bool has_debug_cmdline); static void usage(); public slots: void new_method(); void open_method(); void close_method(); void exit_odin(); void edit(); void recompile(); bool plot() {return create_seqplot();} void kspace(); void sim(); void geo(); void seqprops(); void seqtree(); void recoinfo(); void pulsars(); void pulsprog(); void gradprog(); void parx(); void pv_pilot(); void pv_scan(); void pv_rgscan(); void pv_howto(); void ideaevents(); void compile_idea(); void export_dlls(); void ideahowto(); void epiccode(); void edit_prefs(); void edit_system(); void load_system(); void edit_study(); void debug_opts(); void show_manual(); void show_apidoc(); void show_seqdoc(); void switch_to_platform_noask(odinPlatform pF); void recalc_method(); void new_geo_pars(); int load_prefs(bool ignore_debugLevels); int react_on_changed_prefs(); int save_prefs(); int save_protocol(); int load_protocol(); void newmeth_rels(); // void changeMethod(int index); signals: void newCaption(const char* text); void newStatus(bool, const char* text); private: void bruker_scan(bool autorg); bool chsrcdir(); bool prepare_method(); bool prepare_acquisition(); bool do_odinreco(const STD_string& outprefix); void update_methodsel(); bool switch_to_platform(odinPlatform pF, bool ask=true); STD_string get_samplefile(); bool create_seqplot(bool for_simulation=false); // implementing virtual functions of OdinMethodCallback void report(bool status, const STD_string& trans_label, const STD_string& message); void create_widgets(); void delete_widgets(); static void odintracefunction(const LogMessage& msg); static GuiTextView* messages_ptr; OdinConf settings; IdeaOpts* ideaopts; OdinMethod method; SeqPlatformProxy platform; GuiGridLayout *grid; GuiComboBox* methodsel; GuiTextView* messages; JDXwidget* seqpars; JDXwidget* commpars; ProgressDisplayDialog* progress; PlotWindow* seqplot; double* signal_x; double* signal_y; JDXfileName templatemeth; JDXstring newmethlabel; NewMethDialog* mewmethwizzard; bool newmethlabel_modified; STD_list subprocs; OdinDebugger debugger; void change_debugger(); }; #endif odin-1.8.5/odin/Makefile.am0000644000175000017500000000301411322062346012361 00000000000000 if GUI_ENABLED INCLUDES = $(all_includes) # Auto-generate any needed moc files %_moc.cpp: %.h $(MOC) -o $@ $< bin_PROGRAMS = odin odin_SOURCES = \ odincomp.cpp odincomp.h \ odinconf.cpp odinconf.h \ odindebugger.cpp odindebugger.h \ odindialog_progress.cpp odindialog_progress.h \ odindialog_process.cpp odindialog_process.h \ odindialog_system.cpp odindialog_system.h odindialog_system_moc.cpp \ odindialog_debug.cpp odindialog_debug.h odindialog_debug_moc.cpp \ odindialog_idea.cpp odindialog_idea.h odindialog_idea_moc.cpp \ odindialog_pulsar.cpp odindialog_pulsar.h odindialog_pulsar_moc.cpp \ odindialog_tree.cpp odindialog_tree.h \ odindialog_kspace.cpp odindialog_kspace.h odindialog_kspace_moc.cpp \ odindialog_new.cpp odindialog_new.h odindialog_new_moc.cpp \ odinmethod.cpp odinmethod.h \ odinplot_range.cpp odinplot_range.h odinplot_range_moc.cpp \ odinplot_vtk.cpp odinplot_vtk.h \ odinplot.cpp odinplot.h odinplot_moc.cpp \ odinview.cpp odinview.h odinview_moc.cpp \ odin.cpp odin.h icons.h odin_moc.cpp \ main.cpp odin_LDADD = ../odinseq/libodinseq.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la odin_LDFLAGS = $(VTKLIBS) # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = odin.1 dist-hook: -rm -rf $(distdir)/*_moc.cpp endif clean-local: -rm -f *_moc.cpp odin-1.8.5/odin/Makefile.in0000644000175000017500000006424011734622602012406 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @GUI_ENABLED_TRUE@bin_PROGRAMS = odin$(EXEEXT) subdir = odin DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__odin_SOURCES_DIST = odincomp.cpp odincomp.h odinconf.cpp \ odinconf.h odindebugger.cpp odindebugger.h \ odindialog_progress.cpp odindialog_progress.h \ odindialog_process.cpp odindialog_process.h \ odindialog_system.cpp odindialog_system.h \ odindialog_system_moc.cpp odindialog_debug.cpp \ odindialog_debug.h odindialog_debug_moc.cpp \ odindialog_idea.cpp odindialog_idea.h odindialog_idea_moc.cpp \ odindialog_pulsar.cpp odindialog_pulsar.h \ odindialog_pulsar_moc.cpp odindialog_tree.cpp \ odindialog_tree.h odindialog_kspace.cpp odindialog_kspace.h \ odindialog_kspace_moc.cpp odindialog_new.cpp odindialog_new.h \ odindialog_new_moc.cpp odinmethod.cpp odinmethod.h \ odinplot_range.cpp odinplot_range.h odinplot_range_moc.cpp \ odinplot_vtk.cpp odinplot_vtk.h odinplot.cpp odinplot.h \ odinplot_moc.cpp odinview.cpp odinview.h odinview_moc.cpp \ odin.cpp odin.h icons.h odin_moc.cpp main.cpp @GUI_ENABLED_TRUE@am_odin_OBJECTS = odincomp.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinconf.$(OBJEXT) odindebugger.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_progress.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_process.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_system.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_system_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_debug.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_debug_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_idea.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_idea_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_pulsar.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_pulsar_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_tree.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_kspace.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_kspace_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_new.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odindialog_new_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinmethod.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinplot_range.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinplot_range_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinplot_vtk.$(OBJEXT) odinplot.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinplot_moc.$(OBJEXT) odinview.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odinview_moc.$(OBJEXT) odin.$(OBJEXT) \ @GUI_ENABLED_TRUE@ odin_moc.$(OBJEXT) main.$(OBJEXT) odin_OBJECTS = $(am_odin_OBJECTS) @GUI_ENABLED_TRUE@odin_DEPENDENCIES = ../odinseq/libodinseq.la \ @GUI_ENABLED_TRUE@ ../odinqt/libodinqt.la \ @GUI_ENABLED_TRUE@ ../odinpara/libodinpara.la \ @GUI_ENABLED_TRUE@ ../tjutils/libtjutils.la odin_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \ $(odin_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(odin_SOURCES) DIST_SOURCES = $(am__odin_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @GUI_ENABLED_TRUE@INCLUDES = $(all_includes) @GUI_ENABLED_TRUE@odin_SOURCES = \ @GUI_ENABLED_TRUE@ odincomp.cpp odincomp.h \ @GUI_ENABLED_TRUE@ odinconf.cpp odinconf.h \ @GUI_ENABLED_TRUE@ odindebugger.cpp odindebugger.h \ @GUI_ENABLED_TRUE@ odindialog_progress.cpp odindialog_progress.h \ @GUI_ENABLED_TRUE@ odindialog_process.cpp odindialog_process.h \ @GUI_ENABLED_TRUE@ odindialog_system.cpp odindialog_system.h odindialog_system_moc.cpp \ @GUI_ENABLED_TRUE@ odindialog_debug.cpp odindialog_debug.h odindialog_debug_moc.cpp \ @GUI_ENABLED_TRUE@ odindialog_idea.cpp odindialog_idea.h odindialog_idea_moc.cpp \ @GUI_ENABLED_TRUE@ odindialog_pulsar.cpp odindialog_pulsar.h odindialog_pulsar_moc.cpp \ @GUI_ENABLED_TRUE@ odindialog_tree.cpp odindialog_tree.h \ @GUI_ENABLED_TRUE@ odindialog_kspace.cpp odindialog_kspace.h odindialog_kspace_moc.cpp \ @GUI_ENABLED_TRUE@ odindialog_new.cpp odindialog_new.h odindialog_new_moc.cpp \ @GUI_ENABLED_TRUE@ odinmethod.cpp odinmethod.h \ @GUI_ENABLED_TRUE@ odinplot_range.cpp odinplot_range.h odinplot_range_moc.cpp \ @GUI_ENABLED_TRUE@ odinplot_vtk.cpp odinplot_vtk.h \ @GUI_ENABLED_TRUE@ odinplot.cpp odinplot.h odinplot_moc.cpp \ @GUI_ENABLED_TRUE@ odinview.cpp odinview.h odinview_moc.cpp \ @GUI_ENABLED_TRUE@ odin.cpp odin.h icons.h odin_moc.cpp \ @GUI_ENABLED_TRUE@ main.cpp @GUI_ENABLED_TRUE@odin_LDADD = ../odinseq/libodinseq.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @GUI_ENABLED_TRUE@odin_LDFLAGS = $(VTKLIBS) # Manual pages for distribution @GUI_ENABLED_TRUE@dist_man_MANS = odin.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu odin/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu odin/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list odin$(EXEEXT): $(odin_OBJECTS) $(odin_DEPENDENCIES) @rm -f odin$(EXEEXT) $(odin_LINK) $(odin_OBJECTS) $(odin_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odin_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odincomp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinconf.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindebugger.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_debug.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_debug_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_idea.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_idea_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_kspace.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_kspace_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_new.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_new_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_process.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_progress.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_pulsar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_pulsar_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_system.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_system_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odindialog_tree.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinmethod.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinplot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinplot_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinplot_range.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinplot_range_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinplot_vtk.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinview_moc.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @GUI_ENABLED_FALSE@dist-hook: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags dist-hook \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 # Auto-generate any needed moc files @GUI_ENABLED_TRUE@%_moc.cpp: %.h @GUI_ENABLED_TRUE@ $(MOC) -o $@ $< # Auto-generate manual pages, only if not in srcdir @GUI_ENABLED_TRUE@%.1: % @GUI_ENABLED_TRUE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @GUI_ENABLED_TRUE@dist-hook: @GUI_ENABLED_TRUE@ -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odin/odindialog_idea.h0000644000175000017500000000752311322062346013602 00000000000000/*************************************************************************** odindialog_idea.h - description ------------------- begin : Fri Mar 9 21:30:11 CEST 2007 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_IDEA_H #define ODINDIALOG_IDEA_H // Qt related headers first to avoid ambiguity with 'debug' #include #include #include #include #include #include "odinconf.h" struct IdeaOpts : JcampDxBlock { IdeaOpts(); void set_defaults(const OdinConf& conf, QWidget *parent); STD_string get_vxworks_postfix() const; STD_string get_vxworks_ext() const; STD_string get_vxworks_Makefile() const; STD_string get_vxworks_cxx() const {return odindir+"/bin/cxxwrapper.exe";} STD_string get_ideadir_slash() const {return replaceStr(ideadir,"\\","/");} STD_string get_odindir_slash() const {return replaceStr(odindir,"\\","/");} JDXfileName arch; JDXfileName ideadir; JDXfileName odindir; JDXfileName msvcdir; JDXfileName seqdir; JDXstring odin2idea_label; JDXfileName icedir; JDXenum vxworks_cpu; JDXint vxworks_heap_size; JDXbool debug_vxworks_host; JDXint make_jobs; JDXbool make_clean; // read-only settings JDXfileName vxworks_dir; JDXstring vxworks_flags; JDXstring vxworks_opts; JDXfileName vxworks_path; JDXfileName win_cxx; JDXstring hostd_flags; JDXstring host_flags; }; /////////////////////////////////////////////////////// class IdeaDialog : public QObject, public GuiDialog { Q_OBJECT public: IdeaDialog(QWidget *parent, IdeaOpts& opts, const OdinConf& conf); ~IdeaDialog(); signals: void changed(); private slots: void cancel(); void defaults(); void compile(); void update(); private: void do_compile(); void error_msg(const STD_string& msg); int find_in_alternatives(const STD_string& findstr, const STD_list& alternatives); bool execute_make(const STD_string& make, const STD_string& target); STD_string hosttarget(bool debug, const STD_string& build_includes, const STD_string& global_conf, const STD_string& mprefix, const STD_string& make_install) const; static STD_string errcodes_src(const STD_string& msgfile); IdeaOpts& opts_cache; const OdinConf& conf_cache; GuiGridLayout* grid; GuiButton* pb_cancel; GuiButton* pb_defaults; GuiButton* pb_compile; JDXwidget* optswidget; }; /////////////////////////////////////////////////////// class IdeaMethodDialog : public QObject, public GuiDialog { Q_OBJECT public: IdeaMethodDialog(const STD_string& methdir, sarray& selectedMethods, const STD_string& install_prefix, const IdeaOpts& ideaopts, QWidget *parent); ~IdeaMethodDialog(); private slots: void make(); void emitDone(); private: GuiButton* pb_make; GuiButton* pb_cancel; GuiGridLayout* grid; GuiListView* method_list; STD_list method_checks; sarray& selMeth; STD_string methrootdir; STD_string install_dir; const IdeaOpts& ideaopts_cache; }; #endif odin-1.8.5/odin/odindialog_process.h0000644000175000017500000000266211322062346014355 00000000000000/*************************************************************************** odindialog_process.h - description ------------------- begin : Sun Oct 2 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_PROCESS_H #define ODINDIALOG_PROCESS_H #include // for forkResult #include "odindialog_progress.h" #define TIMER_INTERVAL 100 class ProcessDialog : public ProgressDisplayDialog { public: ProcessDialog(QWidget *parent); int execute_cmds(const svector& command_chain, bool log_std_streams=true); private: void update_progbar(); int progcount; }; #endif odin-1.8.5/odin/odinmethod.cpp0000644000175000017500000001221711322062346013170 00000000000000#include "odinmethod.h" #include "odindialog_process.h" OdinMethod::OdinMethod(const OdinConf& conf, OdinMethodCallback* callback, QWidget* parent4dialog) : StateMachine(&clean), clean (this,"Clean", 0, &OdinMethod::make_clean), compiled(this,"Compiled",&clean, &OdinMethod::clean2compiled), linked (this,"Linked" ,&compiled,&OdinMethod::compiled2linked), settings(conf), cback(callback), parent(parent4dialog) { Log odinlog("OdinMethod","OdinMethod"); register_direct_trans(&linked,&compiled,&OdinMethod::linked2compiled); } bool OdinMethod::make_clean() { Log odinlog("OdinMethod","make_clean"); if(!check_srcdir()) return false; bool result=unlink(); cback->report(result, "make_clean", method.get_status_string()); return result; } bool OdinMethod::clean2compiled() { Log odinlog("OdinMethod","clean2compiled"); if(!check_srcdir()) return false; return make(); } bool OdinMethod::compiled2linked() { Log odinlog("OdinMethod","compiled2linked"); if(!check_srcdir()) return false; STD_string so_name(find_so()); ODINLOG(odinlog,normalDebug) << "so_name=" << so_name << STD_endl; if(!method.load_method_so(so_name)) { cback->report(false, "compiled2linked", "Failed linking shared object "+so_name); return false; } else ODINLOG(odinlog,normalDebug) << "loaded sequence plugin" << STD_endl; int nmeth=method.get_numof_methods(); ODINLOG(odinlog,normalDebug) << "nmeth=" << nmeth << STD_endl; if(nmeth) { if(!method->init()) { cback->report(false, "compiled2linked", method.get_status_string()); return false; } ODINLOG(odinlog,normalDebug) << "init method done" << STD_endl; method->load_sequencePars(seqParsFile()); ODINLOG(odinlog,normalDebug) << "loaded sequencePars" << STD_endl; if(!method->build()) { cback->report(false, "compiled2linked", method.get_status_string()); return false; } ODINLOG(odinlog,normalDebug) << "build method done" << STD_endl; cback->create_widgets(); } cback->report(true, "compiled2linked", method.get_status_string()); return true; } bool OdinMethod::linked2compiled() { Log odinlog("OdinMethod","linked2compiled"); if(!check_srcdir()) return false; return unlink(); } bool OdinMethod::relink() { Log odinlog("OdinMethod","relink"); if(compiled.obtain_state()) return linked.obtain_state(); return false; } STD_string OdinMethod::seqParsFile() { return settings.sourcecode.get_dirname()+SEPARATOR_STR+settings.sourcecode.get_basename_nosuffix()+"_sequencePars"; } bool OdinMethod::unlink() { Log odinlog("OdinMethod","unlink"); if(method.get_numof_methods()) method->write_sequencePars(seqParsFile()); ODINLOG(odinlog,normalDebug) << "sequencePars stored" << STD_endl; ODINLOG(odinlog,normalDebug) << "deleting widgets" << STD_endl; cback->delete_widgets(); ODINLOG(odinlog,normalDebug) << "deleting old methods" << STD_endl; method.delete_methods(); return true; } bool OdinMethod::check_srcdir() { Log odinlog("OdinMethod","check_srcdir"); if(settings.sourcecode=="") { cback->report(false, "check_srcdir", "No method specified"); return false; } STD_string dirname(settings.sourcecode.get_dirname()); ODINLOG(odinlog,normalDebug) << "sourcecode / dirname=" << settings.sourcecode << " / " << dirname << STD_endl; if(!browse_dir(dirname).size()) { ODINLOG(odinlog,normalDebug) << "length(dirname)=0" << STD_endl; cback->report(false, "check_srcdir", "Directory " + dirname + " is invalid"); return false; } if(chpwd(dirname.c_str())) { ODINLOG(odinlog,normalDebug) << "chpwd failed" << STD_endl; cback->report(false, "check_srcdir", "Cannot change directory to " + dirname); return false; } cback->report(true, "check_srcdir", "Ready"); return true; } bool OdinMethod::make() { Log odinlog("OdinMethod","make"); ProcessDialog makedlg(parent); int waitstate=makedlg.execute_cmds(settings.get_method_compile_chain()); bool status=!waitstate; if(waitstate==-2) { cback->report(true,"make","Compilation interrupted"); } if(waitstate==-1) { cback->report(false,"make","Cannot start compiler"); } if(waitstate>0) { cback->report(false,"make","Compilation failed"); } ODINLOG(odinlog,normalDebug) << "status / waitstate = " << status << " / " << waitstate << STD_endl; if(status) cback->report(true, "make_clean", "Compiled"); return status; } STD_string OdinMethod::find_so() { Log odinlog("OdinMethod","find_so"); STD_string result; STD_string methlabel(settings.sourcecode.get_basename_nosuffix()); svector filelist(browse_dir(settings.sourcecode.get_dirname(),false,true)); for(unsigned int i=0; i0) { result=curr_file; break; } } ODINLOG(odinlog,normalDebug) << "result = " << result << STD_endl; return settings.sourcecode.get_dirname()+SEPARATOR_STR+result; } odin-1.8.5/odin/odinplot_range.h0000644000175000017500000000367211322062346013514 00000000000000/*************************************************************************** odinplot_range.h - description ------------------- begin : Wed Oct 12 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINPLOT_RANGE_H #define ODINPLOT_RANGE_H #include #include class QScrollBar; // forward declaration class RangeWidget : public QWidget { Q_OBJECT public: RangeWidget(double total_min, double total_max, double start_min, double start_max, QWidget *parent); ~RangeWidget(); double get_min() {return min_x->get_value();} double get_max() {return max_x->get_value();} // public slots: void set_range(double min, double max, bool discard_scrollbar=false); signals: void new_range(); private slots: void new_scroll_val(int v); void new_minmax_val(float); private: friend class QScrollBar; friend class floatLineEdit; void check_and_set_range(double min, double max); void update_scrollbar(); GuiGridLayout* grid; GuiScrollBar* scrollbar; floatLineEdit *min_x, *max_x; double total_min_cache, total_max_cache; bool react_on_scrollbar_change; }; #endif odin-1.8.5/odin/odindialog_system.cpp0000644000175000017500000000331011322062346014545 00000000000000#include "odindialog_system.h" #include #include SystemDialog::SystemDialog(QWidget *parent) : GuiDialog(parent,"SystemDialog",false), sysInfo_widget(0) { grid = new GuiGridLayout( GuiDialog::get_widget(), 3, 2 ); svector poss_platforms(SeqPlatformProxy::get_possible_platforms()); odinPlatform current_pf=SeqPlatformProxy::get_current_platform(); pf=new enumBox(poss_platforms,GuiDialog::get_widget(),"Platform"); pf->setValue(current_pf); grid->add_widget( pf, 0, 0, GuiGridLayout::Center ); connect( pf, SIGNAL(newVal(int)), this,SLOT(change_platform(int)) ); create_systemInfo_widget(); pb_done = new GuiButton( GuiDialog::get_widget(), this, SLOT(emitDone()), "Done" ); grid->add_widget( pb_done->get_widget(), 2, 1, GuiGridLayout::Center ); // connect( pb_done->get_widget(), SIGNAL(clicked()), this,SLOT(emitDone()) ); this->show(); } SystemDialog::~SystemDialog() { if(sysInfo_widget) delete sysInfo_widget; delete pf; delete pb_done; delete grid; } void SystemDialog::create_systemInfo_widget() { if(sysInfo_widget) delete sysInfo_widget; SeqPlatformProxy platform; sysInfo_widget=new JDXwidget(platform->get_systemInfo(),1,GuiDialog::get_widget()); sysInfo_widget->show(); grid->add_widget( sysInfo_widget, 1, 0, GuiGridLayout::Center, 1, 2 ); connect( sysInfo_widget, SIGNAL(valueChanged()), this,SLOT(emitChanged()) ); } void SystemDialog::emitChanged() { emit new_setting(); } void SystemDialog::emitDone() { emit finished(); GuiDialog::done(); } void SystemDialog::change_platform(int pF) { emit new_platform(odinPlatform(pF)); // change platform before creating new widget create_systemInfo_widget(); } odin-1.8.5/odin/odindialog_process.cpp0000644000175000017500000000440711322062346014707 00000000000000#include "odindialog_process.h" #include #include "odincomp.h" ProcessDialog::ProcessDialog(QWidget *parent) : ProgressDisplayDialog(parent,false) { Log odinlog("ProcessDialog","ProcessDialog"); } void ProcessDialog::update_progbar() { GuiProgressDialog::set_progress(progcount); progcount++; GuiApplication::process_events(); } int ProcessDialog::execute_cmds(const svector& command_chain, bool log_std_streams) { Log odinlog("ProcessDialog","execute_cmds"); int status=0; bool firstcmd=true; progcount=0; if(!command_chain.size()) return status; Process* procs=new Process[command_chain.size()]; // ODINLOG(odinlog,infoLog) << STD_endl; // make sure we start a new line for(unsigned int icmd=0; icmd or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/odin/odin.h0000644000175000017500000002000611322062346011427 00000000000000/*************************************************************************** odin.h - description ------------------- begin : Sun Sep 28 21:30:11 CEST 2003 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef Odin_H #define Odin_H #include "odinview.h" /** * \page odin_doc ODIN user interface for sequence design (odin binary) * * \image html http://od1n.sourceforge.net/screenshots/odin.jpg * * \section odin_intro Introduction * The ODIN user interface is an easy-to-use program to edit, compile, test, and * simulate NMR sequences interactively in a single window. * Thereby the NMR sequence is compiled as a plug-in (shared object on UNIX or DLL * on Windows) and linked into the user interface. After that, the sequence * can be analyzed in various ways (vizualisation, simulation). * This documentation will describe all elements of the user interface * and their functionality to accomplish this task. * * \section odin_qg Quick Guide * A typical session with the ODIN user interface involves the following steps * - Create a new sequence by File->New or open an existing sequence by File->Open * - Compile & Link the sequence by the 'recycling'-symbol in the tool bar (alternatively Action->Compile & Link) * - Edit the sequence paramers * - Visualize the sequence by the 'plot'-symbol in the tool bar (alternatively Action->Plot Sequence) * - Simulate the sequence by the 'oscilloscope'-symbol in the tool bar (alternatively Action->Simulate) * * * \section parfield Parameter Field * After successfully compiling and linking a sequence, the central part * will contain a grid of widgets which contain the sequence parameters. * Each time a parameter is changed, the sequence will be recalculated. * * \section msgbox Message Box * The lower part contains a text field which displays warning/error messages from the * current sequence, compiler errors, etc. * * \section statindicator Status Bar * At the very bottom, the current status of the user interface is indicated by * a green/red light and a short message. For example, if compilation of * the sequence fails, this will be indicated in the Status Bar. * * * \section fileMenu File Menu * \subsection fileMenu_new New * Creates a new sequence by taking the source code of another sequences as a template * \subsection fileMenu_open Open * Opens the source code of a previously used sequence * \subsection fileMenu_close Close * Closes the current sequence * \subsection fileMenu_save Save Settings * Saves the current state of the ODIN user interface (compiler settings, debug levels, sequence parameters, system configuration, ...) * \subsection fileMenu_storeprot Save Protocol * Saves the current measurement protocol in a single protocol file * \subsection fileMenu_loadprot Load Protocol * Loads the current measurement protocol from a single protocol file * \subsection fileMenu_quit Quit * Exit the ODIN user interface * * \section actionMenu Action Menu * All entries in this menu can also be found in the tool bar with the corresponding icon. * \subsection actionMenu_edit Edit * Opens an editor (customizable via Preferences->Settings) to edit the source code of the sequence * \subsection actionMenu_comp Compile & &Link * Compiles the current sequence, and if successful, links it into the ODIN user interface * \subsection actionMenu_geo Geometry * Opens a dialog to edit the current geometry, i.e. slice positioning * \subsection actionMenu_plot Plot Sequence * Plots the sequence using an embedded plotting window * \subsection actionMenu_kspace Acquisition k-Space * Shows the k-Space during acquisition * \subsection actionMenu_sim Simulate * Simulates the current sequence. First, a dialog will pop-up to ask you for * various simulation settings. Then, after loading a virtual sample, a virtual NMR * signal will be created which can then be viewed in the plotting window. The * simulated raw data together with the parameter files is stored under * $HOME/odin-methods//sim. After simulation, the reconstruction is started using the simulated raw data. * * \section infoMenu Info Menu * \subsection infoMenu_prop Sequence Properties * Shows the description of the sequence together with some additional information * \subsection infoMenu_tree Sequence Tree * Displays the sequence tree, i.e. the internal layout of the sequence * \subsection infoMenu_reco Reconstruction Parameters * Displays all parameters used for automatic reconstruction * \subsection infoMenu_pulsars Pulsar Pulses * Displays a list of used SeqPulsar pulses in the current sequence. * By clicking an item in the list, the Pulsar user interface will pop up to show the * parameters of the pulse. * * \section brukerMenu Bruker Menu * \subsection brukerMenu_ppg Pulse Program * Displays the pulse program * \subsection brukerMenu_gp Gradient Program * Displays the gradient program * \subsection brukerMenu_parx PARX parameters * Displays parameters in the PARX parameter space which are used by ODIN * \subsection brukerMenu_pilot Pilot * Start a pilot scan on the host where Paravision is running * \subsection brukerMenu_scan Scan * Start a scan (GOP) on host where Paravision is running using the current sequence settings * * \section siemensMenu Siemens Menu * \subsection siemensMenu_events Event Table * Displays the event blocks and the events therein of the current sequence * \subsection siemensMenu_idea Compile ODIN for IDEA * Compile the ODIN libraries for sequence design for IDEA so that IDEA DLLs can be exported * \subsection siemensMenu_dll Export Siemens DLLs * Create all files/objects necessary to create a Siemens sequence DLL which contains all previously selected ODIN sequences * * \section geMenu GE Menu * \subsection geMenu_events EPIC Code * Generates code for the EPIC framework * * \section prefMenu Preferences Menu * \subsection prefMenu_sett Settings * Edit the Settings of the ODIN user interface * \subsection prefMenu_sys System * Edit the system configuration * \subsection prefMenu_loadsys Load systemInfo * Load the system configuration from a file * \subsection prefMenu_debug Debugging/Tracing * Change the debugging/tracing settings * This option is not available if ODIN was compiled as a release * */ #define IDS_ODIN_ABOUT "ODIN user interface\nVersion " VERSION \ "\n(w) 2004 by Thies Jochimsen\n\n" \ "Compiled with the following plugins:\n" \ PLUGIN_LIBS class Odin : public QObject, public GuiMainWindow { Q_OBJECT public: Odin(); void initOdin(GuiApplication* a, bool has_debug_cmdline); public slots: void changeCaption(const char* text); void changeStatus(bool status, const char* text); private slots: void slotHelpAbout(); private: OdinView *view; GuiPopupMenu *fileMenu; GuiPopupMenu *actionMenu; GuiPopupMenu *infoMenu; GuiPopupMenu *brukerMenu; GuiPopupMenu *siemensMenu; GuiPopupMenu *geMenu; GuiPopupMenu *prefMenu; GuiPopupMenu *helpMenu; GuiToolBar *toolbar; bool old_status; bool first_status; }; #endif odin-1.8.5/odin/odindialog_progress.h0000644000175000017500000000333011322062346014534 00000000000000/*************************************************************************** odindialog_progress.h - description ------------------- begin : Sun Oct 2 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_PROGRESS_H #define ODINDIALOG_PROGRESS_H #include #include struct OdinCancel {}; // exception ///////////////////////////////////////////// class ProgressDisplayDialog : public GuiProgressDialog, public virtual ProgressDisplayDriver { public: ProgressDisplayDialog(QWidget *parent, bool modal = true); void finish(); private: // Implementing virtual functions of ProgressDisplayDriver void init(unsigned int nsteps, const char* txt); void increase(const char*); bool refresh(); int counter; // Getting current progress from GuiProgressDialog does not work in non-percent mode, so we need an extra counter }; #endif odin-1.8.5/odin/odindialog_system.h0000644000175000017500000000315311322062346014217 00000000000000/*************************************************************************** odindialog_system.h - description ------------------- begin : Sun Oct 2 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_SYSTEM_H #define ODINDIALOG_SYSTEM_H #include #include #include class SystemDialog : public QObject, public GuiDialog { Q_OBJECT public: SystemDialog(QWidget *parent); ~SystemDialog(); signals: void new_platform(odinPlatform pF); void new_setting(); void finished(); private slots: void emitDone(); void emitChanged(); void change_platform(int pF); private: void create_systemInfo_widget(); GuiGridLayout* grid; enumBox* pf; GuiButton* pb_done; JDXwidget* sysInfo_widget; }; #endif odin-1.8.5/odin/odindialog_tree.h0000644000175000017500000000321711322062346013633 00000000000000/*************************************************************************** odindialog_tree.h - description ------------------- begin : Mon Oct 10 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_TREE_H #define ODINDIALOG_TREE_H #include #include class TreeDialog : public GuiDialog, public SeqTreeCallbackAbstract { public: TreeDialog(QWidget *parent, const char* caption, const svector& column_labels); ~TreeDialog(); private: // virtual functions from SeqTreeCallbackAbstract void display_node(const SeqClass* thisnode, const SeqClass* parentnode, int treelevel, const svector& columntext); GuiGridLayout* grid; GuiListView* root; STD_map nodemap; STD_map lastitemmap; }; #endif odin-1.8.5/odin/icons.h0000644000175000017500000006351211322062346011622 00000000000000static const char *recompIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 193 2", " c Gray0", ". c Transparent", "X c #010101", "o c Gray1", "O c #070707", "+ c #010801", "@ c #020900", "# c Gray3", "$ c Gray4", "% c #0b0b0b", "& c Gray5", "* c #041203", "= c #061902", "- c #121600", "; c #141400", ": c #161600", "> c #101800", ", c #111113", "< c Gray7", "1 c Gray8", "2 c #151515", "3 c Gray9", "4 c #17171b", "5 c #191919", "6 c Gray10", "7 c Gray11", "8 c #1d1d1d", "9 c Gray12", "0 c #02230b", "q c #082003", "w c #0b2a05", "e c #0d3306", "r c #0a3009", "t c #112405", "y c #142908", "u c #142b0a", "i c #192c0b", "p c #16310c", "a c #17320c", "s c #1a330d", "d c #1b3e0f", "f c #113d10", "g c #1c3f10", "h c #270708", "j c #230806", "k c #250904", "l c #212106", "z c #213b14", "x c Gray13", "c c #222222", "v c Gray14", "b c #252525", "n c Gray16", "m c #2a2a2a", "M c #2c2c2c", "N c Gray18", "B c #2f2f2f", "V c Gray20", "C c #343434", "Z c #353535", "A c #34343a", "S c Gray22", "D c Gray23", "F c #3c3c3c", "G c Gray24", "H c #3f3f47", "J c #15410c", "K c #1c4110", "L c #1d4613", "P c #1e4917", "I c #284919", "U c #215017", "Y c #225118", "T c #275225", "R c #2b5623", "E c #2d582b", "W c #305020", "Q c #315c27", "! c #217316", "~ c #25791e", "^ c #256022", "/ c #296c27", "( c #2a6f2b", ") c #2a732f", "_ c #2c7f39", "` c #366d2f", "' c #337f3a", "] c #490f0e", "[ c #446a3d", "{ c #417036", "} c #407438", "| c Gray25", " . c #414141", ".. c Gray26", "X. c #434343", "o. c Gray27", "O. c #464646", "+. c Gray28", "@. c #414149", "#. c #484848", "$. c #4b4b4b", "%. c #4c4c4c", "&. c Gray30", "*. c #4a4a52", "=. c #505050", "-. c #515151", ";. c #565656", ":. c Gray34", ">. c #52525a", ",. c Gray37", "<. c #426344", "1. c #406641", "2. c #477d40", "3. c #686868", "4. c Gray41", "5. c #6a6a6a", "6. c #6d6d6d", "7. c #6f6f6f", "8. c Gray44", "9. c #717171", "0. c Gray46", "q. c #797979", "w. c #2c813a", "e. c #2d823b", "r. c #2f833c", "t. c #31843e", "y. c #32843f", "u. c #3d8e35", "i. c #2f8b40", "p. c #2f8f46", "a. c #378843", "s. c #3d8f4b", "d. c #3a924c", "f. c #319e52", "g. c #2fa057", "h. c #32a65c", "j. c #32a85d", "k. c #33b364", "l. c #34b464", "z. c #48a92e", "x. c #49a23f", "c. c #52aa3f", "v. c #56ae3b", "b. c #46914f", "n. c #419652", "m. c #50854a", "M. c #46b670", "N. c #47b671", "B. c #55bd7a", "V. c #668a5f", "C. c #628663", "Z. c #63c284", "A. c #63c385", "S. c #64c280", "D. c #65c284", "F. c #6ac684", "G. c #6fc386", "H. c #7dcb8f", "J. c #c7371a", "K. c #818181", "L. c Gray51", "P. c #848484", "I. c #898989", "U. c #8d8d8d", "Y. c #8f8f97", "T. c #9a9a9a", "R. c Gray61", "E. c Gray63", "W. c Gray64", "Q. c #a5a5a5", "!. c #afafaf", "~. c #bcbcbc", "^. c #8ccb84", "/. c #82cd91", "(. c #9dc392", "). c #a3daae", "_. c #b3d7ac", "`. c #b0e1b5", "'. c #b2e0b8", "]. c #b8e2be", "[. c #b9e4bd", "{. c #bee5c1", "}. c #cacaca", "|. c #cbe9cb", " X c #ceecce", ".X c #d4f4d4", "XX c #d8f0d6", "oX c #dbf1d9", "OX c #dff3dd", "+X c #e0f3dd", "@X c #e2f4e1", "#X c #e4f4e1", "$X c None", /* pixels */ "$X$X$X$X$X$X$X$XU Y g K z s ; $X$X$X$X$X$X$X", "$X$X$X$X$X$XL ) D.XX[./.s.2.{ P d $X$X$X$X$X", "$X$X$X$X$XL j.oX].N.r.L t - l ; P y $X$X$X$X", "$X$X$X$X$X) @X'.N.m.; ; $X$X$X$X; y > $X$X$X", "$X$X$X$XL D.|.A.' a $X$X$X$X$X$X$X$Xy ; $X$X", "$X$X$X$X( #X).y.; $X$X$X$X$X$X$X$X$X$X; $X$X", "$X$X$X$X/ +XA.b.y $X$X$X$X$X$X$X$X$X$X$X$X$X", "; d I W g.{.B.y.i ; ; ; $X$X$X$X$X$X$X$X$X$X", "; _ `.OX.XG.n.a.H. Xw.a $X$X$X. 1 $X$X$X$X$X", "$X; ` h.l.f.d.S.w.^ ; $X$X$X. E.o.5 $X$X$X$X", "$X$X; ` p.k.F.w.^ ; $X$X$X. ~.6.P.o.1 $X$X$X", "$X$X$X; } i.w.^ ; $X$X$X. }.6.S $.U.&.5 $X$X", "$X$X$X$X; ` ^ ; $X$X$X. ~.8.C c m &.U.o.1 $X", "$X$X$X$X$X; ; $X$X$XN E.4.o.o.m N N o.8.N % ", "$X$X$X$X$X$X$X$X$X$X. . . . 0.F =.b . . . . ", "$X$X$X$X$X$X$X$X$X$X$X$X$X. I. .;.b $X$X$X$X", "$X$X. $X$X$X$X$X$X$X$X$X$X. E.S =.5 $X$X$X$X", "$X$X. . $X$X$X$X$X$X$X$X. !.4. . .% $X$X$X$X", "$X$X$X. . . $X$X$X$X. . !.P. .$.1 $X$X$X$X$X", "$X$X$X$X% c % 9 . . q.!.K.=.=.N O $X$X$X$X$X", "$X$X$X$X$X. 9 $.4.K.Q.,. .=.& . $X$X$X$X$X$X", "$X$X$X$X$X$X$X% , 5 9 c 9 . $X$X$X$X$X$X$X$X" }; /* static const char *cleanIcon[] = { "22 22 9 1", " c black", ". c navy", "X c #800000", "o c #C00000", "O c #8080FF", "+ c #C0C0FF", "@ c #FFC0C0", "# c gray100", "$ c None", "$$$$$$$$$$$$$$$$+. $$$", "$$$$$$$$$$$$$$$+OO. $$", "$$$$$$$$$$$$$$+OOOO. $", "$$$$$$$$$$$$$+OOOOOO. ", "$$$$$$$$$$$$+OOOOOOOO.", "$$$$$$$$$$$+OOOOOOOOO.", "$$$$$$$$$$+OOOOOOOOO. ", "$$$$$$$$$+OOOOOOOOO. $", "$$$$$$$$+OOOOOOOOO. $$", "$$$$$$$@##OOOOOOO. $$$", "$$$$$$@oo##OOOOO. $$$$", "$$$$$@oooo##OOO. $$$$$", "$$$$@oooooo##O. $$$$$$", "$$$@oooooooo#. $$$$$$$", "$$@oooooooooX $$$$$$$$", "$@oooooooooX $$$$$$$$$", "@@@oooooooX $$$$$$$$$$", "@@@@oooooX $$$$$$$$$$$", "$@@@@oooX $$$$$$$$$$$$", "$$@@@@oX $$$$$$$$$$$$$", "$$$@@@X $$$$$$$$$$$$$$", "$$$$@X $$$$$$$$$$$$$$$" }; */ static const char *editIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 187 2", " c Gray0", ". c #040404", "X c #090909", "o c Gray5", "O c #0e0e0e", "+ c #101010", "@ c #151515", "# c #161616", "$ c Gray9", "% c #32261e", "& c #2e2a22", "* c #36322e", "= c #363232", "- c #422e26", "; c #524636", ": c #5a4e36", "> c #5a4a3e", ", c #724e3a", "< c Gray31", "1 c #505050", "2 c #535353", "3 c #565252", "4 c Gray33", "5 c #565656", "6 c #585858", "7 c #5b5b5b", "8 c Gray37", "9 c #5f5f5f", "0 c #72664e", "q c #776a56", "w c #606060", "e c #626262", "r c Gray39", "t c Gray40", "y c #686868", "u c Gray41", "i c Gray42", "p c #6d6d6d", "a c Gray43", "s c #7e766b", "d c Gray44", "f c Gray45", "g c #747474", "h c #767676", "j c #777777", "k c Gray47", "l c #7b7b7b", "z c Gray", "x c #864a1e", "c c #9a4606", "v c #9e4a06", "b c #8e522a", "n c #8e5e36", "m c #965a3a", "M c #92622e", "N c #9a6636", "B c #a24e06", "V c #ae6232", "C c #ba7a3e", "Z c #877c6e", "A c #897960", "S c #c25e12", "D c #ca6206", "F c #ce6602", "G c #d66a06", "H c #da6e3e", "J c #f27e0e", "K c #e26a2e", "L c #908674", "P c #908675", "I c #938978", "U c #93897a", "Y c #998e7f", "T c #9d907d", "R c #a48f6f", "E c #b68a6a", "W c #b69e7a", "Q c #bc9d70", "! c #bd9f74", "~ c #bda176", "^ c #bda177", "/ c #bda27a", "( c #bea37b", ") c #f68606", "_ c #fa8606", "` c #fe8206", "' c #fe8602", "] c #fe8606", "[ c #fa820a", "{ c #fe8a02", "} c #fe8a06", "| c #fe9632", " . c #c28246", ".. c #ca825e", "X. c #da924e", "o. c #c68662", "O. c #ce8266", "+. c #ea8e5a", "@. c #e29a56", "#. c #ea9a6e", "$. c #faae5e", "%. c #eeb276", "&. c #808080", "*. c Gray51", "=. c #838383", "-. c #868686", ";. c #9d9382", ":. c #a39882", ">. c #a49985", ",. c #ac9d85", "<. c #aea28d", "1. c #afa38e", "2. c #b2a08a", "3. c #b2a38b", "4. c #bea680", "5. c #b9a688", "6. c #bfa885", "7. c #b8a88c", "8. c #beaa89", "9. c #bdaa8d", "0. c #bfab8d", "q. c #b2a690", "w. c #b5a593", "e. c #bbae9c", "r. c #bcb19c", "t. c #caae82", "y. c #c0b29b", "u. c #c8b79f", "i. c #d0ba9a", "p. c #c3b9a6", "a. c #c4bcac", "s. c #c3beb0", "d. c #c5bfb1", "f. c #f2b296", "g. c #f6b696", "h. c #c6c1b6", "j. c #c9c6bf", "k. c #d3c1a8", "l. c #dec6aa", "z. c #dbcbb1", "x. c #dacfbd", "c. c #e2caa2", "v. c #e0c9ae", "b. c #e4cca8", "n. c #e5cda9", "m. c #e6ceaa", "M. c #e7cfb3", "N. c #f6c6aa", "B. c #fecea6", "V. c #fed2b2", "C. c #fedaba", "Z. c #fedebe", "A. c #feeaae", "S. c #cfc9c2", "D. c Gray79", "F. c #d3ccc5", "G. c #d2cec8", "H. c #d3cfcf", "J. c Gray82", "K. c #d3d0d0", "L. c #d6d6d3", "P. c #d5d5d5", "I. c Gray84", "U. c #efe3d3", "Y. c #fee2c6", "T. c #fee6ca", "R. c #f2eada", "E. c #fae6d2", "W. c #feead2", "Q. c #f2eae2", "!. c #f6eee2", "~. c #f4ece4", "^. c #f7efe7", "/. c #f5f1e5", "(. c #f6f2e6", "). c #f7f3eb", "_. c #fef2e2", "`. c #faf2ea", "'. c #faf6ee", "]. c #f9f5f1", "[. c #faf6f6", "{. c #fafaf6", "}. c Gray98", "|. c #fefefa", " X c Gray99", ".X c #fefefe", "XX c None", /* pixels */ "XXXX-.-.=.z k h h d p u t e 9 7 7 2 2 b $.", "XXXX-.D.D.D.D.D.D.D.D.D.D.D.D.D.D.h.< b $.A.", "XXXX=.D..X.X.X.X.X.XI..X.X.X.X.X.Xs.b @.A.| ", "XXXX=.D..X.X.X.X.X.XI..X.X.X.X.X.Xn @.C.| } ", "XXXXz D..X.X.X.X.X.XI..X.X.X.X.XM @.C.| ` ' ", "XXXXk D.I.I.I.I.I.I.I.I.I.I.J.N @.B.| ` ' { ", "XXXXk D..X.X.X.X.X.XI..X.X.XC @.B.| _ ' ) G ", "XXXXh D..X.X.X.X.X.XI..X.X .X.B.| [ ' ) D B ", "XXXXd D..X.X.X.X.X.XI..Xg.%.B.| ' ] ) F v o ", "XXXXd D.I.I.I.I.I.I.I.g.Z.E.#.[ ' ) D v o ", "XXXXp D..X.X.X.X.X.XJ.B._.N.+.J [ F c o ", "XXXXu D..X.X.X.X.X].g.T.C.#.H K S c o ", "XXXXu D..X.X.X|.{.).B.W.g...V b x o $ ", "XXXXt D.I.I.L.H.G.g.Y.f...m b : o q $ ", "XXXXe D..X}.{.'.^.V.N.O.m : & * P A $ XX", "XXXXe D.|.[.`.^.0 E o., > * I T ,.R $ XXXX", "XXXX9 D.{.'./.t.0 % - 3 I ;.1.y.i.W + XXXXXX", "XXXX7 D.F.S.j.0 & = t.s P :.3.5.9.( o XXXXXX", "XXXX7 D./.!.U.; t.Y Z 1.u.z.M.b.c.^ X XXXXXX", "XXXX5 D.Q.R.U.x.e.w.>.k.v.b.b.c.l.! . XXXXXX", "XXXX2 h.d.a.p.r.q.3.7.9.8.6.4.( ^ Q XXXXXX", "XXXX XXXXXX" }; static const char *plotIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 3 1", " c Black", "@ c White", "- c Gray", /* pixels */ " ", " @@@@ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", "@----------@-------@@@", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @ @ ", " @@@@@ ", " ", " " }; static const char *geoIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 2 1", " c Black", "# c None", /* pixels */ " ", " ######## ######## ", " ####### ####### ", " ###### ###### ", " ######### ######### ", " ######### ######### ", " ######### ######### ", " ## ###### ###### ## ", " # ###### ###### # ", " ###### ###### ", " ", " ", " ###### ###### ", " # ###### ###### # ", " ## ###### ###### ## ", " ######### ######### ", " ######### ######### ", " ######### ######### ", " ###### ###### ", " ####### ####### ", " ######## ######## ", " " }; static const char *kspaceIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 16 1", " c black", ". c #111111", "X c #222222", "o c gray20", "O c #444444", "+ c #555555", "@ c gray40", "# c #777777", "$ c #888888", "% c gray60", "& c #aaaaaa", "* c #bbbbbb", "= c gray80", "- c #dddddd", "; c #eeeeee", ": c None", /* pixels */ ":::::::;*%##::::::::::", ":::::# #::::::::::", ":::::::O &::::::::::", ":::::::+ ;::::::::::", ":::::::X O:::::::::::", "::::::= #:::::::::::", "::::::$ *:::::::::::", "::::::O .::::::::::::", ":::::: +:%X X::::", ":::::& $:::X o*:::::", ":::::# =::& @:::::::", ":::::X X::*.$::::::::", "::::- @:% %:::::::::", "::::$ %@ ::::::::::", "::::+ . *:::::::::", "::::. # $:::::::::", ":::* #:. @:::::::::", ":::# *:+ X:::::::::", ":::o ::$ -:;+:::::", "::: +::- +;O*:::::", "::: $:::@ #::::::", ":::OOO-:::;O X$:::::::" }; static const char *visIcon[] = { /* columns rows colors chars-per-pixel */ "22 22 59 1", " c black", ". c #020202", "X c #040404", "o c gray3", "O c #090909", "+ c gray4", "@ c #0C0C0C", "# c gray5", "$ c gray7", "% c #151515", "& c #161616", "* c #1B1B1B", "= c #1E1E1E", "- c gray12", "; c #222222", ": c gray14", "> c #282828", ", c gray16", "< c #2D2D2D", "1 c #313131", "2 c #323232", "3 c #373737", "4 c #393939", "5 c #3A3A3A", "6 c gray23", "7 c gray24", "8 c #3F3F3F", "9 c #414141", "0 c #444444", "q c #484848", "w c #5D5D5D", "e c #606060", "r c gray43", "t c gray44", "y c #747474", "u c gray48", "i c #838383", "p c gray52", "a c #868686", "s c #888888", "d c gray54", "f c #8E8E8E", "g c #909090", "h c #929292", "j c #989898", "k c #9A9A9A", "l c #A5A5A5", "z c gray68", "x c #AFAFAF", "c c #B7B7B7", "v c #C1C1C1", "b c gray77", "n c #C5C5C5", "m c gray78", "M c gainsboro", "N c gray88", "B c #E4E4E4", "V c #EFEFEF", "C c None", /* pixels */ "CCCCCCCCCCCCCCCCCCCCCC", "CCCCCCCCCCCCCCCCCCCCCC", "CCCCCC11CCCCCCCCCCCCCC", "CCCCCC1w CCCCCCCCCCCCC", "CCCCCC1bw CCCCCCCCCCCC", "CCCCCC1bBw CCCCCCCCCCC", "CCCCCC c #B7B7B5", ", c #B8B8B6", "< c #B8B8B7", "1 c #BABAB8", "2 c #BBBBB9", "3 c #BBBBBA", "4 c #BCBCBB", "5 c #BDBDBB", "6 c #BEBEBC", "7 c #BEBEBD", "8 c #BFBFBD", "9 c #BFBFBE", "0 c #C0C0BF", "q c #C1C1BF", "w c #C1C1C0", "e c #C2C2C0", "r c #C3C3C2", "t c #C4C4C2", "y c #C5C5C4", "u c #C6C6C5", "i c #C7C7C5", "p c #C7C7C6", "a c #C8C8C7", "s c #C9C9C8", "d c #CACAC9", "f c #CBCBC9", "g c #CBCBCA", "h c #CCCCCB", "j c #CDCDCB", "k c #CDCDCC", "l c #CFCFCD", "z c #D0D0CF", "x c #D1D1D0", "c c #D3D3D2", "v c #D5D5D4", "b c #D6D6D5", "n c #D7D7D6", "m c #D8D8D7", "M c #DADAD9", "N c #DBDBDA", "B c #DDDDDC", "V c #DEDEDD", "C c #DFDFDE", "Z c #E0E0DF", "A c #E1E1E0", "S c #E2E2E1", "D c gray89", "F c #E5E5E4", "G c gray90", "H c #E8E8E7", "J c #E9E9E9", "K c #EAEAE9", "L c #EAEAEA", "P c #ECECEC", "I c #EFEFEE", "U c #EFEFEF", "Y c gray94", "T c #F3F3F3", "R c #F4F4F4", "E c gray97", "W c #F9F9F9", "Q c gray100", "! c None", /* pixels */ "!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!", "!! !!!", "! TTTTTLHD Nvzgp95, !!", "! RWWRTILF Nv..pr5, !!", "! RWQWRILF N.zg.95, !!", "! TRWWTILF B.zg.r5, !!", "! .TRTIIHD .vlgp.5> !!", "! .IUILLFZ .vlsp.5> !!", "! L.LLHFZZ.vzkpr9.& !!", "! . . . !!", "! B.ZZZNNm.zkpr95.* !!", "! NN.NNmm. gsp95,&. !!", "! vv.mvvl. sp99<&*. !!", "! zzz.ll.g p965,*#O !!", "! sgg.gg.p 965,*#+X !!", "! pppp..rr 5,>&#+XX !!", "! rr9rr995 ,>&#+XXX !!", "!! !!!", "!!!!!!!!!!!!!!!!!!!!!!", "!!!!!!!!!!!!!!!!!!!!!!" }; static const char * redIcon[] = { "18 18 188 2", " c #FFFFFF", ". c #C2B6B6", "+ c None", "@ c #523030", "# c #371515", "$ c #331515", "% c #473232", "& c #736868", "* c #BAB7B7", "= c #DBD0D0", "- c #754A4A", "; c #4A0F0F", "> c #490F0F", ", c #480F0F", "' c #440F0F", ") c #401010", "! c #3A1010", "~ c #331111", "{ c #2B1212", "] c #594D4D", "^ c #D2D1D1", "/ c #CAB5B5", "( c #591212", "_ c #590E0E", ": c #5A0D0D", "< c #5A0E0E", "[ c #580E0E", "} c #540E0E", "| c #4F0E0E", "1 c #411010", "2 c #391010", "3 c #2F1111", "4 c #281616", "5 c #B9B7B7", "6 c #DFD0D0", "7 c #631111", "8 c #660C0C", "9 c #690C0C", "0 c #6B0C0C", "a c #6A0C0C", "b c #680C0C", "c c #640D0D", "d c #5F0D0D", "e c #500E0E", "f c #460F0F", "g c #3C1010", "h c #311111", "i c #8E4848", "j c #700C0C", "k c #760B0B", "l c #790B0B", "m c #7B0B0B", "n c #780B0B", "o c #740B0B", "p c #6E0C0C", "q c #5D0D0D", "r c #530E0E", "s c #3D1010", "t c #301111", "u c #D3B5B5", "v c #800A0A", "w c #860A0A", "x c #8A0909", "y c #8B0909", "z c #880A0A", "A c #830A0A", "B c #7D0B0B", "C c #600D0D", "D c #3B1010", "E c #2D1111", "F c #AB6363", "G c #8E0909", "H c #950808", "I c #9A0808", "J c #9C0808", "K c #9B0808", "L c #980808", "M c #930909", "N c #820A0A", "O c #770B0B", "P c #510E0E", "Q c #361111", "R c #756868", "S c #972B2B", "T c #A40707", "U c #AA0707", "V c #AC0606", "W c #AC0707", "X c #A80707", "Y c #A10707", "Z c #990808", "` c #4C0F0F", " . c #4A3131", ".. c #940D0D", "+. c #9F0808", "@. c #B30606", "#. c #BA0505", "$. c #BD0505", "%. c #BC0505", "&. c #B70606", "*. c #B00606", "=. c #A50707", "-. c #8D0909", ";. c #7F0A0A", ">. c #710C0C", ",. c #620D0D", "'. c #9D0C0C", "). c #A90707", "!. c #B60606", "~. c #C10505", "{. c #C90404", "]. c #CD0404", "^. c #CC0404", "/. c #C60404", "(. c #B10606", "_. c #960808", ":. c #870A0A", "<. c #3C1414", "[. c #AF2828", "}. c #B20606", "|. c #C00505", "1. c #D80303", "2. c #DE0202", "3. c #DC0202", "4. c #D40303", "5. c #C80404", "6. c #6D0C0C", "7. c #4D0F0F", "8. c #573030", "9. c #C76060", "0. c #B80606", "a. c #C70404", "b. c #D70303", "c. c #E50202", "d. c #EE0101", "e. c #EB0101", "f. c #DF0202", "g. c #D00303", "h. c #910909", "i. c #846666", "j. c #E5B3B3", "k. c #CA0404", "l. c #DB0303", "m. c #FB0000", "n. c #F50000", "o. c #C40505", "p. c #A30707", "q. c #920909", "r. c #610D0D", "s. c #C5B6B6", "t. c #CA4343", "u. c #E70202", "v. c #F10101", "w. c #E10202", "x. c #D20303", "y. c #C20505", "z. c #A20707", "A. c #810A0A", "B. c #7B4A4A", "C. c #F0CECE", "D. c #C30909", "E. c #AD0606", "F. c #9E0808", "G. c #7E0A0A", "H. c #611111", "I. c #DCD0D0", "J. c #E9B3B3", "K. c #C50808", "L. c #D10303", "M. c #BF0505", "N. c #A60707", "O. c #970808", "P. c #6C1010", "Q. c #CDB5B5", "R. c #F1CECE", "S. c #CD4343", "T. c #BB0505", "U. c #8F0909", "V. c #964747", "W. c #E1D0D0", "X. c #E7B3B3", "Y. c #CC6060", "Z. c #B62828", "`. c #A60B0B", " + c #9E0C0C", ".+ c #A02A2A", "++ c #B16262", "@+ c #D6B4B4", "+ + + + + . @ @ # $ % & * + + + + + ", "+ + + = - ; > , ' ) ! ~ { ] ^ + + + ", "+ + / ( _ : < [ } | > 1 2 3 4 5 + + ", "+ 6 7 8 9 0 a b c d [ e f g h 4 ^ + ", "+ i j k l m m n o p 8 q r , s t ] + ", "u n v w x y y z A B o 0 C } , D E * ", "F w G H I J K L M y N O 0 d P ' Q R ", "S M J T U V W X Y Z G N k b : ` s .", "..+.U @.#.$.%.&.*.=.I -.;.>.,.r ' # ", "'.).!.~.{.].^./.$.(.T _.:.n b _ > <.", "[.}.|.].1.2.3.4.5.#.W J -.B 6.q 7.8.", "9.0.a.b.c.d.e.f.g.~.(.Y h.v j C | i.", "j.#.k.l.e.m.n.c.4.o.@.p.q.N >.r.e s.", "+ t.5.1.u.v.d.w.x.y.}.z.h.A.>.C B.+ ", "+ C.D.g.l.w.f.b.k.%.E.F.G G.p H.I.+ ", "+ + J.K.].L.g.{.M.@.N.O.z l P.Q.+ + ", "+ + + R.S.|.|.T.@.X J U.A.V.W.+ + + ", "+ + + + + X.Y.Z.`. +.+++@++ + + + + "}; static const char * greenIcon[] = { "18 18 192 2", " c #FFFFFF", ". c #B6C2B9", "+ c None", "@ c #305239", "# c #15371E", "$ c #15331D", "% c #324737", "& c #68736B", "* c #B7BAB7", "= c #D0DBD3", "- c #4A7556", "; c #0F4A1F", "> c #0F491E", ", c #0F481E", "' c #0F441D", ") c #10401D", "! c #103A1B", "~ c #11331A", "{ c #122B18", "] c #4D5950", "^ c #D1D2D1", "/ c #B5CABB", "( c #125924", "_ c #0E5922", ": c #0D5A22", "< c #0E5A22", "[ c #0E5821", "} c #0E5421", "| c #0E4F20", "1 c #10411D", "2 c #10391B", "3 c #112F19", "4 c #16281B", "5 c #B7B9B7", "6 c #D0DFD4", "7 c #116326", "8 c #0C6624", "9 c #0C6925", "0 c #0C6B25", "a c #0C6A25", "b c #0C6825", "c c #0D6424", "d c #0D5F23", "e c #0E5020", "f c #0F461E", "g c #103C1C", "h c #11311A", "i c #488E5B", "j c #0C7026", "k c #0B7628", "l c #0B7928", "m c #0B7B29", "n c #0B7828", "o c #0B7427", "p c #0C6E26", "q c #0D5D23", "r c #0E5321", "s c #103D1C", "t c #113019", "u c #B5D3BD", "v c #0A802A", "w c #0A862B", "x c #098A2C", "y c #098B2C", "z c #0A882B", "A c #0A832A", "B c #0B7D29", "C c #0D6023", "D c #103B1B", "E c #112D19", "F c #B7BAB8", "G c #63AB76", "H c #098E2D", "I c #08952E", "J c #089A2F", "K c #089C2F", "L c #089B2F", "M c #08982F", "N c #09932D", "O c #0A822A", "P c #0B7728", "Q c #0E5120", "R c #11361A", "S c #68756B", "T c #2B9747", "U c #07A431", "V c #07AA32", "W c #06AC33", "X c #07AC33", "Y c #07A832", "Z c #07A130", "` c #08992F", " . c #0F4C1F", ".. c #314A38", "+. c #0D9430", "@. c #089F30", "#. c #06B334", "$. c #05BA35", "%. c #05BD36", "&. c #05BC36", "*. c #06B735", "=. c #06B033", "-. c #07A531", ";. c #098D2C", ">. c #0A7F29", ",. c #0C7127", "'. c #0D6224", "). c #0E5320", "!. c #0C9D32", "~. c #07A932", "{. c #06B635", "]. c #05C137", "^. c #04C939", "/. c #04CD39", "(. c #04CC39", "_. c #04C638", ":. c #06B134", "<. c #08962E", "[. c #0A872B", "}. c #143C1F", "|. c #28AF4C", "1. c #06B234", "2. c #05C037", "3. c #03D83C", "4. c #02DE3D", "5. c #02DC3C", "6. c #03D43B", "7. c #04C838", "8. c #05BA36", "9. c #0C6D26", "0. c #0F4D1F", "a. c #30573A", "b. c #60C77C", "c. c #06B835", "d. c #04C738", "e. c #03D73B", "f. c #02E53E", "g. c #01EE40", "h. c #01EB40", "i. c #02DF3D", "j. c #03D03A", "k. c #09912D", "l. c #66846E", "m. c #B3E5C0", "n. c #04CA39", "o. c #03DB3C", "p. c #00FB43", "q. c #00F542", "r. c #05C437", "s. c #07A331", "t. c #09922D", "u. c #0D6123", "v. c #B6C5BA", "w. c #43CA67", "x. c #02E73F", "y. c #01F141", "z. c #02E13D", "A. c #03D23A", "B. c #05C237", "C. c #07A231", "D. c #0A812A", "E. c #4A7B57", "F. c #CEF0D7", "G. c #09C33A", "H. c #02E13E", "I. c #06AD33", "J. c #089E30", "K. c #0A7E29", "L. c #116126", "M. c #D0DCD3", "N. c #B3E9C1", "O. c #08C53B", "P. c #03D13A", "Q. c #05BF37", "R. c #07A631", "S. c #08972E", "T. c #106C28", "U. c #B5CDBB", "V. c #CEF1D7", "W. c #43CD68", "X. c #05BB36", "Y. c #098F2D", "Z. c #47965C", "`. c #D0E1D4", " + c #B3E7C1", ".+ c #60CC7D", "++ c #28B64E", "@+ c #0BA634", "#+ c #0C9E32", "$+ c #2AA049", "%+ c #62B177", "&+ c #B4D6BD", "+ + + + + . @ @ # $ % & * + + + + + ", "+ + + = - ; > , ' ) ! ~ { ] ^ + + + ", "+ + / ( _ : < [ } | > 1 2 3 4 5 + + ", "+ 6 7 8 9 0 a b c d [ e f g h 4 ^ + ", "+ i j k l m m n o p 8 q r , s t ] + ", "u n v w x y y z A B o 0 C } , D E F ", "G w H I J K L M N y O P 0 d Q ' R S ", "T N K U V W X Y Z ` H O k b : .s ..", "+.@.V #.$.%.&.*.=.-.J ;.>.,.'.).' # ", "!.~.{.].^./.(._.%.:.U <.[.n b _ > }.", "|.1.2./.3.4.5.6.7.8.X K ;.B 9.q 0.a.", "b.c.d.e.f.g.h.i.j.].:.Z k.v j C | l.", "m.$.n.o.h.p.q.f.6.r.#.s.t.O ,.u.e v.", "+ w.7.3.x.y.g.z.A.B.1.C.k.D.,.C E.+ ", "+ F.G.j.o.H.i.e.n.&.I.J.H K.p L.M.+ ", "+ + N.O./.P.j.^.Q.#.R.S.z l T.U.+ + ", "+ + + V.W.2.2.X.#.Y K Y.D.Z.`.+ + + ", "+ + + + + +.+++@+#+$+%+&++ + + + + "}; /* static const char *recoIcon[] = { "22 22 178 2", " c #000000", ". c #010101", "X c #020202", "o c #030303", "O c #040404", "+ c #050505", "@ c #060606", "# c #080808", "$ c #0A0A0A", "% c #0B0B0B", "& c #0F0F0F", "* c #101010", "= c #111111", "- c #131313", "; c #141414", ": c #151515", "> c #161616", ", c #181818", "< c #191919", "1 c #1A1A1A", "2 c #1B1B1B", "3 c #1C1C1C", "4 c #1D1D1D", "5 c #1E1E1E", "6 c #1F1F1F", "7 c #202020", "8 c #212121", "9 c #222222", "0 c #242424", "q c #252525", "w c #262626", "e c #272727", "r c #282828", "t c #292929", "y c #2B2B2B", "u c #2C2C2C", "i c #2D2D2D", "p c #2E2E2E", "a c #2F2F2F", "s c #303030", "d c #313131", "f c #323232", "g c #333333", "h c #363636", "j c #373737", "k c #393939", "l c #3A3A3A", "z c #3C3C3C", "x c #3D3D3D", "c c #3E3E3E", "v c #3F3F3F", "b c #404040", "n c #414141", "m c #424242", "M c #434343", "N c #444444", "B c #454545", "V c #464646", "C c #474747", "Z c #484848", "A c #494949", "S c #4A4A4A", "D c #4C4C4C", "F c #4D4D4D", "G c #4E4E4E", "H c #4F4F4F", "J c #505050", "K c #515151", "L c #525252", "P c #535353", "I c #545454", "U c #555555", "Y c #575757", "T c #585858", "R c #595959", "E c #5A5A5A", "W c #5B5B5B", "Q c #5C5C5C", "! c #5D5D5D", "~ c #5F5F5F", "^ c #606060", "/ c #616161", "( c #626262", ") c #636363", "_ c #646464", "` c #656565", "' c #666666", "] c #676767", "[ c #686868", "{ c #696969", "} c #6A6A6A", "| c #6B6B6B", " . c #6C6C6C", ".. c #6D6D6D", "X. c #6E6E6E", "o. c #6F6F6F", "O. c #707070", "+. c #717171", "@. c #727272", "#. c #737373", "$. c #747474", "%. c #767676", "&. c #777777", "*. c #787878", "=. c #797979", "-. c #7A7A7A", ";. c #7B7B7B", ":. c #7C7C7C", ">. c #7D7D7D", ",. c #7E7E7E", "<. c #7F7F7F", "1. c #808080", "2. c #818181", "3. c #828282", "4. c #838383", "5. c #848484", "6. c #858585", "7. c #868686", "8. c #878787", "9. c #888888", "0. c #898989", "q. c #8A8A8A", "w. c #8C8C8C", "e. c #8D8D8D", "r. c #8F8F8F", "t. c #909090", "y. c #929292", "u. c #939393", "i. c #959595", "p. c #969696", "a. c #979797", "s. c #989898", "d. c #999999", "f. c #9A9A9A", "g. c #9B9B9B", "h. c #9C9C9C", "j. c #9E9E9E", "k. c #9F9F9F", "l. c #A2A2A2", "z. c #A3A3A3", "x. c #A4A4A4", "c. c #A5A5A5", "v. c #A6A6A6", "b. c #A7A7A7", "n. c #A8A8A8", "m. c #A9A9A9", "M. c #AAAAAA", "N. c #ABABAB", "B. c #ACACAC", "V. c #ADADAD", "C. c #AEAEAE", "Z. c #AFAFAF", "A. c #B0B0B0", "S. c #B1B1B1", "D. c #B2B2B2", "F. c #B4B4B4", "G. c #B5B5B5", "H. c #B6B6B6", "J. c #B7B7B7", "K. c #BABABA", "L. c #BBBBBB", "P. c #BDBDBD", "I. c #BEBEBE", "U. c #C1C1C1", "Y. c #C2C2C2", "T. c #C3C3C3", "R. c #C6C6C6", "E. c #C7C7C7", "W. c #C8C8C8", "Q. c #C9C9C9", "!. c #CECECE", "~. c #D0D0D0", "^. c #D1D1D1", "/. c #DDDDDD", "(. c #DEDEDE", "). c #F0F0F0", "_. c #F4F4F4", "`. c gray100", " O % ; 1 1 ; = O ", " & e r f f e e f f f 6 ", " e l a a a l e 6 e r a n l & ", " j B a C / L B c 8 e 8 f f B C % ", " 8 B r E ,.| | U C C l c C L B L C ", "O j 6 f O.,.%.%.` L ` Q L E / %.c C = ", "; e e B E ..O.2.c.C.F.F.b.%.,.7.a r 8 ", "e = j ..=.,.r.Y.Y.Y.b.2.W.i.f.7.8 C 6 ", "e 1 U 2.,.O.R.~.9.F.R.z.f.c.` 8 & ` f O ", "6 e O.7.,.E 9.b.P.(.C.f.b.C ; ; c U D C f ; ", "8 l ,.9.=.=.| O.(._.9.Q ..; r / %.E n E =.B ", "e l | 2...r.Z.f.~.`.F...j n =.O.%.D B ` D ; ", "r 8 B ` O.f.Y...c.).i.` 9.=.....L B Q i.=.6 ", "1 r f L ` f.C.=.C.W.U 7.Z.7.O.C.i.=.,.Q r.L ", "O n a e D %.2.,.2.j.2.Z.P.W.!.Y.z.F.F.O.2.=.", " 8 7.O.E n a f n E f.Z.b.F.R.j.r.r.j...r.f ", " r ,.c.9.=.7.i.=.` O.,.z.Y.f.f.C.W.%.P.` ", " O D J.r.C.9.O.%./ ,.f.F.9.r.Y.W.b.!.O.", " Q i.7.=.,.r.Q | | =.9.i.b.P.f.| 1 ", " & ,.%.2.=.f./ U E L ,.i./ j 6 ", " O E %.Q %.r.O...Q U i.U O ", " O n ` Q | ,.U E =.E =.1 " }; */ odin-1.8.5/odin/odinplot.cpp0000644000175000017500000012164711363773556012717 00000000000000#include // for QMouseEvent #include // for connecting signals #include #include "odinplot.h" #include "odinplot_range.h" #include "odindialog_progress.h" #include "odincomp.h" #include #include #include static const char *rectIcon[] = { "22 22 3 1", " c black", "# c white", "+ c yellow", /* pixels */ " # ", " ++++++++###+++++++++ ", " + ##### + ", " + # + ", " + # + ", " + # + ", " + # + ", " + # + ", " +# # #+ ", " ## # ## ", "######################", " ## # ## ", " +# # #+ ", " + # + ", " + # + ", " + # + ", " + # + ", " + # + ", " + # + ", " + ##### + ", " ++++++++###+++++++++ ", " # " }; static const char *hortIcon[] = { "22 22 3 1", " c black", "# c white", "+ c yellow", /* pixels */ " ", " + + ", " + + ", " + + ", " + + ", " + + ", " + + ", " + + ", " +# #+ ", " ## ## ", "######################", " ## ## ", " +# #+ ", " + + ", " + + ", " + + ", " + + ", " + + ", " + + ", " + + ", " + + ", " " }; static const char *vertIcon[] = { "22 22 3 1", " c black", "# c white", "+ c yellow", /* pixels */ " # ", " ++++++++###+++++++++ ", " ##### ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " # ", " ##### ", " ++++++++###+++++++++ ", " # " }; ////////////////////////////////////////////// /////////////////////////////////////////////// PlotView::PlotView(const char* method, const STD_string& nucleus, GuiMainWindow* parent ) : QWidget(parent->get_widget()), nuc(nucleus) { Log odinlog("PlotView","PlotView"); int iplot; for(iplot=0; iplotget_plot_data(); if(!plotdata) { ODINLOG(odinlog,errorLog) << "Unable to get plot_data" << STD_endl; return; } ODINLOG(odinlog,normalDebug) << "plotdata->n_frames()=" << plotdata->n_frames() << STD_endl; totaldur=plotdata->get_total_duration(); double min_x_cache=0.0; double max_x_cache=totaldur; if(max_x_cache>MAX_START_RANGE) max_x_cache=MAX_START_RANGE; ODINLOG(odinlog,normalDebug) << "min_x_cache/max_x_cache/totaldur=" << min_x_cache << "/" << max_x_cache << "/" << totaldur << STD_endl; baseline_x[0]=0.0; baseline_x[1]=totaldur; baseline_y[0]=0.0; baseline_y[1]=0.0; for(iplot=0; iplothas_curves_on_channel(plotChannel(iplot)); // default visibility if(iplot==B1re_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot0(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot0(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot0(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot0(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot0()), autoscale_txt); } if(iplot==B1im_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot1(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot1(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot1(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot1(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot1()), autoscale_txt); } if(iplot==rec_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot2(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot2(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot2(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot2(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot2()), autoscale_txt); cbon=false; // override visibilty } if(iplot==signal_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot3(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot3(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot3(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot3(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot3()), autoscale_txt); } if(iplot==freq_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot4(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot4(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot4(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot4(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot4()), autoscale_txt); } if(iplot==phase_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot5(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot5(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot5(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot5(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot5()), autoscale_txt); } if(iplot==Gread_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot6(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot6(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot6(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot6(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot6()), autoscale_txt); } if(iplot==Gphase_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot7(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot7(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot7(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot7(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot7()), autoscale_txt); } if(iplot==Gslice_plotchan) { connect( plotter[iplot], SIGNAL(plotMouseMoved(const QMouseEvent&)), SLOT(mouseMovedInPlot8(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot8(const QMouseEvent&)) ); connect( plotter[iplot], SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot8(const QMouseEvent&)) ); connect( wheel [iplot], SIGNAL(valueChanged(double)), SLOT(rescalePlot8(double)) ); // autoscalebutton[iplot]=new GuiButton(this, this, SLOT(autoscalePlot8()), autoscale_txt); } plotflag[iplot]=new GuiToolButton(chan_toolbar, 0, "", this, SLOT(hide_and_show()), true, cbon ); grid->add_widget( plotter[iplot]->get_widget(), iplot, 0); grid->add_widget( wheel[iplot]->get_widget(), iplot, 1); // grid->add_widget( autoscalebutton[iplot]->get_widget(), iplot, 2); } // canvas_framewidth=plotter[0]->canvas()->lineWidth(); // ODINLOG(odinlog,normalDebug) << "canvas_framewidth=" << canvas_framewidth << STD_endl; x_range=new RangeWidget(0.0,totaldur,min_x_cache,max_x_cache,this); connect( x_range, SIGNAL(new_range()),this, SLOT(update_x_axes()) ); grid->add_widget( x_range, numof_plotchan, 0, GuiGridLayout::Default, 1, 2); chan_toolbar->add_separator(); svector modelabel; modelabel.resize(numof_tcmodes); for(int imode=0; imodeset_current_item(tcmode_curves); oldmode=tcmode_curves; connect( plotmode->get_widget(), SIGNAL(activated(int)),this, SLOT(changeMode(int)) ); chan_toolbar->add_separator(); oscibutton=new GuiToolButton(chan_toolbar, 0, "Osci", this, SLOT(osci())); oscibutton->set_tooltip("Triggered oscilloscope"); printbutton=new GuiToolButton(chan_toolbar, 0, "Print", this, SLOT(print())); printbutton->set_tooltip("Print sequence plot"); savebutton=new GuiToolButton(chan_toolbar, 0, "Save", this, SLOT(save())); savebutton->set_tooltip("Save sequence plot as multi-column ASCII file"); closebutton=new GuiToolButton(chan_toolbar, 0, "Close", this, SLOT(close())); closebutton->set_tooltip("Close sequence plot"); plotAxes =new GuiToolButton(settings_toolbar, 0, "Axes", this, SLOT(settingsChanged()), true, true ); plotMarkers=new GuiToolButton(settings_toolbar, 0, "Markers", this, SLOT(settingsChanged()), true, false ); plotGrid =new GuiToolButton(settings_toolbar, 0, "Grid", this, SLOT(settingsChanged()), true, true ); for(int i=exttrigger_marker; i odinlog("PlotView","~PlotView()"); ODINLOG(odinlog,normalDebug) << "mem(pre )=" << Profiler::get_memory_usage() << STD_endl; plotdata->reset(); // free memory ODINLOG(odinlog,normalDebug) << "mem(post)=" << Profiler::get_memory_usage() << STD_endl; for(unsigned int iplot=0; iplot odinlog("PlotView","close()"); ODINLOG(odinlog,normalDebug) << "mem(pre )=" << Profiler::get_memory_usage() << STD_endl; plotdata->reset(); // free memory ODINLOG(odinlog,normalDebug) << "mem(post)=" << Profiler::get_memory_usage() << STD_endl; emit closeMe(); } void PlotView::changeMode(int newmode) { Log odinlog("PlotView","changeMode"); for(int iplot=0; iplotclear(); } if(newmode>tcmode_curves) { ODINLOG(odinlog,normalDebug) << "Creating timecourse for mode " << newmode << STD_endl; if(!create_timecourses(timecourseMode(newmode))) newmode=oldmode; } if(newmode==tcmode_curves) { ODINLOG(odinlog,normalDebug) << "Creating & Plotting curves" << STD_endl; create_plotcurves_and_markers(); } else { ODINLOG(odinlog,normalDebug) << "Plotting timecourse" << STD_endl; plot_timecourses(timecourseMode(newmode)); } plotmode->set_current_item(newmode); change_toolbar(); set_plot_labels(); bool do_autoscale=true; if(newmode==tcmode_plain && oldmode==tcmode_curves) do_autoscale=false; if(oldmode==tcmode_plain && newmode==tcmode_curves) do_autoscale=false; if(do_autoscale) { autoscale_y(Gread_plotchan); autoscale_y(Gphase_plotchan); autoscale_y(Gslice_plotchan); } replot(); oldmode=timecourseMode(newmode); } void PlotView::change_toolbar() { if(plotmode->get_current_item()==tcmode_curves) { savebutton->set_enabled(false); plotflag[freq_plotchan]->set_enabled(false); plotflag[phase_plotchan]->set_enabled(false); } else { savebutton->set_enabled(true); plotflag[freq_plotchan]->set_enabled(true); plotflag[phase_plotchan]->set_enabled(true); } } void PlotView::create_baseline() { int iplot; for(iplot=0; iplotinsert_curve(false, false, true); plotter[iplot]->set_curve_data(curveid_baseline[iplot],baseline_x,baseline_y,2); } } void PlotView::add_plotcurve(const Curve4Qwt& curve) { double minx=x_range->get_min(); double maxx=x_range->get_max(); if(curve.x[curve.size-1]>=minx && curve.x[0]<=maxx) { long curveid=plotter[curve.channel]->insert_curve(false,curve.spikes); curves_map[curve.channel][curveid]=curve; plotter[curve.channel]->set_curve_data(curveid,curve.x,curve.y,curve.size); } } void PlotView::create_plotcurves() { Log odinlog("PlotView","create_plotcurves"); int iplot; for(iplot=0; iplotclear(); curves_map[iplot].clear(); } create_baseline(); STD_list::const_iterator curves_begin; STD_list::const_iterator curves_end; STD_list::const_iterator curvit; plotdata->get_curves(curves_begin,curves_end,x_range->get_min(),x_range->get_max(),MAX_HIGHRES_INTERVAL); for(curvit=curves_begin; curvit!=curves_end; ++curvit) { add_plotcurve(*curvit); } plotdata->get_signal_curves(curves_begin, curves_end, x_range->get_min(), x_range->get_max()); for(curvit=curves_begin; curvit!=curves_end; ++curvit) { add_plotcurve(*curvit); } set_curve_pens(); } void PlotView::add_marker(const Marker4Qwt& marker) { Log odinlog("PlotView","add_marker"); double minx=x_range->get_min(); double maxx=x_range->get_max(); if(marker.x>=minx && marker.x<=maxx) { for(int iplot=0; iplotinsert_marker(marker.label,marker.x); } } } void PlotView::add_tc_marker(const TimecourseMarker4Qwt& marker) { double minx=x_range->get_min(); double maxx=x_range->get_max(); if(marker.x>=minx && marker.x<=maxx) { for(int iplot=0; iplotinsert_marker(ftos(marker.y[iplot]).c_str(),marker.x); } } } void PlotView::create_markers() { Log odinlog("PlotView","create_markers"); for(int iplot=0; iplotremove_markers(); if(!plotMarkers->is_on()) return; if((x_range->get_max()-x_range->get_min())>MAX_MARKER_INTERVAL) return; timecourseMode type=timecourseMode(plotmode->get_current_item()); if(type==tcmode_curves) { STD_list::const_iterator markers_begin; STD_list::const_iterator markers_end; plotdata->get_markers(markers_begin,markers_end,x_range->get_min(),x_range->get_max()); for(STD_list::const_iterator markit=markers_begin; markit!=markers_end; ++markit) { add_marker(*markit); } } else { STD_list::const_iterator tc_markers_begin; STD_list::const_iterator tc_markers_end; plotdata->get_timecourse_markers(type,tc_markers_begin,tc_markers_end,x_range->get_min(),x_range->get_max()); for(STD_list::const_iterator tc_markit=tc_markers_begin; tc_markit!=tc_markers_end; ++tc_markit) { add_tc_marker(*tc_markit); } } } void PlotView::create_plotcurves_and_markers() { create_plotcurves(); create_markers(); } void PlotView::plot_timecourses(timecourseMode type) { double min=x_range->get_min(); double max=x_range->get_max(); const SeqTimecourseData* subtimecourse=plotdata->get_subtimecourse(type,min, max); if(!subtimecourse) return; bool symbols=( (max-min) < PLOT_SYMBOLS_MAX_RANGE ); for(int iplot=0; iplotclear(); timecourse_curve_id[type][iplot]=plotter[iplot]->insert_curve(false,false); plotter[iplot]->set_curve_data(timecourse_curve_id[type][iplot],subtimecourse->x,subtimecourse->y[iplot],subtimecourse->size,symbols); } set_curve_pens(); create_markers(); } bool PlotView::create_timecourses(timecourseMode type) { Log odinlog("PlotView","create_timecourses"); bool do_plot=true; bool first_time=false; if(!plotdata->timecourse_created(type)) { ProgressDisplayDialog display(this); ProgressMeter progmeter(display); progmeter.new_task(plotdata->n_frames(),"Generating timecourse"); try { plotdata->create_timecourses(type,nuc,&progmeter); } catch(OdinCancel) { ODINLOG(odinlog,normalDebug) << " aborted" << STD_endl; do_plot=false; } display.finish(); first_time=true; } if(do_plot && first_time) { ODINLOG(odinlog,normalDebug) << "autoscaling freq/phase" << STD_endl; autoscale_y(freq_plotchan); autoscale_y(phase_plotchan); } return do_plot; } void PlotView::plot_all() { autoscale_x(); autoscale_all_y(); } void PlotView::autoscale_x() { set_range_and_update_x_axes(0.0,totaldur); replot(); } void PlotView::set_range_and_update_x_axes(double min, double max, bool discard_scrollbar) { x_range->set_range(min,max,discard_scrollbar); update_x_axes(); } void PlotView::autoscale_all_y() { for(int iplot=0; iplot odinlog("PlotView","autoscale_y"); double maxBound; plotter[iplot]->autoscale_y(maxBound); ODINLOG(odinlog,normalDebug) << "maxBound[" << iplot << "]=" << maxBound << STD_endl; wheel[iplot]->set_range(0.01*maxBound,10.0*maxBound); wheel[iplot]->set_value(maxBound); } void PlotView::rescale_y(int iplot, double val) { plotter[iplot]->rescale_y(val); } double PlotView::get_x(int iplot, int x_pixel) {return plotter[iplot]->get_x(x_pixel);} double PlotView::get_y(int iplot, int y_pixel) {return plotter[iplot]->get_y(y_pixel);} void PlotView::mouseMovedInPlot(int iplot, const QMouseEvent& e) { Log odinlog("PlotView","mouseMovedInPlot"); double xpos=get_x(iplot,e.x()); double ypos=get_y(iplot,e.y()); STD_string msg("x="+ftos(xpos)+"\t "+"y="+ftos(ypos)); if(plotmode->get_current_item()==tcmode_curves) { int dist; closest=plotter[iplot]->closest_curve(e.x(),e.y(),dist); // check whether we have a valid plotting curve for(int i=0; i=CLOSEST_CURVE_MAX) closest=0; bool do_replot=true; if(left_button(&e,true)) do_replot=false; ODINLOG(odinlog,normalDebug) << "closest/dist=" << closest << "/" << dist << STD_endl; // remove highlighting from last curve bool different_plot= (lastplot_closest!=iplot); bool different_curve=(lastcurve_closest!=closest); if(lastcurve_closest>0 && (different_plot || different_curve) ) { ODINLOG(odinlog,normalDebug) << "removing highlighting from last curve #" << lastcurve_closest << STD_endl; plotter[lastplot_closest]->highlight_curve(lastcurve_closest,false); if(do_replot) plotter[lastplot_closest]->replot(); } if(closest) { msg+="\t "; const char* curve_label=curves_map[iplot][closest].label; if(curve_label) msg+=curve_label; if(curves_map[iplot][closest].has_freq_phase) { msg+="\t "; msg+="freq="+ftos(curves_map[iplot][closest].freq)+ODIN_FREQ_UNIT; msg+="\t "; msg+="phase="+ftos(curves_map[iplot][closest].phase)+ODIN_ANGLE_UNIT; } if(curves_map[iplot][closest].gradmatrix) { msg+="\t "; msg+="gradmatrix="+curves_map[iplot][closest].gradmatrix->print(); } // highlight closest curve if(closest!=lastcurve_closest) { ODINLOG(odinlog,normalDebug) << "highlighting closest curve #" << closest << STD_endl; plotter[iplot]->highlight_curve(closest,true); if(do_replot) plotter[iplot]->replot(); } } lastplot_closest=iplot; lastcurve_closest=closest; } setMessage(msg.c_str()); } #define IMPOSSIBLE_PIXELVAL -100000 void PlotView::mousePressedInPlot (int iplot, const QMouseEvent& e) { Log odinlog("PlotView","mousePressedInPlot"); markid_vertzoom=0; markid_hortzoom=0; // for some reason, mouse release event is issued twice on MacOS/Qt4/qwt5 so we will process only matched mouse press-release events x_pressed=IMPOSSIBLE_PIXELVAL; y_pressed=IMPOSSIBLE_PIXELVAL; ODINLOG(odinlog,normalDebug) << "iplot=" << iplot << STD_endl; if(left_button(&e,false)) { ODINLOG(odinlog,normalDebug) << "left_button" << STD_endl; // plotter[iplot]->enable_outline(true); plot_pressed=iplot; x_pressed=e.x(); y_pressed=e.y(); if(zoomflag[horizontal]->is_on()) { markid_hortzoom=plotter[iplot]->insert_marker("",get_x(iplot,x_pressed),true,false); plotter[iplot]->replot(); } if(zoomflag[vertical]->is_on()) { markid_vertzoom=plotter[iplot]->insert_marker("",get_y(iplot,y_pressed),true,true); plotter[iplot]->replot(); } ODINLOG(odinlog,normalDebug) << "markid_hortzoom/markid_vertzoom=" << markid_hortzoom << "/" << markid_vertzoom << STD_endl; } if(right_button(&e,false)) { ODINLOG(odinlog,normalDebug) << "right_button" << STD_endl; // plotter[iplot]->enable_outline(false); GuiPopupMenu pm(this); pm.insert_item("Display All", this, SLOT(plot_all())); pm.insert_item("Autoscale x-Axis", this, SLOT(autoscale_x())); if(iplot==0) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot0())); if(iplot==1) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot1())); if(iplot==2) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot2())); if(iplot==3) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot3())); if(iplot==4) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot4())); if(iplot==5) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot5())); if(iplot==6) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot6())); if(iplot==7) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot7())); if(iplot==8) pm.insert_item("Autoscale y-Axis", this, SLOT(autoscalePlot8())); pm.insert_item("Refresh Plot", this, SLOT(replot())); if(closest) { iplot_cache=iplot; if(plotmode->get_current_item()==tcmode_curves) { pm.insert_item(("Save Curve \'"+STD_string(curves_map[iplot_cache][closest].label)+"\'").c_str(), this, SLOT(save_closest_curve_data())); } else { STD_string chanlabel, chanunit; get_plot_label(iplot, chanlabel, chanunit); pm.insert_item(("Save Channel \'"+chanlabel+"\'").c_str(), this, SLOT(save_current_channel_data())); } } ODINLOG(odinlog,normalDebug) << "e.pos=" << e.pos().x() << "/" << e.pos().y() << STD_endl; QPoint pos=plotter[iplot]->get_widget()->mapToGlobal(e.pos()); ODINLOG(odinlog,normalDebug) << "pos=" << pos.x() << "/" << pos.y() << STD_endl; pm.popup(pos); } } void PlotView::mouseReleasedInPlot(int iplot, const QMouseEvent& e) { Log odinlog("PlotView","mouseReleasedInPlot"); if(left_button(&e,false) && iplot==plot_pressed) { if(x_pressed!=IMPOSSIBLE_PIXELVAL && y_pressed!=IMPOSSIBLE_PIXELVAL) { int x_released=e.x(); int y_released=e.y(); int low_x=x_pressed; if(x_releasedupp_x) upp_x=x_released; int upp_y=y_pressed; if(y_released>upp_y) upp_y=y_released; ODINLOG(odinlog,normalDebug) << "low_x/low_y/upp_x/upp_y(" << iplot << ")=" << low_x << "/" << low_y << "/" << upp_x << "/" << upp_y << STD_endl; double y_axis_low=get_y(iplot,upp_y); double y_axis_upp=get_y(iplot,low_y); double x_axis_low=get_x(iplot,low_x); double x_axis_upp=get_x(iplot,upp_x); if(x_axis_lowis_on()) {rescale_y=true; rescale_x=true;} if(zoomflag[horizontal]->is_on()) {rescale_x=true;} if(zoomflag[vertical]->is_on()) {rescale_y=true;} if(rescale_y) plotter[iplot]->set_y_axis_scale(y_axis_low,y_axis_upp); if(rescale_x) set_range_and_update_x_axes(x_axis_low,x_axis_upp); } } if(markid_vertzoom) plotter[iplot]->remove_marker(markid_vertzoom); if(markid_hortzoom) plotter[iplot]->remove_marker(markid_hortzoom); replot(); } // reset x_pressed=IMPOSSIBLE_PIXELVAL; y_pressed=IMPOSSIBLE_PIXELVAL; markid_vertzoom=0; markid_hortzoom=0; } void PlotView::update_x_axes() { Log odinlog("PlotView","update_x_axes"); int iplot; if(plotmode->get_current_item()==tcmode_curves) { create_plotcurves_and_markers(); } else { timecourseMode type=timecourseMode(plotmode->get_current_item()); plot_timecourses(type); } for(iplot=0; iplotset_x_axis_scale(x_range->get_min(),x_range->get_max()); } replot(); } void PlotView::get_plot_label(int iplot, STD_string& label, STD_string& unit) const { STD_string gradunit(timecourseUnit[plotmode->get_current_item()]); STD_string gradprefix(timecoursePrefix[plotmode->get_current_item()]); if(iplot==B1re_plotchan) {label="B1re"; unit=ODIN_FIELD_UNIT;} if(iplot==B1im_plotchan) {label="B1im"; unit=ODIN_FIELD_UNIT;} if(iplot==rec_plotchan) {label="Rec"; unit="";} if(iplot==signal_plotchan) {label="Signal"; unit="";} if(iplot==freq_plotchan) {label="Freq"; unit=ODIN_FREQ_UNIT;} if(iplot==phase_plotchan) {label="Phase"; unit=ODIN_ANGLE_UNIT;} if(iplot==Gread_plotchan) {label=gradprefix+"read"; unit=gradunit;} if(iplot==Gphase_plotchan) {label=gradprefix+"phase"; unit=gradunit;} if(iplot==Gslice_plotchan) {label=gradprefix+"slice"; unit=gradunit;} } void PlotView::set_plot_labels(bool extra_space) { if(plotAxes->is_on()) { STD_string cbtext; STD_string plotunit; for(int iplot=0; iplotset_label(cbtext.c_str()); STD_string axtitle(cbtext); if(plotunit!="")axtitle+=" ["+plotunit+"]"; if(extra_space) axtitle+="\n\n\n\n"; plotter[iplot]->set_y_axis_label(axtitle.c_str()); } } } void PlotView::set_curve_pens(bool thick_lines) { int cpen_width=1; int bpen_width=1; if(thick_lines) { cpen_width=3; bpen_width=2; } for(unsigned iplot=0; iplotget_current_item()==tcmode_curves) { for(STD_map::const_iterator it=curves_map[iplot].begin(); it!=curves_map[iplot].end(); ++it) { plotter[iplot]->set_curve_pen(it->first,_ARRAY_FOREGROUND_COLOR1_,cpen_width); } if(curveid_baseline[iplot]) plotter[iplot]->set_curve_pen(curveid_baseline[iplot],_ARRAY_FOREGROUND_COLOR2_,bpen_width); } else { for(unsigned itc=0; itcset_curve_pen(timecourse_curve_id[itc][iplot],_ARRAY_FOREGROUND_COLOR1_,cpen_width); } } } } void PlotView::hide_and_show() { int lastplot=-1; for(int iplot=0; iplotis_on()) { plotter[iplot]->get_widget()->show(); wheel[iplot]->get_widget()->show(); // autoscalebutton[iplot]->get_widget()->show(); lastplot=iplot; grid->set_row_stretch(iplot,100); } else { plotter[iplot]->get_widget()->hide(); wheel[iplot]->get_widget()->hide(); // autoscalebutton[iplot]->get_widget()->hide(); grid->set_row_stretch(iplot,0); } plotter[iplot]->set_x_axis_label("",true); } // add axis label Time to last plotter if(lastplot>=0) { STD_string axtitle(STD_string("Time [")+ODIN_TIME_UNIT+"]"); plotter[lastplot]->set_x_axis_label(axtitle.c_str()); } if(lastplot_old!=lastplot) { if(lastplot_old>=0) plotter[lastplot_old]->replot(); if(lastplot>=0) plotter[lastplot]->replot(); } lastplot_old=lastplot; } void PlotView::set_zoom_tool(zoomMode mode) { for(int imode=0; imodeset_on(true); else zoomflag[imode]->set_on(false); } int iplot; if(zoomflag[rect]->is_on()) for(iplot=0; iplotset_rect_outline_style(); if(zoomflag[horizontal]->is_on()) for(iplot=0; iplotset_line_outline_style(false); if(zoomflag[vertical]->is_on()) for(iplot=0; iplotset_line_outline_style(true); } void PlotView::replot() { Log odinlog("PlotView","replot"); for(int iplot=0; iplotisOn())*/ plotter[iplot]->replot(); } } const SeqTimecourseData* PlotView::get_timecourses() { if(!create_timecourses(tcmode_plain)) return 0; return plotdata->get_timecourse(tcmode_plain); } const SeqTimecourseData* PlotView::get_kspace_trajs() { if(!create_timecourses(tcmode_kspace)) return 0; return plotdata->get_timecourse(tcmode_kspace); } bool PlotView::simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter) { SeqSimFeedbackAbstract* feedback=0; VtkMagnPlotter magplot; // put it on stack so it gets deleted automatically on Cancel if(plotdata->monitor_simulation()) { active_magplot=&magplot; magplot.start(); feedback=this; ipage=-1; // trigger page zoom on first call of plot_vector } else active_magplot=0; if(!plotdata->simulate(fidfile,samplefile,progmeter,feedback)) return false; plotflag[signal_plotchan]->set_on(true); // make signal plotter visible create_plotcurves_and_markers(); // update to show simulated signal autoscale_y(signal_plotchan); hide_and_show(); // plotter[signal_plotchan]->replot(); return true; } void PlotView::plot_vector(double timepoint, float M[3], float* dM) { int iplot; if(active_magplot) { active_magplot->plot_vector(M,dM); bool change_page=false; while( ipage < int(timepoint/MAGN_PLOT_PAGE_DURATION) ) { ipage++; change_page=true; } if(change_page) { set_range_and_update_x_axes(ipage*MAGN_PLOT_PAGE_DURATION,(ipage+1)*MAGN_PLOT_PAGE_DURATION); for(iplot=0; iplotinsert_marker("Simulation",timepoint,false,false,true); } } for(iplot=0; iplotset_marker_pos(markid_magplot,timepoint); } replot(); } } void PlotView::settingsChanged() { for(int iplot=0; iplotenable_axes(plotAxes->is_on()); plotter[iplot]->enable_grid(plotGrid->is_on()); } create_markers(); replot(); } void PlotView::save_closest_curve_data() { if(!closest) return; STD_string fname=get_save_filename("Save Curve as ASCII", "", "", this); if(fname=="") return; STD_ofstream file(fname.c_str()); const Curve4Qwt& closcurve=curves_map[iplot_cache][closest]; if(!closcurve.size) return; double x0=closcurve.x[0]; // substract base time point to avoid round-off errors for(int i=0; iget_current_item()); if(!create_timecourses(type)) return; const SeqTimecourseData* timecourse=plotdata->get_timecourse(type); if(!timecourse) return; STD_string fname=get_save_filename("Save channel as ASCII", "", "", this); if(fname=="") return; STD_ofstream file(fname.c_str()); for(unsigned int i=0; isize; i++) { file << timecourse->x[i] << "\t" << timecourse->y[iplot_cache][i] << "\n"; } file.close(); } void PlotView::osci() { Log odinlog("PlotView","osci"); JcampDxBlock oscisettings("Settings for Oscilloscope"); oscisettings.append(TriggerType); oscisettings.append(TriggerWidth); oscisettings.append(RefreshRate); JDXwidgetDialog* dlg=new JDXwidgetDialog(oscisettings,1,this,true); markType marktype=markType(int(TriggerType)); timecourseMode tc_mode=timecourseMode(plotmode->get_current_item()); dvector timepoints; if(tc_mode==tcmode_curves) { STD_list::const_iterator markers_begin; STD_list::const_iterator markers_end; plotdata->get_markers(markers_begin,markers_end,0.0,totaldur); for(STD_list::const_iterator it=markers_begin; it!=markers_end; ++it) { if(it->type==marktype) timepoints.push_back(it->x); } } else { STD_list::const_iterator tc_markers_begin; STD_list::const_iterator tc_markers_end; plotdata->get_timecourse_markers(tc_mode,tc_markers_begin,tc_markers_end,0.0,totaldur); for(STD_list::const_iterator it=tc_markers_begin; it!=tc_markers_end; ++it) { if(it->type==marktype) timepoints.push_back(it->x); } } ODINLOG(odinlog,normalDebug) << "timepoints=" << timepoints.printbody() << STD_endl; if(timepoints.size()) { ProgressDisplayDialog display(this); ProgressMeter progmeter(display); progmeter.new_task(timepoints.size(),"Oscilloscope"); // cache min/max double minx=x_range->get_min(); double maxx=x_range->get_max(); try { for(unsigned int i=0; i odinlog("PlotView","print"); int iplot; int nplots=0; for(iplot=0; iplotis_on()) nplots++; if(!nplots) return; if(!printer->setup(this)) return; QPainter painter(printer->get_device()); int plotheight=paintdevice_height(printer->get_device())/nplots; int plotwidth =paintdevice_width(printer->get_device()); int hmargin=int(float(plotwidth)/20.0); plotwidth-=2*hmargin; int vmargin=-int(float(plotheight)/20.0); plotheight-=2*vmargin; ODINLOG(odinlog,normalDebug) << "plotheight/plotwidth=" << plotheight << "/" << plotwidth << STD_endl; ODINLOG(odinlog,normalDebug) << "hmargin/vmargin=" << hmargin << "/" << vmargin << STD_endl; // prepare printing set_plot_labels(true); set_curve_pens(true); int plotpos=0; for(iplot=0; iplotis_on()) { int left=hmargin; int top=plotpos*(2*vmargin+plotheight)+vmargin; int width=plotwidth; int height=plotheight; QRect rect( left, top, width, height); ODINLOG(odinlog,normalDebug) << "left/top/width/height[" << plotpos << "]=" << left << "/" << top << "/" << width << "/" << height << STD_endl; plotter[iplot]->print(&painter,rect); plotpos++; } } // reset after printing set_plot_labels(false); set_curve_pens(false); } void PlotView::save() { int iplot; if(plotmode->get_current_item()==tcmode_curves) return; timecourseMode type=timecourseMode(plotmode->get_current_item()); if(!create_timecourses(type)) return; const SeqTimecourseData* timecourse=plotdata->get_timecourse(type); if(!timecourse) return; STD_string fname=get_save_filename("Save plot as ASCII", "", "", this); if(fname=="") return; bool doplot[numof_plotchan]; for(iplot=0; iplotis_on()) doplot[iplot]=true; else doplot[iplot]=false; } STD_ofstream file(fname.c_str()); for(unsigned int i=0; isize; i++) { file << timecourse->x[i] << "\t"; for(iplot=0; iploty[iplot][i] << "\t"; } file << "\n"; } file.close(); } int PlotView::lastplot_old=-1; /////////////////////////////////////////////////////////// PlotWindow::PlotWindow(const char* method, const STD_string& nucleus, QWidget *parent) : GuiMainWindow(parent) { Log odinlog("PlotWindow","PlotWindow"); GuiMainWindow::set_caption(("Sequence Plot of "+STD_string(method)).c_str()); view=new PlotView(method, nucleus,this); connect(view, SIGNAL(setMessage(const char*)),this, SLOT (statusBarMessage(const char*))); connect(view, SIGNAL(closeMe()), this, SLOT (close())); GuiMainWindow::show(view,true); } PlotWindow::~PlotWindow() { Log odinlog("PlotWindow","~PlotWindow"); delete view; } void PlotWindow::statusBarMessage(const char* text) { GuiMainWindow::set_status_message(text); } void PlotWindow::close() { GuiMainWindow::close(); } odin-1.8.5/odin/odinplot_range.cpp0000644000175000017500000000663011322062346014044 00000000000000#include #include "odinplot_range.h" #include "odincomp.h" RangeWidget::RangeWidget(double total_min, double total_max, double start_min, double start_max, QWidget *parent) : QWidget(parent), total_min_cache(total_min), total_max_cache(total_max), react_on_scrollbar_change(true) { grid=new GuiGridLayout(this, 1, 3); grid->set_col_stretch(1,1000); scrollbar=new GuiScrollBar(this); connect(scrollbar->get_widget(), SIGNAL(valueChanged(int)), SLOT(new_scroll_val(int))); grid->add_widget( scrollbar->get_widget(), 0, 1 ); min_x=new floatLineEdit(total_min, total_max, start_min, 5, this, "min_x", 3*TEXTEDIT_WIDTH/2, TEXTEDIT_HEIGHT); max_x=new floatLineEdit(total_min, total_max, start_max, 5, this, "max_x", 3*TEXTEDIT_WIDTH/2, TEXTEDIT_HEIGHT); connect(min_x, SIGNAL(floatLineEditValueChanged(float)), SLOT(new_minmax_val(float))); connect(max_x, SIGNAL(floatLineEditValueChanged(float)), SLOT(new_minmax_val(float))); grid->add_widget( min_x->get_widget(), 0, 0, GuiGridLayout::Center ); grid->add_widget( max_x->get_widget(), 0, 2, GuiGridLayout::Center ); // setFixedHeight(2*min_x->sizeHint().height()); set_range(min_x->get_value(), max_x->get_value()); // initialize scrollbar } RangeWidget::~RangeWidget() { delete grid; } void RangeWidget::update_scrollbar() { Log odinlog("RangeWidget","update_scrollbar"); int scrollmin=int(total_min_cache); int scrollmax=int(total_max_cache); int linestep=int(max_x->get_value()-min_x->get_value())/10; int pagestep=int(max_x->get_value()-min_x->get_value()); int margin=pagestep/2; int value=int(0.5*(max_x->get_value()+min_x->get_value())); if(linestep<=0) linestep=1; if(pagestep<=0) pagestep=1; ODINLOG(odinlog,normalDebug) << "linestep/pagestep/value=" << linestep << "/" << pagestep << "/" << value << STD_endl; scrollbar->set_values(scrollmin+margin, scrollmax-margin, linestep, pagestep, value); } void RangeWidget::check_and_set_range(double min, double max) { Log odinlog("RangeWidget","check_and_set_range"); ODINLOG(odinlog,normalDebug) << "min/max/total_min_cache/total_max_cache=" << min << "/" << max << "/" << total_min_cache << "/" << total_max_cache << STD_endl; if(mintotal_max_cache) max=total_max_cache; if(maxset_value(min); max_x->set_value(max); } void RangeWidget::set_range(double min, double max, bool discard_scrollbar) { Log odinlog("RangeWidget","set_range"); check_and_set_range(min,max); if(!discard_scrollbar) update_scrollbar(); } void RangeWidget::new_scroll_val(int v) { Log odinlog("RangeWidget","new_scroll_val"); if(!react_on_scrollbar_change) return; double timepoint=double(v); double range_half=0.5*(max_x->get_value()-min_x->get_value()); if(timepoint<(total_min_cache+range_half)) timepoint=total_min_cache+range_half; if(timepoint>(total_max_cache-range_half)) timepoint=total_max_cache-range_half; double newmin=timepoint-range_half; double newmax=timepoint+range_half; ODINLOG(odinlog,normalDebug) << "newmin/newmax=" << newmin << "/" << newmax << STD_endl; check_and_set_range(newmin,newmax); emit new_range(); } void RangeWidget::new_minmax_val(float) { check_and_set_range(min_x->get_value(), max_x->get_value()); react_on_scrollbar_change=false; update_scrollbar(); react_on_scrollbar_change=true; emit new_range(); } odin-1.8.5/odin/odinview.cpp0000644000175000017500000006730111455553540012676 00000000000000#include "odinview.h" #include "odindialog_process.h" #include "odindialog_progress.h" #include "odindialog_system.h" #include "odindialog_debug.h" #include "odindialog_pulsar.h" #include "odindialog_tree.h" #include "odindialog_kspace.h" #include "odindialog_new.h" #include "odindialog_idea.h" #include "odincomp.h" #include #include #include //////////////////////////////////////////////////////////// void OdinView::usage() { STD_cout << "odin: Graphical user interface of ODIN" << STD_endl; STD_cout << "Usage: odin [options]" << STD_endl; STD_cout << "Options:" << STD_endl; STD_cout << "\t-c : Do not load configuration" << STD_endl; STD_cout << "\t-cl : Log to shell" << STD_endl; STD_cout << "\t-i : Ignore environment/registry settings" << STD_endl; STD_cout << "\t-m : Root directory of methods" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } OdinView::OdinView(QWidget *parent) : QWidget(parent), settings("settings",isCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-i")), ideaopts(new IdeaOpts), method(settings, this, parent), grid(0), messages(0), seqpars(0), commpars(0), progress(0), seqplot(0),signal_x(0),signal_y(0) { Log odinlog("OdinView","OdinView"); newCaption("empty"); grid = new GuiGridLayout(this, 2, 2, false ); grid->set_row_minsize(0, 2*MESSAGES_HEIGHT); // reserve space for parameter widgets if(!isCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-cl")) { messages=new GuiTextView(this, ODIN_MINWIDTH, MESSAGES_HEIGHT); grid->add_widget( messages->get_widget(), 1, 0, GuiGridLayout::Default, 1, 2 ); messages_ptr=messages; LogBase::set_log_output_function(OdinView::odintracefunction); } } OdinView::~OdinView() { messages_ptr=0; delete ideaopts; } void OdinView::initOdinView(GuiToolBar* action_toolbar, bool has_debug_cmdline) { Log odinlog("OdinView","initOdinView"); // methodsel= new GuiComboBox(action_toolbar, svector() ); // connect( methodsel->get_widget(), SIGNAL(activated(int)),this, SLOT(changeMethod(int)) ); if(!settings.init(this)) { ODINLOG(odinlog,errorLog) << "Unable to initialize settings" << STD_endl; exit(-1); } ODINLOG(odinlog,normalDebug) << "GuiApplication::argc/argv()=" << GuiApplication::argc() << "/" << GuiApplication::argv() << STD_endl; char buff[ODIN_MAXCHAR]; if(!isCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-c")) { ODINLOG(odinlog,normalDebug) << "loading settings" << STD_endl; int loadresult=load_prefs(has_debug_cmdline); settings.set_label("General Settings"); ODINLOG(odinlog,normalDebug) << "loadresult=" << loadresult << STD_endl; if(getCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-m",buff,ODIN_MAXCHAR)) { settings.methroot=STD_string(buff)+SEPARATOR_STR; ODINLOG(odinlog,normalDebug) << "method root dir = >" << buff << "<" << STD_endl; } if( loadresult < 0 ) new_method(); else { //if(chsrcdir()) link(); // emit newStatus(chsrcdir(),SeqMethodProxy::get_status_string()); chsrcdir(); } } else { ODINLOG(odinlog,normalDebug) << "starting in clean mode" << STD_endl; new_method(); } } void OdinView::report(bool status, const STD_string& trans_label, const STD_string& message) { emit newStatus(status,message.c_str()); } void OdinView::create_widgets() { Log odinlog("OdinView","create_widgets"); commpars=new JDXwidget(method->get_commonPars(),1,this,false,(STD_string(method->get_label())+"_").c_str()); commpars->show(); grid->add_widget( commpars, 0, 0, GuiGridLayout::Center ); connect(commpars,SIGNAL(valueChanged()),this,SLOT(recalc_method())); seqpars=new JDXwidget(method->get_methodPars(),1,this,false,(STD_string(method->get_label())+"_").c_str()); seqpars->show(); grid->add_widget( seqpars, 0, 1, GuiGridLayout::Center ); connect(seqpars,SIGNAL(valueChanged()),this,SLOT(recalc_method())); } void OdinView::delete_widgets() { Log odinlog("OdinView","delete_widgets"); if(seqpars) { ODINLOG(odinlog,normalDebug) << "deleting seqpars" << STD_endl; seqpars->hide(); delete seqpars; seqpars=0; } if(commpars) { ODINLOG(odinlog,normalDebug) << "deleting commpars" << STD_endl; commpars->hide(); delete commpars; commpars=0; } } void OdinView::new_method() { Log odinlog("OdinView","new_method"); JcampDxBlock newmethfiles("NewSequence"); templatemeth.set_label("SequenceTemplate"); templatemeth.set_defaultdir(settings.get_seqexamplesdir()); templatemeth.set_suffix("cpp"); newmethlabel.set_label("NewSequenceLabel"); newmethlabel_modified=false; // start with empty fields templatemeth=""; newmethlabel=""; newmethfiles.append(templatemeth); newmethfiles.append(newmethlabel); mewmethwizzard=new NewMethDialog(this, newmethfiles); connect(mewmethwizzard,SIGNAL(valueChanged()),this,SLOT(newmeth_rels())); if(mewmethwizzard->exec()) { ODINLOG(odinlog,normalDebug) << "newmethlabel/templatemeth=" << newmethlabel << "/" << templatemeth << STD_endl; if( STD_string(newmethlabel)!="" && STD_string(templatemeth)!="" ) { createdir(settings.methroot.c_str()); createdir((settings.methroot+SEPARATOR_STR+newmethlabel).c_str()); settings.sourcecode=settings.methroot+SEPARATOR_STR+newmethlabel+SEPARATOR_STR+newmethlabel+".cpp"; ODINLOG(odinlog,normalDebug) << "settings.sourcecode=" << settings.sourcecode << STD_endl; copyfile(templatemeth.c_str(),settings.sourcecode.c_str()); // Create default Makefile SeqMakefile mf(newmethlabel,settings.get_installdir()); ::write(mf.get_Makefile("."),settings.methroot+SEPARATOR_STR+newmethlabel+SEPARATOR_STR+"Makefile"); if(chsrcdir()) { // Delete old sequencePars file STD_string seqparsfile(method.seqParsFile()); ODINLOG(odinlog,normalDebug) << "seqparsfile=" << seqparsfile << STD_endl; if(filesize(seqparsfile.c_str())) rmfile(seqparsfile.c_str()); method.link(); } } } } void OdinView::newmeth_rels() { Log odinlog("OdinView","newmeth_rels"); STD_string template_id=templatemeth.get_basename_nosuffix(); ODINLOG(odinlog,normalDebug) << "templatemeth/newmethlabel/template_id=" << templatemeth << "/" << STD_string(newmethlabel) << "/" << template_id << STD_endl; if(!newmethlabel_modified && STD_string(newmethlabel)=="" && template_id!="" ) { newmethlabel=template_id; ODINLOG(odinlog,normalDebug) << "newmethlabel(pre)=" << STD_string(newmethlabel) << STD_endl; mewmethwizzard->updateWidget(); ODINLOG(odinlog,normalDebug) << "newmethlabel(post)=" << STD_string(newmethlabel) << STD_endl; newmethlabel_modified=true; } } /* void OdinView::changeMethod(int index) { } */ void OdinView::update_methodsel() { /* int nmeth=method.get_numof_methods(); svector methlabel; methlabel.resize(nmeth); for(int i=0; iset_names(methlabel); */ } void OdinView::open_method() { Log odinlog("OdinView","open_method"); JDXfileName fname=get_open_filename("Open Method", settings.methroot.c_str(), (STD_string(settings.sourcecode.get_label())+" (*."+settings.sourcecode.get_suffix()+")").c_str(), this); if(fname!="") { method.clear(); settings.sourcecode=STD_string(fname); // Set methroot accordingly JDXfileName methdir=fname.get_dirname(); settings.methroot=STD_string(methdir.get_dirname()); if(chsrcdir()) method.link(); } } void OdinView::close_method() { Log odinlog("OdinView","close_method"); method.clear(); settings.sourcecode=""; save_prefs(); newCaption("empty"); } void OdinView::exit_odin() { Log odinlog("OdinView","exit_odin"); save_prefs(); // This must be executed before method.clear() so that linked in libs (odindata) still have their debug handler activated method.clear(); // Profiler::dump_final_result(); debugger.detach(); for(STD_list::iterator it=subprocs.begin(); it!=subprocs.end(); ++it) it->kill(); GuiApplication::quit(); } void OdinView::edit() { Log odinlog("OdinView","edit"); settings.open_ascfile(settings.sourcecode,subprocs); } void OdinView::recompile() { Log odinlog("OdinView","recompile"); method.clear(); if(method.compile()) method.link(); } bool OdinView::create_seqplot(bool for_simulation) { #ifdef STANDALONE_PLUGIN Log odinlog("OdinView","create_seqplot"); if(seqplot) delete seqplot; seqplot=0; if(!switch_to_platform(standalone)) return false; // ask for options prior to prepare_method because of coil selection SeqPlotDataAbstract* pd=SeqPlatformProxy()->get_plot_data(); if(!pd) { ODINLOG(odinlog,errorLog) << "Unable to get plot_data" << STD_endl; return false; } // load old config pd->set_coilsdir(settings.get_coilsdir()); pd->get_opts(true,true).load(settings.get_confdir()+SEPARATOR_STR+"plotsimopts"); JDXwidgetDialog* sidlg=new JDXwidgetDialog(pd->get_opts(true,for_simulation),1,this,true); ODINLOG(odinlog,normalDebug) << "sidlg=" << sidlg << STD_endl; // store new config pd->get_opts(true,true).write(settings.get_confdir()+SEPARATOR_STR+"plotsimopts"); if(!prepare_acquisition()) return false; ProgressDisplayDialog display(this); ProgressMeter progmeter(display); bool display_plot=true; try { SeqPlatformProxy()->create_plot_events(&progmeter); } catch(OdinCancel) { ODINLOG(odinlog,infoLog) << " aborted" << STD_endl; display_plot=false; } display.finish(); if(display_plot) { seqplot=new PlotWindow(method->get_label().c_str(), method->get_main_nucleus(), this); } return display_plot; #else return false; #endif } STD_string OdinView::get_samplefile() { Log odinlog("OdinView","get_samplefile"); STD_string fname=get_open_filename("Please select a virtual sample", settings.smpfile.c_str(), "Sample Files (*.smp)", this); if(fname=="") return ""; settings.smpfile=fname; return settings.smpfile; } bool OdinView::do_odinreco(const STD_string& outprefix) { Log odinlog("OdinView","do_odinreco"); STD_string scandir=method->get_systemInfo().get_scandir(); ODINLOG(odinlog,normalDebug) << "scandir=" << scandir << STD_endl; svector cmd_chain; cmd_chain.resize(1); cmd_chain[0]="\""+settings.get_binprefix()+"odinreco\" -ff Hamming -fp 0.8 -f jdx -v 1 -r \""+scandir+"/recoInfo\" -o \""+outprefix+"\""; ODINLOG(odinlog,normalDebug) << "cmd_chain=" << cmd_chain.printbody() << STD_endl; ProcessDialog recoproc(this); int waitstate=recoproc.execute_cmds(cmd_chain); bool status=(!waitstate); return status; } void OdinView::sim() { #ifdef STANDALONE_PLUGIN Log odinlog("OdinView","sim"); if(!create_seqplot(true)) return; STD_string methdir(settings.sourcecode.get_dirname()); STD_string simdir(methdir+SEPARATOR_STR+"sim"+SEPARATOR_STR); createdir(simdir.c_str()); STD_string fidfile(simdir+platform->get_rawfile()); STD_string outfile(simdir+"image"); STD_string sample=get_samplefile(); if(sample=="") return; ProgressDisplayDialog display(this); ProgressMeter progmeter(display); bool do_reco=true; try { if(!seqplot->simulate(fidfile,sample,&progmeter)) do_reco=false; } catch(OdinCancel) { ODINLOG(odinlog,infoLog) << " aborted" << STD_endl; do_reco=false; } display.finish(); Profiler::dump_final_result(); if(do_reco) { method->get_systemInfo().set_scandir(simdir); method->write_meas_contex(simdir); if(!do_odinreco(outfile)) return; Process proc; proc.start("\""+settings.get_binprefix()+IMAGEVIEWER+"\" \""+outfile+".jdx\""); subprocs.push_back(proc); } #endif } void OdinView::geo() { Log odinlog("OdinView","geo"); STD_string geoeditcmd="\""+settings.get_binprefix()+"geoedit\" "; STD_string pilot=platform->pv_pilot_scan(); if(pilot!="") { geoeditcmd+="-blowup 2 -pilot \""+pilot+"\" "; } else { STD_string sample=get_samplefile(); if(sample!="") geoeditcmd+="-sample \""+sample+"\" "; } STD_string geofile=settings.get_tmpdir()+SEPARATOR_STR+"geometryInfo"; geoeditcmd+="\""+geofile+"\""; ODINLOG(odinlog,normalDebug) << "geoeditcmd=" << geoeditcmd << STD_endl; method->write_geometry(geofile); Process proc; proc.start(geoeditcmd,true); // Block odin while geoedit is open subprocs.push_back(proc); method->load_geometry(geofile); new_geo_pars(); } void OdinView::new_geo_pars() { method->get_geometry().update(); recalc_method(); } void OdinView::seqprops() { Log odinlog("OdinView","seqprops"); if(!prepare_method()) return; STD_string msg; msg+=STD_string(method->get_label())+"\n\n"; msg+=STD_string(justificate(method->get_description())+"\n"); msg+="Total Duration : " + ftos(method->get_totalDuration()) + " min\n"; msg+="Number of Acquisitions : " + itos(method->get_numof_acquisitions()) + "\n"; msg+="RF Energy Deposition : "+ftos(method->get_rf_energy())+" a.u.\n"; message_question(msg.c_str(), "Sequence Properies", this); } void OdinView::seqtree() { Log odinlog("OdinView","seqtree"); if(!method.link()) return; svector column_labels; column_labels.resize(4); column_labels[0]="Label"; column_labels[1]="Type"; column_labels[2]="Duration[ms]"; column_labels[3]="Properties"; TreeDialog* treedlg=new TreeDialog(this,"Sequence Tree",column_labels); method->tree(treedlg); treedlg->show(); } void OdinView::recoinfo() { Log odinlog("OdinView","recoinfo"); if(!prepare_acquisition()) return; STD_string fname(settings.get_tmpdir()+SEPARATOR_STR+"recoInfo"); method->write_recoInfo(fname); settings.open_ascfile(fname,subprocs); } void OdinView::pulsars() { Log odinlog("OdinView","pulsars"); if(!prepare_method()) return; STD_string sifname(settings.get_tmpdir()+SEPARATOR_STR+"systemInfo4pulsar"); method->write_systemInfo(sifname); new PulsarDialog(method->get_active_pulsar_pulses(),settings.get_binprefix()+"pulsar",subprocs,settings.get_tmpdir(),sifname,this); } void OdinView::kspace() { #ifdef STANDALONE_PLUGIN Log odinlog("OdinView","kspace"); if(!create_seqplot()) return; const SeqTimecourseData* ktrajs=seqplot->get_kspace_trajs(); if(!ktrajs) return; float kmax=0.0; geometryMode geomode=method->get_geometry().get_Mode(); for(int i=0; iget_commonPars().get_MatrixSize(direction(i)); if(n>1) { float kmaxdir=secureDivision( PII * n , method->get_geometry().get_FOV(direction(i)) ); kmax=STD_max(kmax,kmaxdir); } } } ODINLOG(odinlog,normalDebug) << "kmax/n_rec_points=" << kmax << "/" << ktrajs->n_rec_points << STD_endl; KspaceDialog* kdlg=new KspaceDialog(this,kmax,ktrajs->n_rec_points); try { for(unsigned int i=0; i<(ktrajs->size); i++) { if((ktrajs->y[rec_plotchan][i])>0.0) { kdlg->draw_point(ktrajs->y[Gread_plotchan][i],ktrajs->y[Gphase_plotchan][i],ktrajs->y[Gslice_plotchan][i]); } } } catch(OdinCancel) { ODINLOG(odinlog,infoLog) << " aborted" << STD_endl; delete kdlg; } #endif } void OdinView::pulsprog() { Log odinlog("OdinView","pulsprog"); if(!switch_to_platform(paravision)) return; if(!prepare_method()) return; STD_string fname(settings.get_tmpdir()+SEPARATOR_STR+"pulsprog"); programContext context; context.mode=brukerPpg; STD_string file(platform->get_program(context)); ::write(file,fname); settings.open_ascfile(fname,subprocs); } void OdinView::gradprog() { Log odinlog("OdinView","gradprog"); if(!switch_to_platform(paravision)) return; if(!prepare_method()) return; STD_string fname(settings.get_tmpdir()+SEPARATOR_STR+"gradprog"); programContext context; context.mode=brukerGpg; STD_string file(platform->get_program(context)); ::write(file,fname); settings.open_ascfile(fname,subprocs); } void OdinView::parx() { Log odinlog("OdinView","parx"); if(!switch_to_platform(paravision)) return; if(!prepare_acquisition()) return; STD_string fname(settings.get_tmpdir()+SEPARATOR_STR+"parx"); programContext context; context.mode=brukerParx; STD_string file(platform->get_program(context)); ::write(file,fname); settings.open_ascfile(fname,subprocs); } void OdinView::pv_pilot() { Log odinlog("OdinView","pv_pilot"); method.clear(); // unlink current method if(!switch_to_platform(paravision)) return; ProgressDisplayDialog display(this); ProgressMeter progmeter(display); progmeter.new_task(0, "Pilot Scan"); bool success=false; try { success=platform->pv_pilot(&progmeter); } catch(OdinCancel) { ODINLOG(odinlog,infoLog) << " aborted" << STD_endl; platform->pv_stop(); } display.finish(); if(success) geo(); } void OdinView::bruker_scan(bool autorg) { Log odinlog("OdinView","pv_scan"); if(!switch_to_platform(paravision)) return; if(!prepare_acquisition()) return; ProgressDisplayDialog display(this); ProgressMeter progmeter(display); progmeter.new_task(0, "GOP Scan"); bool success=false; try { success=platform->pv_gop(autorg,&progmeter); } catch(OdinCancel) { ODINLOG(odinlog,infoLog) << " aborted" << STD_endl; platform->pv_stop(); } display.finish(); if(success) { STD_string outprefix=method->get_systemInfo().get_scandir()+"/image"; // Get prefix after clone in pv_gop if(!do_odinreco(outprefix)) return; Process proc; proc.start("\""+settings.get_binprefix()+IMAGEVIEWER+"\" -blowup 2 \""+outprefix+".jdx\""); subprocs.push_back(proc); } } void OdinView::pv_scan() {bruker_scan(false);} void OdinView::pv_rgscan() {bruker_scan(true);} void OdinView::pv_howto() { settings.open_ascfile(settings.get_installdir()+SEPARATOR_STR+"share"+SEPARATOR_STR+"doc"+SEPARATOR_STR+"odin"+SEPARATOR_STR+"Paravision"+SEPARATOR_STR+"HOWTO.txt",subprocs); } void OdinView::ideaevents() { Log odinlog("OdinView","ideaevents"); if(!switch_to_platform(numaris_4)) return; if(!prepare_acquisition()) return; svector column_labels; column_labels.resize(8); column_labels[0]="Event Block / Sequence Object"; column_labels[1]="NCO"; column_labels[2]="RF"; column_labels[3]="Gx"; column_labels[4]="Gy"; column_labels[5]="Gz"; column_labels[6]="ADC"; column_labels[7]="Sync"; TreeDialog* evdlg=new TreeDialog(this,"IDEA events",column_labels); eventContext context; context.action=seqRun; context.event_display=evdlg; method->event(context); evdlg->show(); } void OdinView::ideahowto() { settings.open_ascfile(settings.get_installdir()+SEPARATOR_STR+"share"+SEPARATOR_STR+"doc"+SEPARATOR_STR+"odin"+SEPARATOR_STR+"IDEA_n4"+SEPARATOR_STR+"HOWTO.txt",subprocs); } void OdinView::epiccode() { Log odinlog("OdinView","epiccode"); if(!switch_to_platform(epic)) return; if(!prepare_method()) return; STD_string fname(settings.get_tmpdir()+SEPARATOR_STR+"odin.e"); programContext context; context.mode=epicCode; STD_string file(platform->get_program(context)); ::write(file,fname); settings.open_ascfile(fname,subprocs); } void OdinView::edit_prefs() { Log odinlog("OdinView","edit_prefs"); JDXwidgetDialog* dlg=new JDXwidgetDialog(settings,2,this); connect(dlg,SIGNAL(finished()),this,SLOT(react_on_changed_prefs())); } void OdinView::edit_system() { Log odinlog("OdinView","edit_system"); SystemDialog* dlg=new SystemDialog(this); connect(dlg,SIGNAL(new_setting()),this,SLOT(recalc_method())); connect(dlg,SIGNAL(new_platform(odinPlatform)),this,SLOT(switch_to_platform_noask(odinPlatform))); connect(dlg,SIGNAL(finished()),this,SLOT(save_prefs())); } void OdinView::edit_study() { Log odinlog("OdinView","edit_study"); JDXwidgetDialog* dlg=new JDXwidgetDialog(method->get_studyInfo(),2,this); connect(dlg,SIGNAL(finished()),this,SLOT(react_on_changed_prefs())); } void OdinView::load_system() { Log odinlog("OdinView","load_system"); STD_string fname=get_open_filename("Load systemInfo", settings.get_homedir().c_str(), "", this); if(fname!="") { method->load_systemInfo(fname); recalc_method(); } } void OdinView::debug_opts() { Log odinlog("OdinView","debug_opts"); #ifdef ODIN_DEBUG DebugDialog* dlg=new DebugDialog(this); connect(dlg,SIGNAL(finished()),this,SLOT(save_prefs())); #endif } int OdinView::load_prefs(bool ignore_debugLevels) { Log odinlog("OdinView","load_prefs"); method->load_systemInfo(settings.get_confdir()+SEPARATOR_STR+"systemInfo"); method->load_geometry(settings.get_confdir()+SEPARATOR_STR+"geometryInfo"); method->get_studyInfo().load(settings.get_confdir()+SEPARATOR_STR+"studyInfo"); #ifdef ODIN_DEBUG if(!ignore_debugLevels) { STD_string debugLevels; ::load(debugLevels,settings.get_confdir()+SEPARATOR_STR+"debugLevels"); LogBase::set_levels(debugLevels.c_str()); } #endif int retval=settings.load(settings.get_confdir()+SEPARATOR_STR+"settings"); ODINLOG(odinlog,normalDebug) << "retval=" << retval << STD_endl; change_debugger(); ideaopts->set_defaults(settings,0); // do not ask for IDEA directory ideaopts->load(settings.get_confdir()+SEPARATOR_STR+"ideaopts"); return retval; } int OdinView::react_on_changed_prefs() { Log odinlog("OdinView","react_on_changed_prefs"); change_debugger(); return save_prefs(); } int OdinView::save_prefs() { Log odinlog("OdinView","save_prefs"); ODINLOG(odinlog,normalDebug) << "saving systemInfo" << STD_endl; method->write_systemInfo(settings.get_confdir()+SEPARATOR_STR+"systemInfo"); ODINLOG(odinlog,normalDebug) << "saving geometryInfo" << STD_endl; method->write_geometry(settings.get_confdir()+SEPARATOR_STR+"geometryInfo"); ODINLOG(odinlog,normalDebug) << "saving studyInfo" << STD_endl; method->get_studyInfo().write(settings.get_confdir()+SEPARATOR_STR+"studyInfo"); ODINLOG(odinlog,normalDebug) << "saving debugLevels" << STD_endl; STD_string debugLevels(LogBase::get_levels()); ::write(debugLevels,settings.get_confdir()+SEPARATOR_STR+"debugLevels"); ideaopts->write(settings.get_confdir()+SEPARATOR_STR+"ideaopts"); ODINLOG(odinlog,normalDebug) << "saving settings" << STD_endl; JcampDxBlock prefs; prefs.merge(settings); return prefs.write(settings.get_confdir()+SEPARATOR_STR+"settings"); } int OdinView::save_protocol() { Log odinlog("OdinView","save_protocol"); if(!method.link()) return -1; STD_string fname=get_save_filename("Store Protocol", settings.protfile.c_str(), "ODIN Protocols (*.pro)", this); if(fname=="") return 0; ODINLOG(odinlog,normalDebug) << "fname=" << fname << STD_endl; settings.protfile=fname; return method->write_protocol(fname); } int OdinView::load_protocol() { Log odinlog("OdinView","load_protocol"); if(!method.link()) return -1; STD_string fname=get_open_filename("Load Protocol", settings.protfile.c_str(), "ODIN Protocols (protocol *.pro)", this); if(fname=="") return 0; settings.protfile=fname; int result=method->load_protocol(fname); if(result>=0) method.relink(); return result; } void OdinView::compile_idea() { IdeaDialog* dlg=new IdeaDialog(this, *ideaopts, settings); connect(dlg,SIGNAL(changed()),this,SLOT(save_prefs())); } void OdinView::export_dlls() { JDXfileName testfile(ideaopts->odindir+SEPARATOR_STR+"build_complete_tag"); if(!testfile.exists()) { message_question(justificate("Cannot find compiled ODIN for IDEA installation under "+ideaopts->odindir+". Please create it first using the following dialog.").c_str(), "ODIN for IDEA not found", this, false, true); compile_idea(); } new IdeaMethodDialog(settings.methroot,settings.selectedMethods,settings.get_installdir(), *ideaopts, this); } void OdinView::show_manual() {settings.display_html(settings.get_manual_location()+"odin_doc.html",subprocs);} void OdinView::show_apidoc() {settings.display_html(settings.get_manual_location()+"index.html",subprocs);} void OdinView::show_seqdoc() {settings.display_html(settings.get_manual_location()+"group__odinseq.html",subprocs);} bool OdinView::chsrcdir() { Log odinlog("OdinView","chsrcdir"); method.clear(); bool result=method.check_srcdir(); if(result) { save_prefs(); newCaption(settings.sourcecode.get_basename_nosuffix().c_str()); } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } bool OdinView::prepare_method() { Log odinlog("OdinView","prepare_method"); bool result=true; if(!method.link()) return result=false; else { method->clear(); if(!method->prepare()) result=false; } return result; } bool OdinView::prepare_acquisition() { Log odinlog("OdinView","prepare_acquisition"); bool result=prepare_method(); if(result) result=method->prep_acquisition(); return result; } void OdinView::recalc_method() { Log odinlog("OdinView","recalc_method"); if(!method.link()) return; if(seqplot) delete seqplot; seqplot=0; if(!method->clear()) { ODINLOG(odinlog,errorLog) << "clear() failed" << STD_endl; // emit newStatus(false,SeqMethodProxy::get_status_string()); return; } if(!method->build()) { ODINLOG(odinlog,errorLog) << "build() failed" << STD_endl; // emit newStatus(false,SeqMethodProxy::get_status_string()); return; } ODINLOG(odinlog,normalDebug) << "updating seqpars/commpars=" << seqpars << "/" << commpars << STD_endl; if(seqpars) seqpars->updateWidget(); if(commpars) commpars->updateWidget(); } void OdinView::odintracefunction(const LogMessage& msg) { if(messages_ptr) { // Do not use code in here which uses Log STD_string msgstr=msg.str(0, false); int msglength=msgstr.length(); if(msgstr[msglength-1]=='\n') msgstr=msgstr.substr(0,msglength-1); // remove endl because lines are wrapped by GuiTextView // catch compiler warnings logPriority level=msg.level; if(msgstr.find("warning:")!=STD_string::npos) level=warningLog; if(msgstr.find("error:") !=STD_string::npos) level=errorLog; // Replace any tag braces msgstr=replaceStr(msgstr, "<","<"); msgstr=replaceStr(msgstr, ">",">"); /* for(unsigned int i=0; i') msgstr[i]=']'; } */ // color-code log level if(level==errorLog) msgstr=""+msgstr+""; else if(level==warningLog) msgstr=""+msgstr+""; else msgstr=""+msgstr+""; messages_ptr->append_text(msgstr.c_str()); } else { default_tracefunction(msg); // fall back to console } } GuiTextView* OdinView::messages_ptr=0; void OdinView::switch_to_platform_noask(odinPlatform pF) { switch_to_platform(pF,false); } bool OdinView::switch_to_platform(odinPlatform pF, bool ask) { Log odinlog("OdinView","switch_to_platform"); bool result=true; if(ask) { if(method->get_systemInfo().get_platform()==pF) return true; STD_string pFstring(SeqPlatformProxy::get_possible_platforms()[pF]); STD_string msg=justificate("In order to perform the operation, the platform must be switched to "+pFstring+". Should it be switched now? (You can switch it back by the Preferences->System menu entry.)"); result=message_question(msg.c_str(), "Switching Platform", this, true); } if(result) { platform.set_current_platform(pF); method.relink(); } return result; } void OdinView::change_debugger() { Log odinlog("OdinView","change_debugger"); if(settings.attachDebugger) debugger.attach(); else debugger.detach(); } odin-1.8.5/odin/odinplot_vtk.h0000644000175000017500000000360711322062346013222 00000000000000/*************************************************************************** odinplot_vtk.h - description ------------------- begin : Tue Jul 26 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINPLOT_VTK_H #define ODINPLOT_VTK_H #include #include // forward declarations of vtk classes class vtkRenderer; class vtkRenderWindow; class vtkRenderWindowInteractor; class vtkPolyDataMapper; class vtkActor; class vtkAxes; class vtkTubeFilter; class vtkActor; class vtkArrowSource; ///////////////////////////////////////////////////// class VtkMagnPlotter { public: VtkMagnPlotter(); ~VtkMagnPlotter(); void start(); void plot_vector(float M[3], float* dM); void interact(); private: vtkRenderer* renderer; vtkRenderWindow* renWin; vtkRenderWindowInteractor* iren; vtkArrowSource* magnArrow; vtkPolyDataMapper* magnMapper; vtkActor* magnActor; vtkActor* magnGradActor; vtkAxes* axes; vtkTubeFilter* axesTubes; vtkPolyDataMapper* axesMapper; vtkActor* axesActor; bool magnGradActor_added; }; #endif odin-1.8.5/odin/odindialog_kspace.h0000644000175000017500000000371111322062346014141 00000000000000/*************************************************************************** odindialog_kspace.h - description ------------------- begin : Mon Oct 10 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_KSPACE_H #define ODINDIALOG_KSPACE_H #include #include #include "odindialog_progress.h" // for OdinCancel #define KSPACE_POINT_SIZE 3 #define KSPACE_INPLANE_SIZE 512 #define KSPACE_THROUGHPLANE_SIZE 128 #define KSPACE_BORDER_SIZE 50 class KspaceDialog : public QObject, public GuiDialog { Q_OBJECT public: KspaceDialog(QWidget *parent, float kmax, unsigned int nadc); ~KspaceDialog(); void draw_point(float kx, float ky, float kz); protected: void repaint(); // overloaded from GuiDialog void close() {canceled=true;} // overloaded from GuiDialog private slots: void cancel(); private: int kpos2index(float kpos) const; void progress(); GuiGridLayout* grid; GuiButton* pb_cancel; QLabel* kspace_label; QPixmap* kspace_pixmap_buff; GuiProgressBar* progbar; GuiPainter* painter; float k0; int progcount; bool canceled; }; #endif odin-1.8.5/odin/odinmethod.h0000644000175000017500000000717011322062346012637 00000000000000/*************************************************************************** odinmethod.h - description ------------------- begin : Sun Dec 25 21:30:11 CEST 2005 copyright : (C) 2005 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef OdinMethod_H #define OdinMethod_H #include #include #include "odincomp.h" #include "odinconf.h" class QWidget; // forward declaration ////////////////////////////////////////////////////////////////////// /* State diagram for OdinMethod, i.e. for compiling/linking of sequences: Possible transitions between states are indicated by the corresponding member functions that perform the transition. clean <-------\ | | | clear() | compile() | | | V | | compiled ------| /---------\ | | | | | | | | link() | | | relink() | | | | V | | | | V | linked --------' ---------' */ ////////////////////////////////////////////////////////////////////// /** * * Callback to report success/failure of state transitions * */ struct OdinMethodCallback { virtual void report(bool status, const STD_string& trans_label, const STD_string& message) = 0; virtual void create_widgets() = 0; virtual void delete_widgets() = 0; }; ////////////////////////////////////////////////////////////////////// /** * * State machine to handle compiling and linking of sequences * */ class OdinMethod : public StateMachine { public: OdinMethod(const OdinConf& conf, OdinMethodCallback* callback, QWidget* parent4dialog); /** * Performs state transition to 'clean' */ bool clear() {return clean.obtain_state();} /** * Performs state transition to 'compiled' */ bool compile() {return compiled.obtain_state();} /** * Performs state transition to 'linked' */ bool link() {return linked.obtain_state();} /** * Relinks the sequence into process space */ bool relink(); /** * Returns pointer to the encapsulated method */ SeqMethod* operator -> () {return method.get_current_method();} /** * Returns true if valid source code is present */ bool check_srcdir(); /** * Location of sequencePars file for this method */ STD_string seqParsFile(); private: // states and their transition functions: State clean; bool make_clean(); State compiled; bool clean2compiled(); State linked; bool compiled2linked(); bool linked2compiled(); // helpers: bool unlink(); bool make(); STD_string find_so(); SeqMethodProxy method; // stuff passed in during construction const OdinConf& settings; OdinMethodCallback* cback; QWidget* parent; }; #endif odin-1.8.5/odin/odindialog_debug.h0000644000175000017500000000277211322062346013767 00000000000000/*************************************************************************** odindialog_debug.h - description ------------------- begin : Sun Oct 3 21:30:11 CEST 2005 copyright : (C) 2003 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINDIALOG_DEBUG_H #define ODINDIALOG_DEBUG_H #include #include class DebugDialog : public QObject, public GuiDialog { Q_OBJECT public: DebugDialog(QWidget *parent); ~DebugDialog(); signals: void finished(); private slots: void emitDone(); void levelChanged(int); private: friend class QComboBox; friend class QPushButton; GuiGridLayout* grid; GuiButton* pb_done; STD_list debugenums; }; #endif odin-1.8.5/odin/odin.cpp0000644000175000017500000001352211455553540011777 00000000000000#include "odin.h" #include "icons.h" #include "odincomp.h" Odin::Odin() : old_status(true), first_status(true) { Log odinlog("Odin","Odin"); set_status_xpm(greenIcon); // init once view=new OdinView(GuiMainWindow::get_widget()); connect(view,SIGNAL(newCaption(const char*)),this,SLOT(changeCaption(const char*))); connect(view,SIGNAL(newStatus(bool,const char*)),this,SLOT(changeStatus(bool,const char*))); fileMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); fileMenu->insert_item("&New", view, SLOT(new_method()), Qt::CTRL+Qt::Key_N); fileMenu->insert_item("&Open", view, SLOT(open_method()), Qt::CTRL+Qt::Key_O); fileMenu->insert_item("&Close", view, SLOT(close_method()), Qt::CTRL+Qt::Key_W); fileMenu->insert_item("&Save Settings", view, SLOT(save_prefs()), Qt::CTRL+Qt::Key_S); fileMenu->insert_item("S&tore Protocol", view, SLOT(save_protocol()), Qt::CTRL+Qt::Key_T); fileMenu->insert_item("&Load Protocol", view, SLOT(load_protocol()), Qt::CTRL+Qt::Key_L); fileMenu->insert_item("&Quit", view, SLOT(exit_odin()), Qt::CTRL+Qt::Key_Q); toolbar = new GuiToolBar(this, "Action"); actionMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); new GuiToolButton(toolbar, editIcon, "Edit", view, SLOT(edit())); actionMenu->insert_item("Edit", view, SLOT(edit()), Qt::Key_F1); new GuiToolButton(toolbar, recompIcon, "Compile & Link", view, SLOT(recompile())); actionMenu->insert_item("Compile and &Link", view, SLOT(recompile()), Qt::Key_F2); new GuiToolButton(toolbar, geoIcon, "Geometry", view, SLOT(geo())); actionMenu->insert_item("Geometry", view, SLOT(geo()), Qt::Key_F3); #ifdef STANDALONE_PLUGIN new GuiToolButton(toolbar, plotIcon, "Plot Sequence", view, SLOT(plot())); actionMenu->insert_item("Plot Sequence", view, SLOT(plot()), Qt::Key_F4); new GuiToolButton(toolbar, kspaceIcon, "k-Space", view, SLOT(kspace())); actionMenu->insert_item("Acquisition k-Space", view, SLOT(kspace()), Qt::Key_F5); new GuiToolButton(toolbar, simIcon, "Simulate", view, SLOT(sim())); actionMenu->insert_item("Simulate", view, SLOT(sim()), Qt::Key_F6); #endif infoMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); infoMenu->insert_item("Sequence Properties", view, SLOT(seqprops())); infoMenu->insert_item("Sequence &Tree", view, SLOT(seqtree())); infoMenu->insert_item("Reconstruction Parameters", view, SLOT(recoinfo())); infoMenu->insert_item("P&ulsar Pulses", view, SLOT(pulsars())); brukerMenu=0; #ifdef PARAVISION_PLUGIN brukerMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); brukerMenu->insert_item("&Pulse Program", view, SLOT(pulsprog()), Qt::CTRL+Qt::Key_P); brukerMenu->insert_item("&Gradient Program", view, SLOT(gradprog()), Qt::CTRL+Qt::Key_G); brukerMenu->insert_item("P&ARX parameters", view, SLOT(parx()), Qt::CTRL+Qt::Key_A); brukerMenu->insert_item("Pilot", view, SLOT(pv_pilot())); brukerMenu->insert_item("Scan", view, SLOT(pv_scan())); brukerMenu->insert_item("AutoRG and Scan", view, SLOT(pv_rgscan())); brukerMenu->insert_item("&Show HOWTO", view, SLOT(pv_howto())); #endif siemensMenu=0; #ifdef IDEA_PLUGIN siemensMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); siemensMenu->insert_item("&Event Table", view, SLOT(ideaevents()), Qt::CTRL+Qt::Key_E); #ifdef USING_WIN32 siemensMenu->insert_item("&Compile ODIN for IDEA", view, SLOT(compile_idea())); siemensMenu->insert_item("E&xport DLLs", view, SLOT(export_dlls()), Qt::CTRL+Qt::Key_X); #endif siemensMenu->insert_item("&Show HOWTO", view, SLOT(ideahowto())); #endif geMenu=0; #ifdef EPIC_PLUGIN geMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); geMenu->insert_item("EPIC Code", view, SLOT(epiccode())); #endif prefMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); prefMenu->insert_item("Settings", view, SLOT(edit_prefs())); prefMenu->insert_item("System", view, SLOT(edit_system())); prefMenu->insert_item("Load systemInfo", view, SLOT(load_system())); prefMenu->insert_item("Study", view, SLOT(edit_study())); #ifdef ODIN_DEBUG prefMenu->insert_item("Debugging/Tracing", view, SLOT(debug_opts())); #endif helpMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); helpMenu->insert_item("User Manual", view, SLOT(show_manual())); helpMenu->insert_item("Programmers Manual", view, SLOT(show_apidoc())); helpMenu->insert_item("Documentation for Seq... Classes", view, SLOT(show_seqdoc())); helpMenu->insert_item("About...", this, SLOT(slotHelpAbout())); GuiMainWindow::insert_menu("File", fileMenu); GuiMainWindow::insert_menu("Action", actionMenu); GuiMainWindow::insert_menu("Info", infoMenu); if(brukerMenu) GuiMainWindow::insert_menu("Bruker", brukerMenu); if(siemensMenu) GuiMainWindow::insert_menu("Siemens", siemensMenu); if(geMenu) GuiMainWindow::insert_menu("GE", geMenu); GuiMainWindow::insert_menu("Preferences", prefMenu); GuiMainWindow::insert_menu_separator(); GuiMainWindow::insert_menu("Help", helpMenu); GuiMainWindow::show(view); } void Odin::initOdin(GuiApplication* a, bool has_debug_cmdline) { Log odinlog("Odin","initOdin"); view->initOdinView(toolbar,has_debug_cmdline); connect( a->get_object(),SIGNAL(aboutToQuit()), view,SLOT(exit_odin()) ); } void Odin::changeCaption(const char* text) { GuiMainWindow::set_caption((STD_string("Odin " VERSION) + " - " + text).c_str()); } void Odin::changeStatus(bool status, const char* text) { Log odinlog("OdinView","changeStatus"); old_status=status; first_status=false; if(status) { GuiMainWindow::set_status_xpm(greenIcon); if(text) GuiMainWindow::set_status_message(text); } else { STD_string msg="Error"; if(text && STD_string(text)!="") msg+=STD_string(" - ")+text; GuiMainWindow::set_status_xpm(redIcon); GuiMainWindow::set_status_message(msg.c_str()); } } void Odin::slotHelpAbout() { message_question(IDS_ODIN_ABOUT, "About...", GuiMainWindow::get_widget()); } odin-1.8.5/depcomp0000755000175000017500000004426711734622601010773 00000000000000#! /bin/sh # depcomp - compile a program generating dependencies as side-effects scriptversion=2009-04-28.21; # UTC # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free # Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try \`$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by `PROGRAMS ARGS'. object Object file output by `PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputing dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u="sed s,\\\\\\\\,/,g" depmode=msvisualcpp fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ## The second -e expression handles DOS-style file names with drive letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the `deleted header file' problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. tr ' ' ' ' < "$tmpdepfile" | ## Some versions of gcc put a space before the `:'. On the theory ## that the space means something, we add a space to the output as ## well. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like `#:fec' to the end of the # dependency line. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ tr ' ' ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' ' ' < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts `$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then # Each line is of the form `foo.o: dependent.h'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else # The sourcefile does not contain any dependencies, so just # store a dummy comment line, to avoid errors with the Makefile # "include basename.Plo" scheme. echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; icc) # Intel's C compiler understands `-MD -MF file'. However on # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c # ICC 7.0 will fill foo.d with something like # foo.o: sub/foo.c # foo.o: sub/foo.h # which is wrong. We want: # sub/foo.o: sub/foo.c # sub/foo.o: sub/foo.h # sub/foo.c: # sub/foo.h: # ICC 7.1 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using \ : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" # Add `dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in `foo.d' instead, so we check for that too. # Subdirectories are respected. dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` test "x$dir" = "x$object" && dir= base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` if test "$libtool" = yes; then # With Tru64 cc, shared objects can also be used to make a # static library. This mechanism is used in libtool 1.4 series to # handle both shared and static libraries in a single compilation. # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. # # With libtool 1.5 this exception was removed, and libtool now # generates 2 separate objects for the 2 libraries. These two # compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 tmpdepfile2=$dir$base.o.d # libtool 1.5 tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.o.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d tmpdepfile4=$dir$base.d "$@" -MD fi stat=$? if test $stat -eq 0; then : else rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" # That's a tab and a space in the []. sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" else echo "#dummy" > "$depfile" fi rm -f "$tmpdepfile" ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for `:' # in the target name. This is to cope with DOS-style filenames: # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. "$@" $dashmflag | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" tr ' ' ' ' < "$tmpdepfile" | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" sed '1,2d' "$tmpdepfile" | tr ' ' ' ' | \ ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove `-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" echo " " >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: odin-1.8.5/sequences/0000755000175000017500000000000011735135552011461 500000000000000odin-1.8.5/sequences/tj_gesse.cpp0000644000175000017500000003053511363773557013730 00000000000000 // include the headers of all sequence classes #include // The whole EPI sequence (including reco) is a C++ class class METHOD_CLASS : public SeqMethod { private: JDXint NumOfEchoes; JDXfloat PulseDur; JDXint NumOfSatPulses; JDXdoubleArr TEs; // sequence objects which are the elementary objects // to build the EPI sequence SeqPulsar exc; SeqPulsarReph exc_reph; SeqPulsar refoc; SeqSat fatsat; SeqAcqRead ge_acq; SeqAcqRead se_acq; SeqAcqDeph deph; SeqObjList ge_preacq; SeqObjList se_preacq; SeqAcqDeph reph; SeqDelay sedelay; SeqGradTrapezParallel rewind; SeqGradPhaseEnc pe,pe_rewind; SeqVecIter phaseiter; SeqObjLoop sliceloop; SeqObjLoop peloop; SeqObjLoop reploop; SeqObjLoop echoloop; SeqObjLoop dummyloop; SeqDelay trdelay; SeqObjVector gerewindvec; SeqObjList gepart; SeqDelay gepart_dummy; SeqObjVector serewindvec; SeqObjList separt; SeqDelay separt_dummy; SeqObjList scan; SeqObjList imagingpart; SeqObjList dummypart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList preppart; SeqDelay exc2acq; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqGradConstPulse spoiler; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("GESSE sequence."); } void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,128); commonPars->set_MatrixSize(phaseDirection,128,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); // commonPars->set_ReductionFactor(3); NumOfEchoes=32; NumOfEchoes.set_description("Number of echoes per period"); append_parameter(NumOfEchoes,"NumOfEchoes"); PulseDur=4.0; // start with large duration so that sequence can be loaded PulseDur.set_unit(ODIN_TIME_UNIT); PulseDur.set_description("Pulse duration of excitation and refocusing pulse"); append_parameter(PulseDur,"PulseDur"); NumOfSatPulses=2; NumOfSatPulses.set_description("Number of consecutive saturation pulses"); append_parameter(NumOfSatPulses,"NumOfSatPulses"); TEs.resize(2*NumOfEchoes); TEs.set_description("Echo times"); append_parameter(TEs,"TEs"); } void method_seq_init() { Log odinlog(this,"method_seq_init"); if(NumOfEchoes<2) NumOfEchoes=2; ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float slicegap=geometryInfo->get_sliceDistance()-slicethick; // excitation pulse exc=SeqPulsarSinc("exc",slicethick,false,PulseDur,commonPars->get_FlipAngle()); dvector exclist=systemInfo->get_gamma() * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector(); ODINLOG(odinlog,normalDebug) << "exclist=" << exclist << STD_endl; exc.set_freqlist( exclist ); exc.set_pulse_type(excitation); exc_reph=SeqPulsarReph("exc_reph",exc); // Slightly thicker refocusing slice for better SNR // Since the same spatial resolution is used for exc and refoc, the gradient strengths will be the same float extra_slicethick_refoc=STD_min(0.5*slicethick, 0.3*slicegap); // refocusing pulse refoc=SeqPulsarSinc("refoc",slicethick+extra_slicethick_refoc,false,PulseDur,180.0); dvector refoclist=systemInfo->get_gamma() * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector(); ODINLOG(odinlog,normalDebug) << "refoclist=" << refoclist << STD_endl; refoc.set_freqlist( refoclist ); if(!commonPars->get_RFSpoiling()) refoc.set_phase(90.0); refoc.set_pulse_type(refocusing); // fat saturation module fatsat=SeqSat("fatsat",fat,0.3,NumOfSatPulses); //////////////// Readout: ////////////////////////////// // set equivalent resolution in read and phase direction float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); int pelines=int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5); commonPars->set_MatrixSize(phaseDirection, pelines, noedit); float os_read=1.25; // slight oversampling to allow off-center FOV ge_acq=SeqAcqRead("ge_acq",commonPars->get_AcqSweepWidth(),commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection),readDirection,os_read); se_acq=ge_acq; // pre-dephase gradient deph=SeqAcqDeph("deph",ge_acq,FID); // post-rephase gradients reph=SeqAcqDeph("reph",ge_acq,rephase); // EPI rewinder after each echo fvector gradint(3); float rewind_strength=0.4*systemInfo->get_max_grad(); // OK for stimulation monitor gradint=reph.get_gradintegral()+deph.get_gradintegral(); // collapse rephase and dephase into one gradient pulse rewind=SeqGradTrapezParallel("rewind",gradint[0],gradint[1],gradint[2],rewind_strength); ODINLOG(odinlog,significantDebug) << "rewind.get_duration()=" << rewind.get_duration() << STD_endl; //////////////// Phase Encoding: ////////////////////////// pe=SeqGradPhaseEnc("pe",commonPars->get_MatrixSize(phaseDirection),geometryInfo->get_FOV(phaseDirection), phaseDirection,0.25*systemInfo->get_max_grad(), linearEncoding,noReorder,1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, commonPars->get_PartialFourier()); pe_rewind=pe; pe_rewind.set_label("pe_rewind"); pe_rewind.invert_strength(); /////////////////// RF Spoiling /////////////////////////////////////////////////////// if(commonPars->get_RFSpoiling()) { // recommended by Goerke et al., NMR Biomed. 18, 534-542 (2005) // int plistsize=16; // double plistincr=45.0; // Handbook of MRI int plistsize=80; double plistincr=117.0; exc.set_phasespoiling(plistsize, plistincr); refoc.set_phasespoiling(plistsize, plistincr, 90.0); ge_acq.set_phasespoiling(plistsize, plistincr); se_acq.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); phaseiter.add_vector(ge_acq.get_phaselist_vector()); phaseiter.add_vector(se_acq.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over phase encoding peloop=SeqObjLoop("peloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over EPI modules echoloop=SeqObjLoop("echoloop"); // loop to iterate over dummy cycles dummyloop=SeqObjLoop("dummyloop"); //////////////// Timing Delays: ////////////////////////////// // TR delay trdelay=SeqDelay("trdelay"); //////////////// Spoiler Gradient: ////////////////////////////// float spoiler_strength=0.5*systemInfo->get_max_grad(); float spoiler_integral=4.0*fabs(deph.get_gradintegral().sum()); float spoiler_dur=secureDivision(spoiler_integral,spoiler_strength); spoiler=SeqGradConstPulse("spoiler",sliceDirection,spoiler_strength,spoiler_dur); // zoomspoiler=SeqGradConstPulse("zoomspoiler",readDirection,spoiler_strength,0.5*spoiler_dur); //////////////// Crusher Gradient: ////////////////////////////// float crusher_strength=0.3*systemInfo->get_max_grad(); // Moderate strength to avoid problems with stimulation float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, crusher_strength); crusherdelay=SeqDelay("crusherdelay",1.0); // Small delay to avoid gradient-induced stimulation // add fat saturation to template and repetitions if(NumOfSatPulses>0) preppart += fatsat; // GE part ivector ge_iv(NumOfEchoes); int i; for(i=0; iget_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; } scan += dummyloop( slicepart_dummy )[3]; // actual scan loop scan+= reploop( peloop( slicepart )[pe][pe_rewind] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { Log odinlog(this,"method_rels"); double TEexc= exc.get_duration() - exc.get_magnetic_center(); ODINLOG(odinlog,significantDebug) << "TEexc=" << TEexc << STD_endl; // Fixed TE according to GE part double TEhalf = TEexc + gepart.get_duration() + refoc.get_magnetic_center(); commonPars->set_EchoTime(2.0*TEhalf); int nechoes_se=2*NumOfEchoes-1; // sample whole spin echo TEs.resize(NumOfEchoes+nechoes_se); double TEpreacq_ge=ge_preacq.get_duration(); double TEpreacq_se=se_preacq.get_duration(); double TEread=ge_acq.get_duration()+rewind.get_duration(); double TEacq=ge_acq.get_acquisition_center(); ODINLOG(odinlog,significantDebug) << "TEpreacq_ge/TEpreacq_se/TEread/TEacq=" << TEpreacq_ge << "/" << TEpreacq_se << "/" << TEread << "/" << TEacq << STD_endl; // GE echo times int i; for(i=0; iget_EchoTime()) << STD_endl; } } // middle readout samples SE double tediff=commonPars->get_EchoTime()-TEs[2*NumOfEchoes-1]; sedelay=tediff; ODINLOG(odinlog,normalDebug) << "tediff=" << tediff << STD_endl; for(i=0; iget_RepetitionTime()set_RepetitionTime(slicedur); trdelay=(commonPars->get_RepetitionTime()-slicedur)/double(geometryInfo->get_nSlices()); } void method_pars_set() { // extra information for the automatic reconstruction ge_acq.set_reco_vector(slice,exc); se_acq.set_reco_vector(slice,exc); ge_acq.set_reco_vector(line,pe); se_acq.set_reco_vector(line,pe); // Index for TEs ge_acq.set_reco_vector(userdef,gerewindvec); se_acq.set_reco_vector(userdef,serewindvec); recoInfo->set_DimValues(userdef,TEs); recoInfo->set_PostProc3D("usercoll | messer"); recoInfo->set_CmdLineOpts("-ff Hamming -fp 0.8"); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinspir.cpp0000644000175000017500000002221711322062347013731 00000000000000////////////////////////////////////////////////////////////////////////////// // // A simple spiral sequence // ////////////////////////////////////////////////////////////////////////////// // includes for the sequence objects #include ////////////////////////////////////////////////////////////////////////////// // The method itself is a class that is derived from // an abstract base class 'SeqMethod' that contains all // routines common to all methods: class METHOD_CLASS : public SeqMethod { public: // Constructor that takes the methods identifier (unique string) as its argument METHOD_CLASS(const STD_string& label); // virtual functions that are overwritten in this method to build the sequence, // calculate parameter relations, etc.: void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); private: // Parameters for this method: JDXint SpiralSegments; JDXbool InOutSpiral; JDXfloat OptimizedPar; JDXtrajectory Trajectory; JDXbool FieldMap; JDXbool FatSaturation; JDXfloatArr DensityComp; JDXdouble ReadoutDuration; JDXint DisplaySegment; JDXfloatArr kx; JDXfloatArr ky; // Sequence objects for this method: SeqPulsar exc; SeqSat fatsat; SeqDelay echodelay; SeqDelay relaxdelay; SeqObjLoop sliceloop; SeqObjLoop segloop; SeqObjLoop reploop; SeqObjList kernel; SeqObjList segpart; SeqObjList scan; SeqAcqSpiral spiral; SeqFieldMap fmapscan; }; ////////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { // Put in here all stuff that will once be initialised and // never changed // Specify a short description of the method set_description("A simple sequence with different spiral k-space trajectories. " "Optionally, a fieldmap can be acquired prior to the actual scan " "which will be used for conjugate-phase multi-frequency reconstruction. "); } ////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_init() { // In this function the methods parameters will be initialised // Assign default values: commonPars->set_RepetitionTime(1000.0); commonPars->set_EchoTime(0.0); commonPars->set_AcqSweepWidth(100.0); commonPars->set_MatrixSize(readDirection,64); commonPars->set_MatrixSize(phaseDirection,64,noedit); Trajectory.set_function_mode(twoDeeMode); Trajectory.set_funcpars("WrapSpiral(32,0.80)"); // Default trajectory Trajectory.set_description("Spiral trajectory"); append_parameter(Trajectory,"Trajectory"); // Make method specific parameters visible in the user interface SpiralSegments=8; SpiralSegments.set_description("Number of spiral interleaves"); append_parameter(SpiralSegments,"SpiralSegments"); InOutSpiral=false; InOutSpiral.set_description("Spiral-in spiral-out readout"); append_parameter(InOutSpiral,"InOutSpiral"); OptimizedPar=-1.0; OptimizedPar.set_description("Optimize trajectory for minimum readout length if trajectory has a free tunable parameter. Set this parameter to a negative value to trigger optimization."); append_parameter(OptimizedPar,"OptimizedPar"); ReadoutDuration.set_description("Total length of spiral readout"); append_parameter(ReadoutDuration,"ReadoutDuration",noedit); DensityComp.set_filemode(exclude); DisplaySegment.set_filemode(exclude); kx.set_filemode(exclude); ky.set_filemode(exclude); if(systemInfo->get_platform()!=numaris_4) { append_parameter(DensityComp,"DensityComp"); append_parameter(DisplaySegment,"DisplaySegment"); append_parameter(kx,"kx"); append_parameter(ky,"ky"); } FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); append_parameter(FatSaturation,"FatSaturation"); FieldMap=true; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); } ////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_seq_init() { // Put in here all stuff to create the layout of the sequence ///////////////// Excitation Pulse: ///////////////////// // Get the slice thickness from the global geometry handler 'geometryInfo': float slicethick=geometryInfo->get_sliceThickness(); // Create the sinc shaped excitation pulse. exc=SeqPulsarSinc("exc",slicethick,true,2.0,commonPars->get_FlipAngle()); // Set the frequency list of the excitation pulse so that we will excite all slices in the slicepack exc.set_freqlist( systemInfo->get_gamma("") * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); // This is useful for simulating/visualization of the sequence exc.set_pulse_type(excitation); // This loop object is used to loop over the slices sliceloop=SeqObjLoop("sliceloop"); ///////////////// Fat saturation Pulse: ///////////////////// fatsat=SeqSat("fatsat",fat); ////////////////// Geometry: ///////////////////////////////// float fov=geometryInfo->get_FOV(readDirection); unsigned int sizeRadial=commonPars->get_MatrixSize(readDirection); commonPars->set_MatrixSize(phaseDirection,sizeRadial,noedit); // check bounds if(SpiralSegments<1) SpiralSegments=1; if(SpiralSegments>int(sizeRadial/2)) SpiralSegments=sizeRadial/2; //////////////// Spiral Readout: ////////////////////////////// // Perform optimization only if requested manually, i.e. if OptimizedPar<0.0 bool optimize=(OptimizedPar<0.0); if(!optimize) Trajectory.set_parameter(_TRAJ_OPTIMIZE_PARLABEL_,ftos(OptimizedPar)); spiral=SeqAcqSpiral("spiral",commonPars->get_AcqSweepWidth(),fov,sizeRadial,SpiralSegments,Trajectory,InOutSpiral,optimize); // Cache calculated value (e.g. for calculation on VxWorks) if(optimize) OptimizedPar=atof(Trajectory.get_parameter(_TRAJ_OPTIMIZE_PARLABEL_).c_str()); //////////////// Delays: ////////////////////////////// // relaxation delay after each readout relaxdelay=SeqDelay("relaxdelay"); // delay to obtain correct TE echodelay=SeqDelay("echodelay"); //////////////// Loops: ////////////////////////////// // Construct a loop object to iterate through the phase encoding DisplaySegments segloop=SeqObjLoop("segloop"); // Construct a loop object to perform repetitions of the experiment reploop=SeqObjLoop("reploop"); //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0); } //////////////// Build the Sequence: /////////////// // This sequence container will hold the objects for one readout: kernel=SeqObjList("kernel"); // This sequence container will hold the objects for one slicepack: segpart=SeqObjList("segpart"); scan=SeqObjList("scan"); if(FatSaturation) { kernel += fatsat; } kernel += exc + echodelay + spiral; segpart = segloop( sliceloop( kernel + relaxdelay )[exc] )[spiral.get_segment_vector()]; if(FieldMap) scan += fmapscan + relaxdelay; scan += reploop( segpart )[commonPars->get_NumOfRepetitions()]; // Finally, build the whole sequence set_sequence( scan ); } ////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_rels() { // Put in here all stuff that has to be performed whenever one of the sequence parameters // has been changed by the user // calculate relaxdelay to get the desired repetition time float scandur=kernel.get_duration()*float(geometryInfo->get_nSlices()); if(scandur>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scandur); relaxdelay.set_duration( (commonPars->get_RepetitionTime()-scandur)/float(geometryInfo->get_nSlices()) ); // set TE float min_echo_time=(exc.get_duration()-exc.get_magnetic_center())+(spiral.get_acquisition_center()); if (commonPars->get_EchoTime()set_EchoTime(min_echo_time); echodelay=commonPars->get_EchoTime()-min_echo_time; ReadoutDuration=secureDivision(double(spiral.get_npts()),commonPars->get_AcqSweepWidth()) ; if(systemInfo->get_platform()!=numaris_4) { DensityComp=spiral.get_denscomp(); kx=spiral.get_ktraj(DisplaySegment,readDirection); ky=spiral.get_ktraj(DisplaySegment,phaseDirection); } } ////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_set() { Log odinlog(this,"method_pars_set"); // Put in here all stuff that has to be performed after the parameters have been edited by the user // and before the sequence is played out spiral.set_reco_vector(slice,exc); } ////////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odindti.cpp0000644000175000017500000003744411455553544013557 00000000000000#include class METHOD_CLASS : public SeqMethod { private: JDXfloat bValue; JDXint NumOfDirections; JDXint b0Rate; JDXfloat GradStrength; JDXint Blades; JDXbool ShortAxis; JDXenum TemplateScan; JDXbool RampSampling; JDXenum RampMode; JDXfloat RampSteepness; JDXbool FatSaturation; JDXint DummyCycles; JDXint NumOfGradEchoes; JDXint NumOfSamples; JDXdouble PulseDur; JDXbool FieldMap; SeqPulsar exc; SeqPulsar refoc; SeqSat fatsat; SeqAcqEPI epiacq; SeqObjList epipart; SeqDelay epiacq_dummy; SeqObjList epipart_dummy; SeqAcqEPI epiacq_template; SeqObjList epipart_template; SeqAcqEPI epiacq_grappa; SeqObjList epipart_grappa; SeqAcqDeph deph; SeqAcqDeph deph_template; SeqAcqDeph deph_grappa; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop bladeloop; SeqObjLoop grappaloop; SeqObjLoop dummyloop; SeqObjLoop dwloop; SeqDelay trdelay; SeqObjList scan; SeqObjList dummypart; SeqObjList templatepart; SeqObjList grappapart; SeqObjList imagingpart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList slicepart_template; SeqObjList slicepart_grappa; SeqObjList preppart; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqTrigger trigger; SeqGradTrapezParallel spoiler; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqFieldMap fmapscan; SeqVecIter phaseiter; SeqDiffWeight dw; SeqObjList midpart; SeqRotMatrixVector bladerot; SeqHalt physiotrigger; dvector bladeangels; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("Diffusion tensor sequence based on PROPELLER-EPI. A simple Stejskal-Tanner gradient pair around the refocusing pulse is used for diffusion weighting."); } void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,128); commonPars->set_MatrixSize(phaseDirection,128,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); commonPars->set_PhysioTrigger(true); bValue=1000.0; bValue.set_unit("s/mm^2").set_description("Uniform b-value"); NumOfDirections=6; NumOfDirections.set_description("Number of uniformly distributed diffusion directions"); b0Rate=5; b0Rate.set_description("Rate of b0 scans interleaved wit diffusion weighting"); GradStrength=80.0; GradStrength.set_minmaxval(0.0,100.0).set_unit("%").set_description("Relative strength of diffusion-weighting gradients"); Blades=8; Blades.set_description("Number of PROPELLER blades"); ShortAxis=false; ShortAxis.set_description("Readout direction along short axis of blades"); TemplateScan.add_item("NoCorrection"); TemplateScan.add_item("PhaseCorrection"); TemplateScan.set_actual("PhaseCorrection"); TemplateScan.set_description("The type of template scan which is acquired beforehand"); RampSampling=false; RampSampling.set_description("Perform sampling during gradient ramps"); RampMode.add_item("linear",linear); RampMode.add_item("sinusoidal",sinusoidal); RampMode.add_item("half_sinusoidal",half_sinusoidal); RampMode.set_actual(linear); RampMode.set_description("The shape of the ramps of the read gradient"); RampSteepness=1.0; RampSteepness.set_description("Relative steepness (slew rate) of the EPI readout ramps"); FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); FieldMap=false; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); PulseDur=4.0; // avoid initial high RF amplitude PulseDur.set_description("Pulse duration of excitation/refocusing pulse"); // register method parameters for user interface, parameter files, etc. append_parameter(bValue,"bValue"); append_parameter(NumOfDirections,"NumOfDirections"); append_parameter(b0Rate,"b0Rate"); append_parameter(GradStrength,"GradStrength"); append_parameter(Blades,"Blades"); append_parameter(ShortAxis,"ShortAxis"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(TemplateScan,"TemplateScan"); append_parameter(RampSampling,"RampSampling"); append_parameter(FatSaturation,"FatSaturation"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); append_parameter(PulseDur,"PulseDur"); if(systemInfo->get_platform()!=numaris_4) { append_parameter(RampMode,"RampMode"); append_parameter(RampSteepness,"RampSteepness"); append_parameter(NumOfGradEchoes,"NumOfGradEchoes",noedit); append_parameter(NumOfSamples,"NumOfSamples",noedit); } } void method_seq_init() { ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float slicegap=geometryInfo->get_sliceDistance()-slicethick; // excitation pulse exc=SeqPulsarSinc("exc",slicethick,true,PulseDur,commonPars->get_FlipAngle()); exc.set_rephased(true, 0.8*systemInfo->get_max_grad()); // short rephaser exc.set_freqlist( systemInfo->get_gamma() * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); // Slightly thicker refocusing slice for better SNR // Since the same spatial resolution is used for exc and refoc, the gradient strengths will be the same float extra_slicethick_refoc=STD_min(0.5*slicethick, 0.3*slicegap); // refocusing pulse refoc=SeqPulsarSinc("refoc",slicethick+extra_slicethick_refoc,false,PulseDur,180.0); refoc.set_freqlist( systemInfo->get_gamma() * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(!commonPars->get_RFSpoiling()) refoc.set_phase(90.0); refoc.set_pulse_type(refocusing); // fat saturation module fatsat=SeqSat("fatsat",fat); //////////////// EPI-Readout: ////////////////////////////// // square FOV int sizeRadial=commonPars->get_MatrixSize(readDirection); commonPars->set_MatrixSize(phaseDirection,sizeRadial,noedit); int readpts_blade=sizeRadial; int pelines_blade=sizeRadial; int bladewidth=sizeRadial; if(Blades>1) bladewidth=int(0.5*PII*sizeRadial/Blades+0.5); if(ShortAxis) readpts_blade=bladewidth; else pelines_blade=bladewidth; float os_read=2.0; // For reduced undersampling artifacts float fov=geometryInfo->get_FOV(readDirection); // uniform FOV epiacq=SeqAcqEPI("epiacq",commonPars->get_AcqSweepWidth(), readpts_blade, fov, pelines_blade, fov, 1, commonPars->get_ReductionFactor(), os_read, "", 0, 0, rampType(int(RampMode)), RampSampling, RampSteepness, commonPars->get_PartialFourier()); // display sampling extents in read/phase direction NumOfGradEchoes=epiacq.get_numof_gradechoes(); NumOfSamples=epiacq.get_npts_read(); // Template scan fo EPI, begin with copy of actual EPI epiacq_template=epiacq; epiacq_template.set_label("epiacq_template"); // 1D phase correction if(TemplateScan=="PhaseCorrection") { epiacq_template.set_template_type(phasecorr_template); } // Full multi-shot EPI readout as GRAPPA training data epiacq_grappa=epiacq; epiacq_grappa.set_label("epiacq_grappa"); epiacq_grappa.set_template_type(grappa_template); // Delay instead of actual EPI readout for dummy scans epiacq_dummy=SeqDelay("epiacq_dummy",epiacq.get_duration()); // EPI pre-dephase gradient deph=SeqAcqDeph("deph",epiacq); deph_template=SeqAcqDeph("deph_template",epiacq_template); deph_grappa=SeqAcqDeph("deph_grappa",epiacq_grappa); /////////////////// Rotation of Blades //////////////////////////////////////////////// bladerot=SeqRotMatrixVector("bladerot"); bladeangels.resize(Blades); for(int iblade=0; ibladeget_RFSpoiling()) { // Use defaults for phase spoiling int plistsize=80; double plistincr=117.0; exc.set_phasespoiling(plistsize, plistincr); refoc.set_phasespoiling(plistsize, plistincr, 90.0); epiacq.set_phasespoiling(plistsize, plistincr); epiacq_template.set_phasespoiling(plistsize, plistincr); epiacq_grappa.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); phaseiter.add_vector(epiacq.get_phaselist_vector()); phaseiter.add_vector(epiacq_template.get_phaselist_vector()); phaseiter.add_vector(epiacq_grappa.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over blades bladeloop=SeqObjLoop("bladeloop"); // loop to iterate over GRAPPA interleaves to obtain training data grappaloop=SeqObjLoop("grappaloop"); // loop to iterate over dummy scans dummyloop=SeqObjLoop("dummyloop"); // loop to iterate over diffusion weighting dwloop=SeqObjLoop("dwloop"); //////////////// Timing Delays: ////////////////////////////// trdelay=SeqDelay("trdelay"); //////////////// Spoiler Gradient: ////////////////////////////// double spoiler_strength=0.5*systemInfo->get_max_grad(); double spoiler_integral=2.0*fabs(deph.get_gradintegral().sum()); // on all three axes for uniform b-value spoiler=SeqGradTrapezParallel("spoiler",spoiler_integral,spoiler_integral,spoiler_integral, spoiler_strength); //////////////// Crusher Gradient: ////////////////////////////// float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, spoiler_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0); } //////////////// Diffusion weighting: ////////////////////////////// fvector bvals(1); bvals[0]=1000.0*bValue; midpart = spoiler + refoc + spoiler; dw=SeqDiffWeight("dw", NumOfDirections, bvals, 0.01*GradStrength*systemInfo->get_max_grad(), midpart, b0Rate, true); //////////////// Build the sequence: ////////////////////////////// // add physiological trigger physiotrigger=SeqHalt("physiotrigger"); if(commonPars->get_PhysioTrigger()) preppart += physiotrigger; // add fat saturation to template and repetitions if(FatSaturation) preppart += fatsat; // Rotate deph and epi simultaneously epipart_dummy =SeqObjList("epipart_dummy"); epipart_template=SeqObjList("epipart_template"); epipart_grappa =SeqObjList("epipart_grappa"); epipart =SeqObjList("epipart"); epipart_dummy += deph + epiacq_dummy; epipart_template+= deph_template + epiacq_template; epipart_grappa += deph_grappa + epiacq_grappa; epipart += deph + epiacq; epipart_dummy .set_gradrotmatrixvector(bladerot); epipart_template.set_gradrotmatrixvector(bladerot); epipart_grappa .set_gradrotmatrixvector(bladerot); epipart .set_gradrotmatrixvector(bladerot); dummypart= preppart + exc + exc2refoc + dw + refoc2acq + epipart_dummy + crusherdelay + crusher; templatepart= preppart + exc + exc2refoc + dw + refoc2acq + epipart_template + crusherdelay + crusher; grappapart= preppart + exc + exc2refoc + dw + refoc2acq + epipart_grappa + crusherdelay + crusher; imagingpart= preppart + exc + exc2refoc + dw + refoc2acq + epipart + crusherdelay + crusher; slicepart_dummy = sliceloop( dummypart + trdelay )[exc][refoc]; slicepart_template = sliceloop( templatepart + trdelay )[exc][refoc]; slicepart_grappa = sliceloop( grappapart + trdelay )[exc][refoc]; slicepart += sliceloop( imagingpart + trdelay )[exc][refoc]; if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; slicepart_template += phaseiter; slicepart_grappa += phaseiter; } if(FieldMap) scan += fmapscan + trdelay; if(DummyCycles>0) { scan+= dummyloop( slicepart_dummy )[DummyCycles]; } if(TemplateScan=="PhaseCorrection") { scan += bladeloop( // Use b0 scan for phase correction of all slicepart_template )[bladerot]; } if(commonPars->get_ReductionFactor()>1) { // Fully sampled k-space scan+= grappaloop( // Use b0 scan for interpolation of all bladeloop( slicepart_grappa )[bladerot] )[deph_grappa.get_epi_reduction_vector()]; } scan+= reploop( dwloop( bladeloop( slicepart )[bladerot] )[dw] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { ////////////////// TE Timings: //////////////////////////////// double min_echo_time=0.0; //////////////// Duration from the middle of the excitation pulse /////////////////// //////////////// to the middle of the refocusing pulse: ///////////////////////////// double TE1=( exc.get_duration() - exc.get_magnetic_center() ) + dw.get_grad1_duration() + spoiler.get_duration() + refoc.get_magnetic_center(); if(min_echo_time<(2.0*TE1)) min_echo_time=2.0*TE1; //////////////// Duration from the middle of the refocusing pulse /////////////////// //////////////// to the middle of the acquisition window: /////////////////////////// double TE2=(refoc.get_duration() - refoc.get_magnetic_center()) + spoiler.get_duration() + dw.get_grad2_duration() + deph.get_duration() + epiacq.get_acquisition_center(); if(min_echo_time<(2.0*TE2)) min_echo_time=2.0*TE2; if (commonPars->get_EchoTime()set_EchoTime(min_echo_time); commonPars->set_EchoTime(min_echo_time); exc2refoc=commonPars->get_EchoTime()/2.0-TE1; refoc2acq=commonPars->get_EchoTime()/2.0-TE2; ////////////////// TR Timings: //////////////////////////////// // reset before recalculating timings trdelay=0.0; float slicedur=slicepart.get_duration(); if(commonPars->get_PhysioTrigger()) { commonPars->set_RepetitionTime(slicedur); // set to minimum TR } else { if(commonPars->get_RepetitionTime()set_RepetitionTime(slicedur); trdelay=(commonPars->get_RepetitionTime()-slicedur)/double(geometryInfo->get_nSlices()); } } void method_pars_set() { // extra information for the automatic reconstruction epiacq.set_reco_vector(slice,exc); epiacq_template.set_reco_vector(slice,exc); epiacq_grappa.set_reco_vector(slice,exc); epiacq.set_reco_vector(cycle,bladerot); epiacq_template.set_reco_vector(cycle,bladerot); epiacq_grappa.set_reco_vector(cycle,bladerot); recoInfo->set_DimValues(cycle,bladeangels); epiacq.set_reco_vector(dti, dw); epiacq_template.set_reco_vector(dti, dw); epiacq_grappa.set_reco_vector(dti, dw); recoInfo->set_DimValues(dti, dw.get_b_vectors()); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinepi.cpp0000644000175000017500000004155011322062347013532 00000000000000 // include the headers of all sequence classes #include // The whole EPI sequence is a C++ class class METHOD_CLASS : public SeqMethod { private: // this section contains the data elements of the sequence, // i.e. the sequence specific parameters and the sequence objects // the following parameters are specific to EPI sequences, // parameters common to all sequences can be accessed via the // 'commonPars' global object JDXbool TakeMinEchoTime; JDXenum SliceTimingMode; JDXenum TemplateScan; JDXbool RampSampling; JDXenum RampMode; JDXfloat RampSteepness; JDXbool FatSaturation; JDXenum EPIMode; JDXint Shots; JDXint DummyCycles; JDXint NumOfGradEchoes; JDXint NumOfSamples; JDXdouble PulseDur; JDXbool fMRITrigger; JDXint fMRIBlockSize; JDXbool FieldMap; // sequence objects which are the elementary objects // to build the EPI sequence SeqPulsar exc; SeqPulsar refoc; SeqSat fatsat; SeqAcqEPI epiacq; SeqDelay epiacq_dummy; SeqAcqEPI epiacq_template; SeqAcqEPI epiacq_grappa; SeqAcqDeph deph; SeqAcqDeph deph_template; SeqAcqDeph deph_grappa; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop segloop; SeqObjLoop grappaloop; SeqObjLoop dummyloop; SeqDelay delayuniform; SeqDelay delaybunched; SeqObjList scan; SeqObjList dummypart; SeqObjList templatepart; SeqObjList grappapart; SeqObjList imagingpart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList slicepart_template; SeqObjList slicepart_grappa; SeqObjList preppart; SeqDelay exc2acq; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqGradConstPulse spoiler; SeqTrigger trigger; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqFieldMap fmapscan; SeqVecIter phaseiter; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("This is a feature-rich multislice EPI method. " "The template scan for phase correction is sampled before the repetitions. " "A field-map scan can be acquired prior to the actual scan for distortion correction."); } unsigned int numof_testcases() const {return 3;} void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,64); commonPars->set_MatrixSize(phaseDirection,64,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); SliceTimingMode.add_item("EPIuniform"); SliceTimingMode.add_item("EPIbunchedEarly"); SliceTimingMode.set_actual("EPIuniform"); SliceTimingMode.set_description("Scanning of slices uniformly distributed over TR (EPIuniform) or bunched at the start (EPIbunchedEarly)"); EPIMode.add_item("FIDMode"); EPIMode.add_item("SEMode"); EPIMode.set_actual("FIDMode"); EPIMode.set_description("Gradient-echo EPI (FIDMode) or spin-echo EPI (SEMode)"); TemplateScan.add_item("NoCorrection"); TemplateScan.add_item("PhaseCorrection"); TemplateScan.set_actual("PhaseCorrection"); TemplateScan.set_description("The type of template scan which is acquired beforehand"); RampSampling=false; RampSampling.set_description("Perform sampling during gradient ramps"); RampMode.add_item("linear",linear); RampMode.add_item("sinusoidal",sinusoidal); RampMode.add_item("half_sinusoidal",half_sinusoidal); RampMode.set_actual(linear); RampMode.set_description("The shape of the ramps of the read gradient"); RampSteepness=1.0; RampSteepness.set_description("Relative steepness (slew rate) of the EPI readout ramps"); FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); TakeMinEchoTime=true; TakeMinEchoTime.set_description("Use minimum possible TE"); Shots=1; Shots.set_description("Number of shots, multi-shot (segmented) EPI if Shots>1"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); fMRITrigger=true; fMRITrigger.set_description("External triggering"); fMRIBlockSize=0; fMRIBlockSize.set_description("If non-zero, fMRI analysis will be performed with this size for both stimulation and rest"); FieldMap=false; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); PulseDur=4.0; // avoid initial high RF amplitude PulseDur.set_description("Pulse duration of excitation/refocusing pulse"); // alternative default settings for sequence test if(get_current_testcase()==1) { EPIMode.set_actual("SEMode"); RampSteepness=0.8; RampSampling=true; FatSaturation=false; DummyCycles=0; commonPars->set_PartialFourier(0.7); } if(get_current_testcase()==2) { TemplateScan.set_actual("NoCorrection"); Shots=3; FieldMap=true; commonPars->set_RFSpoiling(false); } // register method parameters for user interface, parameter files, etc. append_parameter(EPIMode,"EPIMode"); append_parameter(TakeMinEchoTime,"TakeMinEchoTime"); append_parameter(Shots,"Shots"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(TemplateScan,"TemplateScan"); append_parameter(RampSampling,"RampSampling"); append_parameter(FatSaturation,"FatSaturation"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); append_parameter(fMRITrigger,"fMRITrigger"); append_parameter(fMRIBlockSize,"fMRIBlockSize"); append_parameter(PulseDur,"PulseDur"); if(systemInfo->get_platform()!=numaris_4) { append_parameter(RampMode,"RampMode"); append_parameter(RampSteepness,"RampSteepness"); append_parameter(SliceTimingMode,"SliceTimingMode"); append_parameter(NumOfGradEchoes,"NumOfGradEchoes",noedit); append_parameter(NumOfSamples,"NumOfSamples",noedit); } } void method_seq_init() { ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float slicegap=geometryInfo->get_sliceDistance()-slicethick; // excitation pulse exc=SeqPulsarSinc("exc",slicethick,true,PulseDur,commonPars->get_FlipAngle()); exc.set_rephased(true, 0.8*systemInfo->get_max_grad()); // short rephaser exc.set_freqlist( systemInfo->get_gamma() * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); // Slightly thicker refocusing slice for better SNR // Since the same spatial resolution is used for exc and refoc, the gradient strengths will be the same float extra_slicethick_refoc=STD_min(0.5*slicethick, 0.3*slicegap); // refocusing pulse refoc=SeqPulsarSinc("refoc",slicethick+extra_slicethick_refoc,false,PulseDur,180.0); refoc.set_freqlist( systemInfo->get_gamma() * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(!commonPars->get_RFSpoiling()) refoc.set_phase(90.0); refoc.set_pulse_type(refocusing); // fat saturation module fatsat=SeqSat("fatsat",fat); //////////////// EPI-Readout: ////////////////////////////// // set equivalent resolution in read and phase direction float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); int pelines=int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5); float os_read=1.2; // slight oversampling to allow off-center FOV epiacq=SeqAcqEPI("epiacq",commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), pelines, geometryInfo->get_FOV(phaseDirection), Shots, commonPars->get_ReductionFactor(), os_read, "", 0, 0, rampType(int(RampMode)), RampSampling, RampSteepness, commonPars->get_PartialFourier()); // display sampling extents in read/phase direction NumOfGradEchoes=epiacq.get_numof_gradechoes(); commonPars->set_MatrixSize(phaseDirection,NumOfGradEchoes*Shots*commonPars->get_ReductionFactor(),noedit); NumOfSamples=epiacq.get_npts_read(); // Template scan fo EPI, begin with copy of actual EPI epiacq_template=epiacq; epiacq_template.set_label("epiacq_template"); // 1D phase correction if(TemplateScan=="PhaseCorrection") { epiacq_template.set_template_type(phasecorr_template); } // Full multi-shot EPI readout as GRAPPA training data epiacq_grappa=epiacq; epiacq_grappa.set_label("epiacq_grappa"); epiacq_grappa.set_template_type(grappa_template); // Delay instead of actual EPI readout for dummy scans epiacq_dummy=SeqDelay("epiacq_dummy",epiacq.get_duration()); // EPI pre-dephase gradient dephaseMode dephmode=FID; if (EPIMode=="SEMode") dephmode=spinEcho; deph=SeqAcqDeph("deph",epiacq,dephmode); deph_template=SeqAcqDeph("deph_template",epiacq_template,dephmode); deph_grappa=SeqAcqDeph("deph_grappa",epiacq_grappa,dephmode); /////////////////// RF Spoiling /////////////////////////////////////////////////////// if(commonPars->get_RFSpoiling()) { // recommended by Goerke et al., NMR Biomed. 18, 534-542 (2005) int plistsize=16; double plistincr=45.0; exc.set_phasespoiling(plistsize, plistincr); refoc.set_phasespoiling(plistsize, plistincr, 90.0); epiacq.set_phasespoiling(plistsize, plistincr); epiacq_template.set_phasespoiling(plistsize, plistincr); epiacq_grappa.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); phaseiter.add_vector(epiacq.get_phaselist_vector()); phaseiter.add_vector(epiacq_template.get_phaselist_vector()); phaseiter.add_vector(epiacq_grappa.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over segments (multi shot) segloop=SeqObjLoop("segloop"); // loop to iterate over GRAPPA interleaves to obtain training data grappaloop=SeqObjLoop("grappaloop"); // loop to iterate over dummy scans dummyloop=SeqObjLoop("dummyloop"); //////////////// Timing Delays: ////////////////////////////// // Delays uniform/bunched delayuniform=SeqDelay("delayuniform"); delaybunched=SeqDelay("delaybunched"); //////////////// Spoiler Gradient: ////////////////////////////// double spoiler_strength=0.5*systemInfo->get_max_grad(); double spoiler_integral=4.0*fabs(deph.get_gradintegral().sum()); double spoiler_dur=secureDivision(spoiler_integral,spoiler_strength); spoiler=SeqGradConstPulse("spoiler",readDirection,spoiler_strength,spoiler_dur); //////////////// Crusher Gradient: ////////////////////////////// float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, spoiler_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// fMRI trigger: ////////////////////////////// trigger=SeqTrigger("fmri_trigger",1.0); //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),os_read,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),os_read); } //////////////// Build the sequence: ////////////////////////////// // add fat saturation to template and repetitions if(FatSaturation) preppart += fatsat; if(fMRITrigger) slicepart += trigger; if (EPIMode=="FIDMode") { dummypart= preppart + exc + deph + exc2acq + epiacq_dummy + crusherdelay + crusher; templatepart= preppart + exc + deph_template + exc2acq + epiacq_template + crusherdelay + crusher; grappapart= preppart + exc + deph_grappa + exc2acq + epiacq_grappa + crusherdelay + crusher; imagingpart= preppart + exc + deph + exc2acq + epiacq + crusherdelay + crusher; slicepart_dummy = sliceloop( dummypart + delayuniform )[exc]; slicepart_template = sliceloop( templatepart + delayuniform )[exc]; slicepart_grappa = sliceloop( grappapart + delayuniform )[exc]; slicepart += sliceloop( imagingpart + delayuniform )[exc]; } if (EPIMode=="SEMode") { dummypart= preppart + exc + exc2refoc + deph + spoiler + refoc + spoiler + refoc2acq + epiacq_dummy + crusherdelay + crusher; templatepart= preppart + exc + exc2refoc + deph_template + spoiler + refoc + spoiler + refoc2acq + epiacq_template + crusherdelay + crusher; grappapart= preppart + exc + exc2refoc + deph_grappa + spoiler + refoc + spoiler + refoc2acq + epiacq_grappa + crusherdelay + crusher; imagingpart= preppart + exc + exc2refoc + deph + spoiler + refoc + spoiler + refoc2acq + epiacq + crusherdelay + crusher; slicepart_dummy = sliceloop( dummypart + delayuniform )[exc][refoc]; slicepart_template = sliceloop( templatepart + delayuniform )[exc][refoc]; slicepart_grappa = sliceloop( grappapart + delayuniform )[exc][refoc]; slicepart += sliceloop( imagingpart + delayuniform )[exc][refoc]; } if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; slicepart_template += phaseiter; slicepart_grappa += phaseiter; } if(FieldMap) scan += fmapscan + delayuniform + delaybunched; if(DummyCycles>0) { scan+= dummyloop( slicepart_dummy + delaybunched )[DummyCycles]; } if(TemplateScan=="PhaseCorrection") { scan += slicepart_template + delaybunched; // phasecorr requires only one shot from template } if(commonPars->get_ReductionFactor()>1) { // Fully sampled k-space scan+= grappaloop( segloop( slicepart_grappa + delaybunched )[deph_grappa.get_epi_segment_vector()] )[deph_grappa.get_epi_reduction_vector()]; } scan+= reploop( segloop( slicepart + delaybunched )[deph.get_epi_segment_vector()] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { ////////////////// TE Timings: //////////////////////////////// double min_echo_time=0.0; if (EPIMode=="FIDMode") { min_echo_time=(exc.get_duration()-exc.get_magnetic_center())+deph.get_duration()+epiacq.get_acquisition_center(); if(commonPars->get_EchoTime()set_EchoTime(min_echo_time); if(TakeMinEchoTime) commonPars->set_EchoTime(min_echo_time); exc2acq=commonPars->get_EchoTime()-min_echo_time; } if (EPIMode=="SEMode") { //////////////// Duration from the middle of the excitation pulse /////////////////// //////////////// to the middle of the refocusing pulse: ///////////////////////////// double TE1=( exc.get_duration() - exc.get_magnetic_center() ) + deph.get_duration() + spoiler.get_duration() + refoc.get_magnetic_center(); if(min_echo_time<(2.0*TE1)) min_echo_time=2.0*TE1; //////////////// Duration from the middle of the refocusing pulse /////////////////// //////////////// to the middle of the acquisition window: /////////////////////////// double TE2=(refoc.get_duration() - refoc.get_magnetic_center()) + spoiler.get_duration() + epiacq.get_acquisition_center(); if(min_echo_time<(2.0*TE2)) min_echo_time=2.0*TE2; if (commonPars->get_EchoTime()set_EchoTime(min_echo_time); if(TakeMinEchoTime) commonPars->set_EchoTime(min_echo_time); exc2refoc=commonPars->get_EchoTime()/2.0-TE1; refoc2acq=commonPars->get_EchoTime()/2.0-TE2; } ////////////////// TR Timings: //////////////////////////////// // reset before recalculating timings delayuniform=0.0; delaybunched=0.0; float slicedur=slicepart.get_duration(); if(commonPars->get_RepetitionTime()set_RepetitionTime(slicedur); if (SliceTimingMode=="EPIuniform") { delayuniform=(commonPars->get_RepetitionTime()-slicedur)/double(geometryInfo->get_nSlices()); delaybunched=0.0; } if (SliceTimingMode=="EPIbunchedEarly") { delaybunched=commonPars->get_RepetitionTime()-slicedur; delayuniform=0.0; } } void method_pars_set() { // extra information for the automatic reconstruction epiacq.set_reco_vector(slice,exc); epiacq_template.set_reco_vector(slice,exc); epiacq_grappa.set_reco_vector(slice,exc); if(fMRIBlockSize>0) recoInfo->set_PostProc3D("repcoll | fmri("+itos(fMRIBlockSize)+","+itos(fMRIBlockSize)+")"); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinonep.cpp0000644000175000017500000001070311322062347013712 00000000000000#include class METHOD_CLASS : public SeqMethod { public: METHOD_CLASS(const STD_string& label); void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); private: JDXenum OnepulseMode; JDXint NumOfSamples; JDXdouble PulseDuration; JDXdouble FreqOffset; SeqPulsarBP exc; SeqPulsarBP refoc; SeqAcq acq; SeqDelay relaxdelay; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqObjLoop acculoop; SeqObjList scanpart; SeqGradConstPulse spoiler; SeqVector averagevec; // index vector for averages SeqVecIter phaseiter; }; //////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { set_description("A simple onepulse experiment (non-selective RF pulse + acquisition)."); } //////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_init() { OnepulseMode.add_item("FID"); OnepulseMode.add_item("SpinEcho"); OnepulseMode.set_actual("FID"); commonPars->set_EchoTime(0.0); NumOfSamples=1024; PulseDuration=1.0; FreqOffset=0.0; append_parameter(OnepulseMode,"OnepulseMode"); append_parameter(NumOfSamples,"NumOfSamples"); append_parameter(PulseDuration,"PulseDuration"); append_parameter(FreqOffset,"FreqOffset"); } //////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_seq_init() { exc=SeqPulsarBP("exc",PulseDuration,commonPars->get_FlipAngle(),systemInfo->get_main_nucleus()); exc.set_pulse_type(excitation); refoc=SeqPulsarBP("refoc",PulseDuration,180.0,systemInfo->get_main_nucleus()); refoc.set_pulse_type(refocusing); acq=SeqAcq("acq",(unsigned int)NumOfSamples,commonPars->get_AcqSweepWidth(),1.0,systemInfo->get_main_nucleus()); exc.set_freqoffset(FreqOffset); refoc.set_freqoffset(FreqOffset); acq.set_freqoffset(FreqOffset); if(commonPars->get_RFSpoiling()) { exc.set_phasespoiling(4, 90.0); acq.set_phasespoiling(4, 90.0); refoc.set_phasespoiling(4, 90.0, 90.0); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(acq.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); } else { refoc.set_phase(90.0); } spoiler=SeqGradConstPulse("spoiler",sliceDirection,0.5*systemInfo->get_max_grad(),2.0); relaxdelay=SeqDelay("relaxdelay"); exc2refoc=SeqDelay("exc2refoc"); refoc2acq=SeqDelay("refoc2acq"); acculoop=SeqObjLoop("acculoop"); if(OnepulseMode=="SpinEcho") scanpart= exc + exc2refoc + spoiler + refoc + spoiler + refoc2acq + acq + relaxdelay; else scanpart= exc + acq + spoiler + relaxdelay; if(commonPars->get_RFSpoiling()) scanpart += phaseiter; averagevec=SeqVector("averagevec",commonPars->get_NumOfRepetitions()); set_sequence( acculoop(scanpart)[averagevec] ); } //////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_rels() { float min_echo_time1=0.0; float min_echo_time2=0.0; if(OnepulseMode=="SpinEcho") { min_echo_time1=(exc.get_duration()-exc.get_magnetic_center())+spoiler.get_duration()+refoc.get_magnetic_center(); min_echo_time2=(refoc.get_duration()-refoc.get_magnetic_center())+spoiler.get_duration()+acq.get_acquisition_center(); } else { min_echo_time1=(exc.get_duration()-exc.get_magnetic_center())+acq.get_acquisition_center(); } if(commonPars->get_EchoTime()set_EchoTime(min_echo_time1); if(commonPars->get_EchoTime()set_EchoTime(min_echo_time2); exc2refoc=commonPars->get_EchoTime()-min_echo_time1; refoc2acq=commonPars->get_EchoTime()-min_echo_time2; if(scanpart.get_duration()>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scanpart.get_duration()); relaxdelay.set_duration(commonPars->get_RepetitionTime()-scanpart.get_duration()); } //////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_set() { acq.set_reco_vector(average,averagevec); recoInfo->set_Recipe("averagecoll | averagesum | kspace | fft | slicecoll | image | store"); // Quick hack to display a single spectrum from multiple averages } //////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinfisp.cpp0000644000175000017500000001477011363773557013743 00000000000000#include class METHOD_CLASS : public SeqMethod { private: SeqPulsar exc; SeqPulsarReph exc_reph; SeqPulsar exc_prep; SeqGradTrapez exc_prep_reph; SeqDelay prepdelay; SeqDelay postdelay; SeqDelay relaxdelay; SeqDelay grechdummy; SeqGradEcho grech; SeqGradConstPulse crusher; SeqObjList kernel; SeqObjList dummykernel; SeqObjList readout; SeqObjList shot; SeqObjList scan; SeqObjLoop reploop; SeqObjLoop sliceloop; SeqObjLoop peloop; SeqObjLoop phaseloop; SeqObjLoop dummyloop; JDXint DummyCycles; JDXenum PhaseEncoding; public: //////////////////////////////////////////////////// METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("Single-shot TrueFISP (balanced SSFP) sequence. See for example Scheffler et.al. Eur Radiol (2003) 13:2409-2418 "); } //////////////////////////////////////////////////// void method_pars_init() { commonPars->set_EchoTime(0.0,noedit); commonPars->set_FlipAngle(60.0); DummyCycles=3; DummyCycles.set_description("Number of dummy cycles before actual acquisition"); PhaseEncoding.add_item("Linear",linearEncoding); PhaseEncoding.add_item("CenterOut",centerOutEncoding); PhaseEncoding=linearEncoding; PhaseEncoding.set_description("Phase encoding order"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(PhaseEncoding,"PhaseEncoding"); } void method_seq_init(){ double gamma=systemInfo->get_gamma(); ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float spatres=slicethick/4.0; // Excitation Pulse exc=SeqPulsarSinc("exc",slicethick,false,2.0,commonPars->get_FlipAngle(),spatres); dvector freqlist=gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector(); exc.set_freqlist(freqlist); exc.set_pulse_type(excitation); // +/- flipangles for FISP dvector phaselist(2); phaselist[0]=0.0; phaselist[1]=180.0; exc.set_phaselist(phaselist); // rephasing lobe for excitation pulse exc_reph=SeqPulsarReph("exc_reph",exc); // initial preparation pulse exc_prep=exc; exc_prep.set_label("exc_prep"); exc_prep.set_flipangle(0.5*commonPars->get_FlipAngle()); exc_prep.set_phase(180.0); exc_prep_reph=SeqGradTrapez("exc_prep_reph",2.0*exc_reph.get_gradintegral().sum(),0.8*systemInfo->get_max_grad(),sliceDirection); ////////////////// Geometry: ///////////////////////////////// // calculate the resolution in the read Channel and set the number of phase encoding // steps so that we will obtain a uniform resolution in read and phase Channel: float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5),noedit); //////////////// Balanced Gradient Echo Module: ////////////// grech=SeqGradEcho("grech", exc, commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), encodingScheme(int(PhaseEncoding)), interleavedSegmented, 2, commonPars->get_ReductionFactor(),DEFAULT_ACL_BANDS,true,commonPars->get_PartialFourier()); grech.set_phaselist(phaselist); // +/- phase switching for SSFP //////////////// crusher Gradient: ////////////////////////////// double crusher_strength=0.5*systemInfo->get_max_grad(); double crusher_dur=4.0; crusher=SeqGradConstPulse("crusher",readDirection,crusher_strength,crusher_dur); //////////////// Loops //////////////////// reploop=SeqObjLoop("reploop"); sliceloop=SeqObjLoop("sliceloop"); peloop=SeqObjLoop("peloop"); phaseloop=SeqObjLoop("phaseloop"); //////////////// Timing Delays //////////////////// prepdelay=SeqDelay("prepdelay"); postdelay=SeqDelay("postdelay"); relaxdelay=SeqDelay("relaxdelay"); grechdummy=SeqDelay("grechdummy",grech.get_duration()-exc.get_duration()-exc_prep_reph.get_duration()); //////////////// building the sequence ////////////////////////////// kernel=SeqObjList("kernel"); kernel= grech + postdelay; dummykernel=SeqObjList("dummykernel"); dummykernel = exc + exc_prep_reph + grechdummy + postdelay; readout=SeqObjList("readout"); readout = dummyloop ( phaseloop( dummykernel )[exc.get_phaselist_vector()] )[DummyCycles] + peloop( phaseloop( kernel )[exc.get_phaselist_vector()][grech.get_phaselist_vector()][grech.get_pe_reorder_vector()] )[grech.get_pe_vector()]; shot=SeqObjList("shot"); shot = exc_prep + exc_prep_reph + prepdelay + readout + crusher; scan=SeqObjList("scan"); scan += reploop( sliceloop( shot + relaxdelay )[exc][exc_prep] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } ////////////////////////////////////////////////// void method_rels(){ Log odinlog(this,"method_rels"); // TrueFISP timings, use minimum TE double TEprep=exc_prep.get_duration()-exc_prep.get_magnetic_center()+ exc_prep_reph.get_duration()+ exc.get_magnetic_center(); double TEpre=grech.get_acquisition_center()-exc.get_magnetic_center(); double TEpost=grech.get_duration()-grech.get_acquisition_center()+ exc.get_magnetic_center(); double TEmax=maxof3(TEprep,TEpre,TEpost); ODINLOG(odinlog,significantDebug) << "TEprep/pre/post/max=" << TEprep << "/" << TEpre << "/" << TEpost << "/" << TEmax << STD_endl; prepdelay=TEmax-TEprep; postdelay=TEmax-TEpost; commonPars->set_EchoTime(TEmax,noedit); // calculate relaxdelay to get the desired repetition time float scandur=shot.get_duration()*float(geometryInfo->get_nSlices()); if(scandur>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scandur); relaxdelay=(commonPars->get_RepetitionTime()-scandur)/float(geometryInfo->get_nSlices()); } ////////////////////////////////////////////////// void method_pars_set(){ } }; ////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinswi.cpp0000644000175000017500000001665311322062347013565 00000000000000#include class METHOD_CLASS : public SeqMethod { private: SeqPulsar exc; SeqPulsarReph exc_reph; SeqPulsarReph exc_reph_neg; SeqAcqRead acqread; SeqAcqRead negacqread; // need separate object since calling SeqAcqDeph on the same object with different polarity does not work SeqAcqDeph readdeph; SeqAcqDeph negreaddeph; SeqGradPhaseEncFlowComp pe; SeqGradPhaseEncFlowComp pe3d; SeqGradConstPulse crusher; SeqDelay exc2acq; SeqDelay relaxdelay; SeqObjList gradpart; SeqObjList scan; SeqObjList readout; SeqObjLoop peloop; SeqObjLoop peloop3d; SeqObjLoop reploop; SeqVecIter phaseiter; JDXfloat T1Ernst; public: METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("Fully flow-compensated FLASH sequence for Susceptibility Weighted Imaging. "); } void method_pars_init() { geometryInfo->set_Mode(voxel_3d); commonPars->set_MatrixSize(readDirection,256); commonPars->set_MatrixSize(phaseDirection,256,noedit); commonPars->set_RepetitionTime(50.0); commonPars->set_EchoTime(28.0); T1Ernst=1300.0; T1Ernst.set_minmaxval(0.0,5000.0).set_description("For optimum SNR, the flip angle will be set to the Ernst angle using this T1"); append_parameter(T1Ernst,"T1Ernst"); // fmapscan.init("fmapscan"); // append_parameter(fmapscan.get_parblock(),"FieldMapPars"); } void method_seq_init(){ Log odinlog(this,"method_seq_init"); ///////////////// Pulses: ///////////////////// // Excitation Pulse float spatres=3.0; float slicethick=geometryInfo->get_FOV(sliceDirection)-2.0*spatres; if(slicethickget_FlipAngle(), spatres, 512); exc.set_filter("Gauss"); exc.set_freqoffset(systemInfo->get_gamma() * exc.get_strength() / (2.0*PII) * geometryInfo->get_offset(sliceDirection) ); exc.set_pulse_type(excitation); // ODINLOG(odinlog,significantDebug) << "exc.rel_magnetic_center/get_pulsduration" << exc.get_rel_magnetic_center() << "/" << exc.get_pulsduration() << STD_endl; // ODINLOG(odinlog,significantDebug) << "exc.get_Gz()" << exc.get_Gz() << STD_endl; // rephasing lobe for excitation pulse exc_reph=SeqPulsarReph("exc_reph",exc); exc_reph_neg=SeqPulsarReph("exc_reph",exc); exc_reph_neg.invert_strength(); ////////////////// Geometry: ///////////////////////////////// // calculate the resolution in the read Channel and set the number of phase encoding // steps so that we will obtain a uniform resolution in read and phase Channel: float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5),noedit); commonPars->set_MatrixSize(sliceDirection,int(secureDivision(geometryInfo->get_FOV(sliceDirection),resolution)+0.5),noedit); //////////////// Phase Encoding: ////////////////////////// float t0=exc.get_duration()-exc.get_magnetic_center()+ exc_reph.get_duration()+ exc_reph.get_duration()+ exc_reph_neg.get_duration(); pe=SeqGradPhaseEncFlowComp("pe", t0, commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), phaseDirection, 0.25*systemInfo->get_max_grad(), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, commonPars->get_PartialFourier()); //////////////// Phase Encoding (3D): ////////////////////////// pe3d=SeqGradPhaseEncFlowComp("pe3d", t0, commonPars->get_MatrixSize(sliceDirection),geometryInfo->get_FOV(sliceDirection), sliceDirection, pe.get_strength(), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor()); //////////////// Readout: ////////////////////////////// acqread=SeqAcqRead("acqread",commonPars->get_AcqSweepWidth(),commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection),readDirection); negacqread=acqread; readdeph=SeqAcqDeph("readdeph", acqread); negreaddeph=SeqAcqDeph("negreaddeph", negacqread, spinEcho); //////////////// RF Spoiling: ////////////////////////////// if(commonPars->get_RFSpoiling()) { exc.set_phasespoiling(); acqread.set_phasespoiling(); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(acqread.get_phaselist_vector()); } //////////////// Crusher: ////////////////////////////// double crusher_strength=0.5*systemInfo->get_max_grad(); double crusher_integral=4.0*fabs(readdeph.get_gradintegral().sum()); double crusher_dur=secureDivision(crusher_integral, crusher_strength); crusher=SeqGradConstPulse("crusher",readDirection,crusher_strength,crusher_dur); //////////////// Field-map template: ////////////////////////////// // fmapscan.build_seq(100.0, SeqObjList(), commonPars->get_RepetitionTime()); //////////////// several padding delays //////////////////// exc2acq=SeqDelay("exc2acq"); relaxdelay=SeqDelay("relaxdelay"); //////////////// total sequence: ////////////////////////////// gradpart=SeqObjList("gradpart"); scan=SeqObjList("scan"); readout=SeqObjList("readout"); peloop=SeqObjLoop("peloop"); peloop3d=SeqObjLoop("peloop3d"); reploop=SeqObjLoop("reploop"); gradpart = (negreaddeph+readdeph)/pe/pe3d; readout = exc + exc_reph + exc_reph + exc_reph_neg + gradpart + exc2acq + readdeph + acqread + crusher; if(commonPars->get_RFSpoiling()) readout += phaseiter; // scan += fmapscan + relaxdelay; scan+= reploop( peloop3d( peloop( readout + relaxdelay )[pe] )[pe3d] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels(){ // TE double minTE=exc.get_duration()-exc.get_magnetic_center()+ exc_reph.get_duration()+ exc_reph.get_duration()+ exc_reph_neg.get_duration()+ gradpart.get_duration()+ readdeph.get_duration()+ acqread.get_acquisition_center(); if(commonPars->get_EchoTime()set_EchoTime(minTE); exc2acq=commonPars->get_EchoTime()-minTE; // TR // calculate relaxdelay to get the desired repetition time float readoutdur=readout.get_duration(); if(readoutdur > commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(readoutdur); relaxdelay.set_duration( commonPars->get_RepetitionTime()-readoutdur ); // calculate Ernst angle accordng to TR float flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), T1Ernst) ) ); commonPars->set_FlipAngle( flipangle, noedit ); exc.set_flipangle( flipangle ); } void method_pars_set(){ // inform the readout about the used phase encoding and slice vector (for automatic reconstruction) acqread.set_reco_vector(line,pe); acqread.set_reco_vector(line3d,pe3d); recoInfo->set_PreProc3D("swi"); recoInfo->set_PostProc3D("mip"); // recoInfo->set_CmdLineOpts("-ff CosSq -fp 0.5"); } }; // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/tj_messer.cpp0000644000175000017500000005311511455553544014111 00000000000000 // include the headers of all sequence classes #include // The whole EPI sequence (including reco) is a C++ class class METHOD_CLASS : public SeqMethod { private: JDXint NumOfEchoes; JDXbool SEAcquisition; JDXint Blades; JDXint Shots; JDXfloat PulseDur; JDXbool RampSampling; JDXbool FatSaturation; JDXbool fMRITrigger; JDXfloat FWbVal; JDXbool FieldMap; JDXdoubleArr TEs; // sequence objects which are the elementary objects // to build the EPI sequence SeqPulsar exc; SeqPulsar refoc; SeqSat fatsat; SeqAcqEPI ge_epi; SeqAcqEPI ge_epi_template; SeqAcqEPI ge_epi_grappa; SeqAcqEPI se_epi; SeqAcqEPI se_epi_template; SeqAcqEPI se_epi_grappa; SeqAcqDeph ge_deph; SeqAcqDeph se_deph; SeqAcqDeph deph_template; // one for both GE and SE SeqAcqDeph ge_deph_grappa; SeqAcqDeph se_deph_grappa; SeqAcqDeph ge_reph; SeqAcqDeph se_reph; SeqAcqDeph reph_template; // one for both GE and SE SeqAcqDeph ge_reph_grappa; SeqAcqDeph se_reph_grappa; SeqDelay sedelay; SeqGradTrapezParallel rewind; SeqGradTrapezParallel rewind_template; SeqDelay rewind_paddelay; SeqVecIter phaseiter; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop segloop; SeqObjLoop grappaloop; SeqObjLoop echoloop; SeqObjLoop dummyloop; SeqDelay trdelay; SeqObjVector gerewindvec; SeqObjVector gerewindvec_template; SeqObjVector gerewindvec_grappa; SeqObjList gepart; SeqObjList gepart_template; SeqObjList gepart_grappa; SeqDelay gepart_dummy; SeqObjVector serewindvec; SeqObjVector serewindvec_template; SeqObjVector serewindvec_grappa; SeqObjList separt; SeqObjList separt_template; SeqObjList separt_grappa; SeqDelay separt_dummy; SeqObjList scan; SeqObjList templatepart; SeqObjList grappapart; SeqObjList imagingpart; SeqObjList dummypart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList slicepart_template; SeqObjList slicepart_grappa; SeqObjList preppart; SeqDelay exc2acq; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqGradConstPulse spoiler; SeqTrigger trigger; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqDiffWeight fw; SeqGradTrapez fw1st; SeqGradTrapezParallel fw2nd_reph; SeqObjList fwpart; SeqDelay fwmid; SeqObjLoop bladeloop; SeqRotMatrixVector bladerot; dvector bladeangels; SeqFieldMap fmapscan; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("Multi-gradient-Echo Single-shot Sampling of Echo Refocussing (MESSER), a combined gradient- and spin-echo sequence using parallel imaging."); } void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,64); commonPars->set_MatrixSize(phaseDirection,64,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); commonPars->set_ReductionFactor(3); NumOfEchoes=3; NumOfEchoes.set_description("Number of echoes per period"); append_parameter(NumOfEchoes,"NumOfEchoes"); SEAcquisition=true; SEAcquisition.set_description("Sample the spin echo directly with the last EPI"); append_parameter(SEAcquisition,"SEAcquisition"); Blades=1; Blades.set_description("Number of long-axis PROPELLER blades"); append_parameter(Blades,"Blades"); Shots=1; Shots.set_description("Number of shots, multi-shot (segmented) EPI if Shots>1"); append_parameter(Shots,"Shots"); PulseDur=4.0; // start with large duration so that sequence can be loaded PulseDur.set_unit(ODIN_TIME_UNIT); PulseDur.set_description("Pulse duration of excitation and refocusing pulse"); append_parameter(PulseDur,"PulseDur"); RampSampling=false; RampSampling.set_description("Perform sampling during gradient ramps"); append_parameter(RampSampling,"RampSampling"); FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); append_parameter(FatSaturation,"FatSaturation"); fMRITrigger=true; fMRITrigger.set_description("External triggering"); append_parameter(fMRITrigger,"fMRITrigger"); FWbVal=0.0; FWbVal.set_unit("s/mm^2"); FWbVal.set_description("b-Value of Weak flow weighting after excitation"); append_parameter(FWbVal,"FWbVal"); FieldMap=false; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); TEs.resize(2*NumOfEchoes); TEs.set_description("Echo times"); append_parameter(TEs,"TEs"); } void method_seq_init() { Log odinlog(this,"method_seq_init"); if(NumOfEchoes<2) NumOfEchoes=2; ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float slicegap=geometryInfo->get_sliceDistance()-slicethick; // excitation pulse exc=SeqPulsarSinc("exc",slicethick,false,PulseDur,commonPars->get_FlipAngle()); exc.set_freqlist( systemInfo->get_gamma() * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); // Slightly thicker refocusing slice for better SNR // Since the same spatial resolution is used for exc and refoc, the gradient strengths will be the same float extra_slicethick_refoc=STD_min(0.5*slicethick, 0.3*slicegap); // refocusing pulse refoc=SeqPulsarSinc("refoc",slicethick+extra_slicethick_refoc,false,PulseDur,180.0); refoc.set_freqlist( systemInfo->get_gamma() * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(!commonPars->get_RFSpoiling()) refoc.set_phase(90.0); refoc.set_pulse_type(refocusing); // fat saturation pulse fatsat=SeqSat("fatsat",fat); //////////////// EPI-Readout: ////////////////////////////// // set equivalent resolution in read and phase direction float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); int pelines=int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5); commonPars->set_MatrixSize(phaseDirection, pelines, noedit); float pefov=geometryInfo->get_FOV(phaseDirection); if(Blades>1) { pelines=int(0.5*PII*commonPars->get_MatrixSize(readDirection)/Blades+0.5); pefov=geometryInfo->get_FOV(readDirection); // quadratic FOV commonPars->set_MatrixSize(phaseDirection,commonPars->get_MatrixSize(readDirection),noedit); // quadratic size } float os_read=1.25; // slight oversampling to allow off-center FOV if(Blades>1) os_read=2.0; ge_epi=SeqAcqEPI("ge_epi",commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), pelines, pefov, Shots, commonPars->get_ReductionFactor(), os_read, "",0,0,linear,RampSampling,1.0,commonPars->get_PartialFourier()); // Phase-correction template ge_epi_template=ge_epi; ge_epi_template.set_label("ge_epi_template"); ge_epi_template.set_template_type(phasecorr_template); // Full multi-shot EPI readout as GRAPPA training data ge_epi_grappa=ge_epi; ge_epi_grappa.set_label("ge_epi_grappa"); ge_epi_grappa.set_template_type(grappa_template); se_epi=ge_epi; se_epi_template=ge_epi_template; se_epi_grappa=ge_epi_grappa; // EPI pre-dephase gradient ge_deph=SeqAcqDeph("ge_deph",ge_epi,FID); se_deph=SeqAcqDeph("se_deph",se_epi,FID); deph_template=SeqAcqDeph("deph_template",ge_epi_template,FID); ge_deph_grappa=SeqAcqDeph("ge_deph_grappa",ge_epi_grappa,FID); se_deph_grappa=SeqAcqDeph("se_deph_grappa",se_epi_grappa,FID); // EPI post-rephase gradients ge_reph=SeqAcqDeph("ge_reph",ge_epi,rephase); se_reph=SeqAcqDeph("se_reph",se_epi,rephase); reph_template=SeqAcqDeph("reph_template",ge_epi_template,rephase); ge_reph_grappa=SeqAcqDeph("ge_reph_grappa",ge_epi_grappa,rephase); se_reph_grappa=SeqAcqDeph("se_reph_grappa",se_epi_grappa,rephase); // EPI rewinder after each echo fvector gradint(3); float rewind_strength=0.4*systemInfo->get_max_grad(); // OK for stimulation monitor gradint=ge_reph.get_gradintegral()+ge_deph.get_gradintegral(); // collapse rephase and dephase into one gradient pulse rewind=SeqGradTrapezParallel("rewind",gradint[0],gradint[1],gradint[2],rewind_strength); gradint=reph_template.get_gradintegral()+deph_template.get_gradintegral(); rewind_template=SeqGradTrapezParallel("rewind_template",gradint[0],gradint[1],gradint[2],rewind_strength); ODINLOG(odinlog,significantDebug) << "rewind/rewind_template.get_duration()=" << rewind.get_duration() << "/" << rewind_template.get_duration() << STD_endl; rewind_paddelay=SeqDelay("rewind_paddelay",rewind.get_duration()-rewind_template.get_duration()); /////////////////// Rotation of Blades //////////////////////////////////////////////// bladerot=SeqRotMatrixVector("bladerot"); if(Blades>1) { bladeangels.resize(Blades); for(int iblade=0; ibladeget_RFSpoiling()) { // recommended by Goerke et al., NMR Biomed. 18, 534-542 (2005) int plistsize=16; double plistincr=45.0; exc.set_phasespoiling(plistsize, plistincr); refoc.set_phasespoiling(plistsize, plistincr, 90.0); ge_epi.set_phasespoiling(plistsize, plistincr); ge_epi_template.set_phasespoiling(plistsize, plistincr); ge_epi_grappa.set_phasespoiling(plistsize, plistincr); se_epi.set_phasespoiling(plistsize, plistincr); se_epi_template.set_phasespoiling(plistsize, plistincr); se_epi_grappa.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); phaseiter.add_vector(ge_epi.get_phaselist_vector()); phaseiter.add_vector(ge_epi_template.get_phaselist_vector()); phaseiter.add_vector(ge_epi_grappa.get_phaselist_vector()); phaseiter.add_vector(se_epi.get_phaselist_vector()); phaseiter.add_vector(se_epi_template.get_phaselist_vector()); phaseiter.add_vector(se_epi_grappa.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over segments segloop=SeqObjLoop("segloop"); // loop to iterate over GRAPPA interleaves grappaloop=SeqObjLoop("grappaloop"); // loop to iterate over EPI modules echoloop=SeqObjLoop("echoloop"); // loop to iterate over dummy cycles dummyloop=SeqObjLoop("dummyloop"); // loop over zoom sats // zoomloop=SeqObjLoop("zoomloop"); // loop to iterate over PROPELLER blades bladeloop=SeqObjLoop("bladeloop"); //////////////// Timing Delays: ////////////////////////////// // TR delay trdelay=SeqDelay("trdelay"); //////////////// Spoiler Gradient: ////////////////////////////// float spoiler_strength=0.5*systemInfo->get_max_grad(); float spoiler_integral=4.0*fabs(ge_deph.get_gradintegral().sum()); float spoiler_dur=secureDivision(spoiler_integral,spoiler_strength); spoiler=SeqGradConstPulse("spoiler",sliceDirection,spoiler_strength,spoiler_dur); //////////////// Crusher Gradient: ////////////////////////////// float crusher_strength=0.3*systemInfo->get_max_grad(); // Moderate strength to avoid problems with stimulation float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, crusher_strength); crusherdelay=SeqDelay("crusherdelay",1.0); // Small delay to avoid gradient-induced stimulation //////////////// Flow Weighting: ////////////////////////////// // reset fwpart.clear(); if(FWbVal>0.0) { fwmid=SeqDelay("fwmid",1.0); // Small delay to avoid nerve stimulation fvector bVals(1); bVals[0]=1000.0*FWbVal; fw=SeqDiffWeight("fw", bVals, 0.8*systemInfo->get_max_grad(), fwmid, sliceDirection); // Combine slice rephaser and flow weighting float fwint=fw.get_grad1().get_gradintegral()[sliceDirection]+exc.get_reph_gradintegral()[sliceDirection]; fw1st=SeqGradTrapez("fw1st", fwint, sliceDirection, fw.get_grad1().get_gradduration()); // fw2nd=SeqGradTrapez("fw2nd", fw.get_grad2().get_gradintegral()[sliceDirection], sliceDirection, fw.get_grad2().get_gradduration()); fw2nd_reph=SeqGradTrapezParallel("fw2nd_reph",0.0,0.0,fw.get_grad2().get_gradintegral()[sliceDirection],fw1st.get_strength()); fwpart=fw1st+fwmid+fw2nd_reph; } else { fw2nd_reph=SeqGradTrapezParallel("fw2nd_reph",0.0,0.0,exc.get_reph_gradintegral()[sliceDirection],0.8*systemInfo->get_max_grad()); fwpart=fw2nd_reph; } //////////////// fMRI trigger: ////////////////////////////// trigger=SeqTrigger("fmri_trigger",1.0); //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0); } //////////////// Build the sequence: ////////////////////////////// // add fat saturation to template and repetitions if(FatSaturation) preppart += fatsat; if(fMRITrigger) slicepart += trigger; // GE part ivector ge_iv(NumOfEchoes); int i; for(i=0; i1) { gepart. set_gradrotmatrixvector(bladerot); gepart_template.set_gradrotmatrixvector(bladerot); gepart_grappa. set_gradrotmatrixvector(bladerot); separt. set_gradrotmatrixvector(bladerot); separt_template.set_gradrotmatrixvector(bladerot); separt_grappa. set_gradrotmatrixvector(bladerot); } sedelay=SeqDelay("sedelay",0.0); imagingpart= preppart + exc + fwpart + gepart + refoc + spoiler + sedelay + separt + crusherdelay + crusher + crusherdelay; dummypart= preppart + exc + fwpart + gepart_dummy + refoc + spoiler + sedelay + separt_dummy + crusherdelay + crusher + crusherdelay; templatepart= preppart + exc + fwpart + gepart_template + refoc + spoiler + sedelay + separt_template + crusherdelay + crusher + crusherdelay; grappapart= preppart + exc + fwpart + gepart_grappa + refoc + spoiler + sedelay + separt_grappa + crusherdelay + crusher + crusherdelay; slicepart += sliceloop( imagingpart + trdelay )[exc][refoc]; slicepart_dummy = sliceloop( dummypart + trdelay )[exc][refoc]; slicepart_template = sliceloop( templatepart + trdelay )[exc][refoc]; slicepart_grappa = sliceloop( grappapart + trdelay )[exc][refoc]; if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; slicepart_template += phaseiter; slicepart_grappa += phaseiter; } if(FieldMap) scan += fmapscan + trdelay; scan += dummyloop( slicepart_dummy )[3]; // template scan for phase correction scan+= bladeloop( slicepart_template )[bladerot]; if(commonPars->get_ReductionFactor()>1) { // Fully sampled k-space scan+= grappaloop( bladeloop( segloop( slicepart_grappa )[ge_deph_grappa.get_epi_segment_vector()][ge_reph_grappa.get_epi_segment_vector()][se_deph_grappa.get_epi_segment_vector()][se_reph_grappa.get_epi_segment_vector()] )[bladerot] )[ge_deph_grappa.get_epi_reduction_vector()][ge_reph_grappa.get_epi_reduction_vector()][se_deph_grappa.get_epi_reduction_vector()][se_reph_grappa.get_epi_reduction_vector()]; } // actual scan loop scan+= reploop( bladeloop( segloop( slicepart )[ge_deph.get_epi_segment_vector()][se_deph.get_epi_segment_vector()][ge_reph.get_epi_segment_vector()][se_reph.get_epi_segment_vector()] )[bladerot] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { Log odinlog(this,"method_rels"); double TEexc= exc.get_duration() - exc.get_magnetic_center() + fwpart.get_duration(); ODINLOG(odinlog,significantDebug) << "TEexc=" << TEexc << STD_endl; // Fixed TE according to GE part double TEhalf = TEexc + gepart.get_duration() // + spoiler.get_duration() + refoc.get_magnetic_center(); commonPars->set_EchoTime(2.0*TEhalf); int nechoes_se=NumOfEchoes; TEs.resize(NumOfEchoes+nechoes_se); double TEdeph=ge_deph.get_duration(); double TEepi=ge_epi.get_duration()+rewind.get_duration(); double TEacq=ge_epi.get_acquisition_center(); ODINLOG(odinlog,significantDebug) << "TEdeph/TEepi/TEacq=" << TEdeph << "/" << TEepi << "/" << TEacq << STD_endl; // GE echo times int i; for(i=0; iget_EchoTime()) << STD_endl; } } if(SEAcquisition) { double tediff=commonPars->get_EchoTime()-TEs[2*NumOfEchoes-1]; sedelay=tediff; for(i=0; iget_RepetitionTime()set_RepetitionTime(slicedur); trdelay=(commonPars->get_RepetitionTime()-slicedur)/double(geometryInfo->get_nSlices()); } void method_pars_set() { // extra information for the automatic reconstruction ge_epi. set_reco_vector(slice,exc); ge_epi_template.set_reco_vector(slice,exc); ge_epi_grappa. set_reco_vector(slice,exc); se_epi. set_reco_vector(slice,exc); se_epi_template.set_reco_vector(slice,exc); se_epi_grappa. set_reco_vector(slice,exc); // Index for TEs ge_epi. set_reco_vector(userdef,gerewindvec); ge_epi_template.set_reco_vector(userdef,gerewindvec_template); ge_epi_grappa. set_reco_vector(userdef,gerewindvec_grappa); se_epi. set_reco_vector(userdef,serewindvec); se_epi_template.set_reco_vector(userdef,serewindvec_template); se_epi_grappa. set_reco_vector(userdef,serewindvec_grappa); recoInfo->set_DimValues(userdef,TEs); if(Blades>1) { ge_epi. set_reco_vector(cycle,bladerot); ge_epi_template.set_reco_vector(cycle,bladerot); ge_epi_grappa. set_reco_vector(cycle,bladerot); se_epi. set_reco_vector(cycle,bladerot); se_epi_template.set_reco_vector(cycle,bladerot); se_epi_grappa. set_reco_vector(cycle,bladerot); recoInfo->set_DimValues(cycle,bladeangels); } recoInfo->set_PostProc3D("usercoll | messer"); recoInfo->set_CmdLineOpts("-ff Hamming -fp 0.8"); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinrare.cpp0000644000175000017500000002650611363773557013733 00000000000000#include class METHOD_CLASS : public SeqMethod { private: SeqPulsar exc; SeqPulsarReph exc_reph; SeqPulsar refoc; SeqAcqRead acqread; SeqAcqRead acqread_templ; SeqAcqDeph readdeph; SeqGradPhaseEnc pe1,pe2; SeqGradPhaseEnc pe3d1,pe3d2; SeqGradConstPulse spoiler; SeqDelay echopad; SeqDelay excpad; SeqDelay relaxdelay; SeqObjList echopart; SeqObjList echopart_templ; SeqGradTrapezParallel postexc; SeqObjList scan; SeqObjList readout; SeqObjList readout_templ; SeqObjList pe1part; SeqObjList pe2part; SeqDelay pe1delay; SeqDelay pe2delay; SeqObjLoop echoloop; SeqObjLoop segloop; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop loop3d; SeqVector echoindex; // index vector for echoes JDXenum PhaseEncoding; JDXint NumOfSegments; JDXdouble PulseDur; JDXdouble refocFlipAngle; JDXdouble SpoilerStrength; JDXdouble SpoilerDuration; JDXbool TemplScan; public: METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("Segmented 2D/3D RARE (Turbo SE) Sequence. " "Phase correction is possible by using a prescan with phase-encoding gradients switched off. "); } unsigned int numof_testcases() const {return 3;} void method_pars_init() { PhaseEncoding.add_item("Linear",linearEncoding); PhaseEncoding.add_item("Reverse",reverseEncoding); PhaseEncoding.add_item("CenterOut",centerOutEncoding); PhaseEncoding.add_item("CenterIn",centerInEncoding); PhaseEncoding=centerOutEncoding; PhaseEncoding.set_description("Phase encoding order"); NumOfSegments=4; NumOfSegments.set_description("Number of excitation to acquire one slice/partition"); PulseDur=5.0; PulseDur.set_unit(ODIN_TIME_UNIT).set_description("Duration of excitation and refocusing pulse"); refocFlipAngle=180.0; refocFlipAngle.set_unit(ODIN_ANGLE_UNIT).set_description("Refocusing flip angle"); SpoilerStrength=50.0; SpoilerStrength.set_unit("%").set_description("Spoiler-gradient strength in percent of max gradient amplitude"); SpoilerDuration=1.0; SpoilerDuration.set_unit(ODIN_TIME_UNIT).set_description("Spoiler-gradient duration"); TemplScan=true; TemplScan.set_description("Acquire and use template scan for phase correction"); // alternative default settings for sequence test if(get_current_testcase()==1) { geometryInfo->set_Mode(voxel_3d); PulseDur=6.0; refocFlipAngle=120.0; SpoilerStrength=30.0; SpoilerDuration=2.0; } if(get_current_testcase()==2) { commonPars->set_ReductionFactor(3); TemplScan=false; NumOfSegments=1; } append_parameter(PhaseEncoding,"PhaseEncoding"); append_parameter(NumOfSegments,"NumOfSegments"); append_parameter(PulseDur,"PulseDur"); append_parameter(TemplScan,"TemplScan"); append_parameter(refocFlipAngle,"refocFlipAngle"); append_parameter(SpoilerStrength,"SpoilerStrength"); append_parameter(SpoilerDuration,"SpoilerDuration"); } ///////////////////////////////////////////////////////////////////////////////////////////////// void method_seq_init(){ Log odinlog(this,"method_seq_init"); float gamma=systemInfo->get_gamma(""); ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); if(geometryInfo->get_Mode()==voxel_3d) { slicethick=geometryInfo->get_FOV(sliceDirection); } float spatres=slicethick/4.0; // Excitation Pulse exc=SeqPulsarSinc("exc",slicethick,false,PulseDur,commonPars->get_FlipAngle(),spatres,256); if(geometryInfo->get_Mode()==slicepack) exc.set_freqlist (gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(geometryInfo->get_Mode()==voxel_3d) exc.set_freqoffset(gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_offset(sliceDirection) ); exc.set_pulse_type(excitation); // rephasing lobe for excitation pulse exc_reph=SeqPulsarReph("exc_reph",exc); // Refocusing Pulse refoc=SeqPulsarSinc("refoc",slicethick,false,PulseDur,refocFlipAngle,spatres,256); refoc.set_phase(90.0); if(geometryInfo->get_Mode()==slicepack) refoc.set_freqlist (gamma * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(geometryInfo->get_Mode()==voxel_3d) refoc.set_freqoffset(gamma * refoc.get_strength() / (2.0*PII) * geometryInfo->get_offset(sliceDirection) ); refoc.set_pulse_type(refocusing); ////////////////// Geometry: ///////////////////////////////// // calculate the resolution in the read Channel and set the number of phase encoding // steps so that we will obtain a uniform resolution in read and phase Channel: float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5),noedit); commonPars->set_MatrixSize(sliceDirection,int(secureDivision(geometryInfo->get_FOV(sliceDirection),resolution)+0.5),noedit); //////////////// Phase Encoding: ////////////////////////// pe1=SeqGradPhaseEnc("pe1",commonPars->get_MatrixSize(phaseDirection),geometryInfo->get_FOV(phaseDirection), phaseDirection,0.25*systemInfo->get_max_grad(), encodingScheme(int(PhaseEncoding)),interleavedSegmented,NumOfSegments, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, commonPars->get_PartialFourier()); pe2=pe1; pe2.set_label("pe2"); pe2.invert_strength(); // Echo indices for template correction unsigned int nechoes=((const SeqVector&)pe1).get_numof_iterations(); ODINLOG(odinlog,significantDebug) << "nechoes=" << nechoes << STD_endl; echoindex=SeqVector("echoindex",nechoes); //////////////// Phase Encoding (3D): ////////////////////////// if(geometryInfo->get_Mode()==voxel_3d) { pe3d1=SeqGradPhaseEnc("pe3d1",commonPars->get_MatrixSize(sliceDirection),geometryInfo->get_FOV(sliceDirection),pe1.get_constduration(), sliceDirection, linearEncoding, noReorder, 1, commonPars->get_ReductionFactor()); pe3d2=pe3d1; pe3d2.set_label("pe3d2"); pe3d2.invert_strength(); } //////////////// Readout: ////////////////////////////// acqread=SeqAcqRead("acqread",commonPars->get_AcqSweepWidth(),commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection),readDirection); acqread_templ=SeqAcqRead(acqread); acqread_templ.set_label("acqread_templ"); acqread_templ.set_template_type(phasecorr_template); readdeph=SeqAcqDeph("readdeph",acqread,spinEcho); //////////////// Spoiler: ////////////////////////////// float spoiler_strength_phys=(double)SpoilerStrength/100.0*systemInfo->get_max_grad(); spoiler=SeqGradConstPulse("spoiler",phaseDirection,spoiler_strength_phys,SpoilerDuration); //////////////// several padding delays //////////////////// excpad=SeqDelay("excpad"); echopad=SeqDelay("echopad"); relaxdelay=SeqDelay("relaxdelay"); pe1delay=SeqDelay("pe1delay"); pe2delay=SeqDelay("pe2delay"); //////////////// total sequence: ////////////////////////////// echopart=SeqObjList("echopart"); echopart_templ=SeqObjList("echopart_templ"); scan=SeqObjList("scan"); echoloop=SeqObjLoop("echoloop"); segloop=SeqObjLoop("segloop"); sliceloop=SeqObjLoop("sliceloop"); reploop=SeqObjLoop("reploop"); loop3d=SeqObjLoop("loop3d"); readout=SeqObjList("readout"); fvector gradint(3); gradint=0.0; gradint+=exc_reph.get_gradintegral(); gradint+=readdeph.get_gradintegral(); gradint+=spoiler.get_gradintegral(); postexc=SeqGradTrapezParallel("postexc",gradint[0],gradint[1],gradint[2],0.5*systemInfo->get_max_grad()); ODINLOG(odinlog,significantDebug) << "postexc. get_gradintegral()=" << postexc.get_gradintegral().printbody() << STD_endl; float spoiler_k_diff=systemInfo->get_gamma()*(spoiler.get_gradintegral()[1]-postexc.get_gradintegral()[1]); ODINLOG(odinlog,significantDebug) << "spoiler_k_diff=" << spoiler_k_diff << STD_endl; if(geometryInfo->get_Mode()==voxel_3d) { pe1part+=pe1/pe3d1; pe2part+=pe2/pe3d2; } else { pe1part+=pe1; pe2part+=pe2; } pe1delay=SeqDelay("pe1delay",pe1part.get_duration()); pe2delay=SeqDelay("pe2delay",pe2part.get_duration()); echopart_templ= refoc + spoiler + echopad + pe1delay + acqread_templ + pe2delay + echopad + spoiler; echopart = refoc + spoiler + echopad + pe1part + acqread + pe2part + echopad + spoiler; readout_templ = exc + postexc + excpad + echoloop(echopart_templ)[echoindex]; readout = exc + postexc + excpad + echoloop(echopart) [pe1][pe2][echoindex]; if(geometryInfo->get_Mode()==voxel_3d) { if(TemplScan) { scan+= readout_templ + relaxdelay; } scan+= reploop( segloop( loop3d( readout + relaxdelay )[pe3d1][pe3d2] )[pe1.get_reorder_vector()][pe2.get_reorder_vector()] )[commonPars->get_NumOfRepetitions()]; } else { if(TemplScan) { scan+= sliceloop( readout_templ + relaxdelay )[exc][refoc]; } scan+= reploop( segloop( sliceloop( readout + relaxdelay )[exc][refoc] )[pe1.get_reorder_vector()][pe2.get_reorder_vector()] )[commonPars->get_NumOfRepetitions()]; } set_sequence( scan ); } ///////////////////////////////////////////////////////////////////////////////////////////////// void method_rels(){ Log odinlog(this,"method_rels"); // CPMG timings double TE1=exc.get_duration()-exc.get_magnetic_center()+ postexc.get_duration()+ refoc.get_magnetic_center(); double TE2=(echopart.get_duration())/2.; ODINLOG(odinlog,significantDebug) << "TE1/TE2=" << TE1 << "/" << TE2 << STD_endl; if(TE2-TE1 < 0) echopad.set_duration(echopad.get_duration()-(TE2-TE1)); else excpad.set_duration(excpad.get_duration()+(TE2-TE1)); ODINLOG(odinlog,significantDebug) << "echopad=" << echopad.get_duration() << STD_endl; ODINLOG(odinlog,significantDebug) << "excpad=" << excpad.get_duration() << STD_endl; commonPars->set_EchoTime(echopart.get_duration(),noedit); // calculate relaxdelay to get the desired repetition time float scandur=readout.get_duration()*float(geometryInfo->get_nSlices()); if(scandur>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scandur); relaxdelay=(commonPars->get_RepetitionTime()-scandur)/float(geometryInfo->get_nSlices()); } ///////////////////////////////////////////////////////////////////////////////////////////////// void method_pars_set(){ // inform the readout about the used phase encoding and slice vector (for automatic reconstruction) acqread.set_reco_vector(line,pe1); acqread_templ.set_reco_vector(echo,echoindex); acqread.set_reco_vector(echo,echoindex); if(geometryInfo->get_Mode()==voxel_3d) { acqread.set_reco_vector(line3d,pe3d1); } acqread.set_reco_vector(slice,exc); acqread_templ.set_reco_vector(slice,exc); } }; ///////////////////////////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinpilot.cpp0000644000175000017500000002363011455553544014116 00000000000000////////////////////////////////////////////////////////////////////////////// // // A navigator sequence for the ODIN framework // ////////////////////////////////////////////////////////////////////////////// // includes for the sequence objects #include // The method itself is a class that is derived from // an abstract base class 'SeqMethod' that contains all // routines common to all methods: class METHOD_CLASS : public SeqMethod { public: // Constructor that takes the methods identifier (unique string) as its argument METHOD_CLASS(const STD_string& label); // virtual functions that are overwritten in this method to build the sequence, // calculate parameter relations, etc.: void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); private: // Parameters for this method: JDXfloat T1Ernst; JDXint DummyCycles; JDXint NumSagSlices; JDXint NumCorSlices; JDXint NumAxiSlices; JDXfloat PilotSliceDist; // Sequence objects for this method: SeqPulsar exc; SeqDelay relaxdelay; SeqObjLoop peloop; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop dummyloop; SeqObjList scanpart; SeqObjList dummypart; SeqDelay dummypad; SeqGradEcho grech; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqRotMatrixVector pilotrot; unsigned int nslices; ivector nslices_dir; dvector dirvec; Geometry area[n_orientations]; }; //////////////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { // Put in here all stuff that will once be initialised and // never changed // Specify a short description of the method set_description("Navigator which acquires three orthogonal sets of slices." ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_init() { // In this function the methods parameters will be initialised // Assign default values: commonPars->set_RepetitionTime(300.0); commonPars->set_AcqSweepWidth(25.0); commonPars->set_MatrixSize(readDirection,128); // set default values and a short a description (which // will appear as a tooltip in the UI) for each parameter T1Ernst=1300.0; T1Ernst.set_minmaxval(0.0,5000.0).set_description("For optimum SNR, the flip angle will be set to the Ernst angle using this T1"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); NumSagSlices=3; NumSagSlices.set_description("Number of sagittal slices in Pilot"); NumCorSlices=3; NumCorSlices.set_description("Number of coronal slices in Pilot"); NumAxiSlices=3; NumAxiSlices.set_description("Number of axial slices in Pilot"); PilotSliceDist=25.0; PilotSliceDist.set_description("Slice distance of Pilot"); // Make method specific parameters visible in the user interface append_parameter(T1Ernst,"T1Ernst"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(NumSagSlices,"NumSagSlices"); append_parameter(NumCorSlices,"NumCorSlices"); append_parameter(NumAxiSlices,"NumAxiSlices"); append_parameter(PilotSliceDist,"PilotSliceDist"); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_seq_init() { Log odinlog(this,"method_seq_init"); // Put in here all stuff to create the layout of the sequence // number of slices in each direction nslices_dir.resize(n_orientations); nslices_dir[sagittal]=NumSagSlices; nslices_dir[coronal]=NumCorSlices; nslices_dir[axial]=NumAxiSlices; nslices=nslices_dir.sum(); geometryInfo->reset(); // Use default orientations ///////////////// Excitation Pulse: ///////////////////// // Get the slice thickness from the global geometry handler 'geometryInfo': float slicethick=4.0; // Create the sinc shaped excitation pulse. exc=SeqPulsarSinc("exc",slicethick,false,2.0,commonPars->get_FlipAngle()); // This is useful for simulating/visualization of the sequence exc.set_pulse_type(excitation); // Do not use maxDistEncoding exc.set_encoding_scheme(linearEncoding); // Pilot rotation and slice offset dvector offset(nslices); offset=0.0; pilotrot=SeqRotMatrixVector("pilotrot"); dirvec.resize(nslices); int ioffset=0; for(int idir=0; idirget_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5),noedit); //////////////// Delays: ////////////////////////////// // relaxation delay after each readout relaxdelay=SeqDelay("relaxdelay"); //////////////// Gradient Echo Module: ////////////////////////////// float os_factor=2.0; // avoid cut-off in read direction for off-center FOV // This is the gradient-recalled echo kernel of the sequence. // Calculations of read/phase gradient strengts and durations are // performed by this module itself so we just have to pass in the size and FOV // in each direction. This module has a tight timing scheme so that short TE is possible. grech=SeqGradEcho("grech", exc, commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, false, commonPars->get_PartialFourier(),0.0,false,os_factor); grech.set_gradrotmatrixvector(pilotrot); // rotate grech //////////////// Crusher Gradient: ////////////////////////////// float crusher_strength=0.5*systemInfo->get_max_grad(); float crusher_integral=4.0*fabs(grech.get_gradintegral().sum()); crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, crusher_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// Loops: ////////////////////////////// // Construct a loop object to iterate through the phase encoding steps peloop=SeqObjLoop("peloop"); // Construct a loop object to perform repetitions of the experiment reploop=SeqObjLoop("reploop"); // Construct a loop object to perform dummy cylces dummyloop=SeqObjLoop("dummyloop"); //////////////// Constructing the Sequence: /////////////// // This sequence container will hold the objects for one readout: scanpart=SeqObjList("scanpart"); scanpart = grech + crusherdelay + crusher; // Contains kernel of one dummy cycle dummypart=SeqObjList("dummypart"); dummypad=SeqDelay("dummypad",scanpart.get_duration()-exc.get_duration()); // Padding delay for dummy cycle dummypart = exc + dummypad + relaxdelay; // Finally, build the whole sequence set_sequence( dummyloop( sliceloop( dummypart )[grech.get_exc_vector()][pilotrot] )[DummyCycles] + peloop( sliceloop( scanpart + relaxdelay // the sequence kernel )[grech.get_exc_vector()][pilotrot] )[grech.get_pe_vector()] ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_rels() { // Put in here all stuff that has to be performed whenever one of the sequence parameters // has been changed by the user // calculate relaxdelay to get the desired repetition time float scandur=scanpart.get_duration()*float(nslices); if(scandur>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scandur); relaxdelay.set_duration( (commonPars->get_RepetitionTime()-scandur)/float(nslices) ); // calculate Ernst angle accordng to TR float flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), T1Ernst) ) ); commonPars->set_FlipAngle( flipangle, noedit ); exc.set_flipangle( flipangle ); // retrieve echo time from gradient echo module to display it in the user interface commonPars->set_EchoTime(grech.get_echo_time(), noedit ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_set() { // Put in here all stuff that has to be performed after the parameters have been edited by the user // and before the sequence is played out // for odinreco grech.set_reco_vector(userdef,pilotrot,dirvec); // distinguish slices by their orientation recoInfo->set_Recipe("kspace | fft | offset | oversampling | usercoll | pilot("+ftos(PilotSliceDist)+") | store"); } //////////////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odingrech.cpp0000644000175000017500000002425411455553544014062 00000000000000////////////////////////////////////////////////////////////////////////////// // // A simple gradient echo sequence for the ODIN framework // ////////////////////////////////////////////////////////////////////////////// // includes for the sequence objects #include // The method itself is a class that is derived from // an abstract base class 'SeqMethod' that contains all // routines common to all methods: class METHOD_CLASS : public SeqMethod { public: // Constructor that takes the methods identifier (unique string) as its argument METHOD_CLASS(const STD_string& label); // virtual functions that are overwritten in this method to build the sequence, // calculate parameter relations, etc.: void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); private: // Parameters for this method: JDXfloat T1Ernst; JDXint DummyCycles; JDXfloat PartialFourierRead; // Sequence objects for this method: SeqPulsar exc; SeqDelay relaxdelay; SeqObjLoop peloop; SeqObjLoop peloop3d; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop dummyloop; SeqObjList scanpart; SeqObjList slicepart; SeqObjList dummypart; SeqDelay dummypad; SeqGradEcho grech; SeqVecIter phaseiter; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; }; //////////////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { // Put in here all stuff that will once be initialised and // never changed // Specify a short description of the method set_description("This is a simple spoiled gradient echo sequence where " "each excitation is used to scan one line " "in k-space via a gradient echo with the " "apropriate phase encoding. The flip angle is " "the Ernst angle for the given T1 (to obtain maximum SNR). " ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_init() { // In this function the methods parameters will be initialised // Assign default values: commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(25.0); commonPars->set_MatrixSize(readDirection,128); // set default values and a short a description (which // will appear as a tooltip in the UI) for each parameter T1Ernst=1300.0; T1Ernst.set_minmaxval(0.0,5000.0).set_description("For optimum SNR, the flip angle will be set to the Ernst angle using this T1"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); PartialFourierRead=0.0; PartialFourierRead.set_description("The amount of partial Fourier undersampling in readout direction (0=no undersampling, 1=half fourier)"); // Make method specific parameters visible in the user interface append_parameter(T1Ernst,"T1Ernst"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(PartialFourierRead,"PartialFourierRead"); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_seq_init() { // Put in here all stuff to create the layout of the sequence ///////////////// Excitation Pulse: ///////////////////// // Get the slice thickness from the global geometry handler 'geometryInfo': float slicethick=geometryInfo->get_sliceThickness(); if(geometryInfo->get_Mode()==voxel_3d) slicethick=0.9*geometryInfo->get_FOV(sliceDirection); float spatres=slicethick/4.0; // Create the sinc shaped excitation pulse. exc=SeqPulsarSinc("exc",slicethick,false,2.0,commonPars->get_FlipAngle(),spatres); // Set the frequency list of the excitation pulse so that we will excite all slices in the slicepack exc.set_freqlist( systemInfo->get_gamma("") * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); // This is useful for simulating/visualization of the sequence exc.set_pulse_type(excitation); // This loop object is used to loop over the slices sliceloop=SeqObjLoop("sliceloop"); ////////////////// Geometry: ///////////////////////////////// // calculate the resolution in the read Channel and set the number of phase encoding // steps so that we will obtain a isotropic resolution in read and phase Channel: float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution)+0.5),noedit); int size3d=1; if(geometryInfo->get_Mode()==voxel_3d) { size3d=int(secureDivision(geometryInfo->get_FOV(sliceDirection),resolution)+0.5); // isotropic resolution } commonPars->set_MatrixSize(sliceDirection,size3d,noedit); //////////////// Delays: ////////////////////////////// // relaxation delay after each readout relaxdelay=SeqDelay("relaxdelay"); //////////////// Gradient Echo Module: ////////////////////////////// // This is the gradient-recalled echo kernel of the sequence. // Calculations of read/phase gradient strengts and durations are // performed by this module itself so we just have to pass in the size and FOV // in each direction. This module has a tight timing scheme so that short TE is possible. if(geometryInfo->get_Mode()==voxel_3d) { // 3D mode grech=SeqGradEcho("grech", commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), commonPars->get_MatrixSize(sliceDirection), geometryInfo->get_FOV(sliceDirection), exc, commonPars->get_AcqSweepWidth(), commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, false, commonPars->get_PartialFourier(),PartialFourierRead); } else { // 2D mode grech=SeqGradEcho("grech", exc, commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, false, commonPars->get_PartialFourier(),PartialFourierRead); } if(commonPars->get_RFSpoiling()) { exc.set_phasespoiling(); grech.set_phasespoiling(); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(grech.get_phaselist_vector()); } //////////////// Crusher Gradient: ////////////////////////////// float crusher_strength=0.5*systemInfo->get_max_grad(); float crusher_integral=4.0*fabs(grech.get_gradintegral().sum()); crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, crusher_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// Loops: ////////////////////////////// // Construct a loop object to iterate through the phase encoding steps peloop=SeqObjLoop("peloop"); // Construct a loop object to iterate through the 2nd phase encoding steps peloop3d=SeqObjLoop("peloop3d"); // Construct a loop object to perform repetitions of the experiment reploop=SeqObjLoop("reploop"); // Construct a loop object to perform dummy cylces dummyloop=SeqObjLoop("dummyloop"); //////////////// Constructing the Sequence: /////////////// // This sequence container will hold the objects for one readout: scanpart=SeqObjList("scanpart"); scanpart = grech + crusherdelay + crusher; if(commonPars->get_RFSpoiling()) scanpart+=phaseiter; // Contains kernel of one dummy cycle dummypart=SeqObjList("dummypart"); dummypad=SeqDelay("dummypad",scanpart.get_duration()-exc.get_duration()); // Padding delay for dummy cycle dummypart = exc + dummypad + relaxdelay; // This sequence container will hold the objects for one slicepack: slicepart=SeqObjList("slicepart"); if(geometryInfo->get_Mode()==voxel_3d) { slicepart = peloop3d( peloop( sliceloop( scanpart + relaxdelay // the sequence kernel )[grech.get_exc_vector()] )[grech.get_pe_vector()] )[grech.get_pe3d_vector()]; } else { slicepart = peloop( sliceloop( scanpart + relaxdelay // the sequence kernel )[grech.get_exc_vector()] )[grech.get_pe_vector()]; } // Finally, build the whole sequence set_sequence( dummyloop( sliceloop( dummypart )[grech.get_exc_vector()] )[DummyCycles] + reploop( slicepart )[commonPars->get_NumOfRepetitions()] ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_rels() { // Put in here all stuff that has to be performed whenever one of the sequence parameters // has been changed by the user // calculate relaxdelay to get the desired repetition time float scandur=scanpart.get_duration()*float(geometryInfo->get_nSlices()); if(scandur>commonPars->get_RepetitionTime()) commonPars->set_RepetitionTime(scandur); relaxdelay.set_duration( (commonPars->get_RepetitionTime()-scandur)/float(geometryInfo->get_nSlices()) ); // calculate Ernst angle accordng to TR float flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), T1Ernst) ) ); commonPars->set_FlipAngle( flipangle, noedit ); exc.set_flipangle( flipangle ); // retrieve echo time from gradient echo module to display it in the user interface commonPars->set_EchoTime(grech.get_echo_time(), noedit ); } //////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::method_pars_set() { // Put in here all stuff that has to be performed after the parameters have been edited by the user // and before the sequence is played out } //////////////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinmdeft.cpp0000644000175000017500000001374411322062347014060 00000000000000#include #define DUMMY_SCANS 3 #define INTER_ACQ_DELAY 2.0 class METHOD_CLASS : public SeqMethod { public: METHOD_CLASS(const STD_string& label); // implementing virtual functions of SeqMethod void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); private: SeqPulsar inv; SeqPulsar exc; SeqGradEcho grech; SeqDelay inv2exc; SeqDelay exc2inv; SeqDelay dummypad; SeqDelay interacq; SeqGradConstPulse spoiler; SeqObjLoop segloop; SeqObjLoop peloop; SeqObjLoop sliceloop; SeqObjLoop dummyloop; SeqObjList prep; SeqObjList kernel; SeqObjList readout; SeqObjList dummyreadout; SeqObjList scanseq; }; ///////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { set_description("Multi-slice MDEFT sequence for high-contrast T1-weighted images (DG Norris, J Magn Reson Imag 11:445-451 (2000))."); } void METHOD_CLASS::method_pars_init() { // default values commonPars->set_RepetitionTime(1300.0); commonPars->set_MatrixSize(phaseDirection,128); commonPars->set_MatrixSize(readDirection,128,noedit); commonPars->set_EchoTime(0.0,noedit); } void METHOD_CLASS::method_seq_init() { Log odinlog(this,"method_seq_init"); ///////////////// Inversion Pulse: ///////////////////// inv=SeqPulsar("inv",false,false); inv.set_dim_mode(zeroDeeMode); inv.set_Tp(10.0); inv.resize(256); inv.set_shape("Wurst(2.96,26.48)"); // bandwidth ~ 1kHz inv.set_pulse_type(inversion); inv.refresh(); // because it's non-interactive ODINLOG(odinlog,normalDebug) << "Inversion Pulse done" << STD_endl; ///////////////// Excitation Pulses and rotation matrix of pilot: ///////////////////// exc=SeqPulsarSinc("exc",geometryInfo->get_sliceThickness(),false); exc.set_freqlist(systemInfo->get_gamma()*exc.get_strength()/(2.0*PII)*geometryInfo->get_sliceOffsetVector()); ////////////////// Geometry: ///////////////////////////////// // condition for reduced power multi-slice MDEFT unsigned int pesize=commonPars->get_MatrixSize(phaseDirection)/geometryInfo->get_nSlices(); commonPars->set_MatrixSize(phaseDirection,pesize*geometryInfo->get_nSlices()); ODINLOG(odinlog,normalDebug) << "MatrixSizePhase=" << commonPars->get_MatrixSize(phaseDirection) << STD_endl; // uniform resolution in read and phase direction // Does not work on Siemens as ADC can only have certain sizes if(systemInfo->get_platform()!=numaris_4) { float resolution=secureDivision( geometryInfo->get_FOV(phaseDirection) , commonPars->get_MatrixSize(phaseDirection) ); commonPars->set_MatrixSize(readDirection,int(secureDivision(geometryInfo->get_FOV(readDirection),resolution)+0.5),noedit); } ///////////////// Delays: ///////////////////// inv2exc=SeqDelay("inv2exc"); exc2inv=SeqDelay("exc2inv"); dummypad=SeqDelay("dummypad"); interacq=SeqDelay("interacq",INTER_ACQ_DELAY); ODINLOG(odinlog,normalDebug) << "Delays done" << STD_endl; ///////////////// Spoiler Gradient: ///////////////////// spoiler=SeqGradConstPulse("spoiler",readDirection,0.5*systemInfo->get_max_grad(),5.0); ODINLOG(odinlog,normalDebug) << "Spoiler Gradient done" << STD_endl; //////////////// Preparation: /////////////// prep=SeqObjList("prep"); prep= exc2inv + inv + spoiler + inv2exc ; ODINLOG(odinlog,normalDebug) << "Preparation done" << STD_endl; //////////////// Loops: /////////////// peloop=SeqObjLoop("peloop"); sliceloop=SeqObjLoop("sliceloop"); segloop=SeqObjLoop("segloop"); dummyloop=SeqObjLoop("dummyloop"); //////////////// Gradient Echo Module: ////////////////////////////// grech=SeqGradEcho("grech", exc, commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), linearEncoding, blockedSegmented, geometryInfo->get_nSlices(), commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, false, commonPars->get_PartialFourier()); grech.set_freq_reorder_scheme(rotateReorder); // rotate slice order ODINLOG(odinlog,normalDebug) << "kernel done" << STD_endl; //////////////// Constructing the Sequence: /////////////// kernel=SeqObjList("kernel"); readout=SeqObjList("readout"); dummyreadout=SeqObjList("dummyreadout"); scanseq=SeqObjList("scanseq"); kernel = grech; kernel += interacq; // Reuired to avoid SAR issue on Siemens // iterate over slices readout = sliceloop ( kernel ) [grech.get_exc_vector()][grech.get_pe_reorder_vector()]; dummyreadout = sliceloop( exc + dummypad )[exc]; // spoiler after each pack of slices readout += spoiler; scanseq = segloop ( peloop ( prep + readout ) [grech.get_pe_vector()] ) [grech.get_freq_reorder_vector()]; set_sequence( dummyloop( prep + dummyreadout )[DUMMY_SCANS] + scanseq ); ODINLOG(odinlog,normalDebug) << "set_sequence done" << STD_endl; } void METHOD_CLASS::method_rels() { Log odinlog(this,"method_rels"); //////////////// Timings for MDEFT condition: /////////////// float readoutduration=readout.get_duration(); float inv2exc_duration=( inv.get_duration() - inv.get_magnetic_center() ) + spoiler.get_duration() + 0.5*readoutduration; inv2exc.set_duration(0.5*commonPars->get_RepetitionTime()-inv2exc_duration); float exc2inv_duration= inv.get_magnetic_center() + 0.5*readoutduration; exc2inv.set_duration(0.5*commonPars->get_RepetitionTime()-exc2inv_duration); dummypad=secureDivision(readoutduration,geometryInfo->get_nSlices())-exc.get_duration(); commonPars->set_EchoTime(grech.get_echo_time(),noedit); } void METHOD_CLASS::method_pars_set() { } ///////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/Makefile.am0000644000175000017500000000152111455553544013440 00000000000000EXTRA_DIST = odindti.cpp odinepi.cpp odinfisp.cpp odingrech.cpp odinmdeft.cpp odinonep.cpp odinpilot.cpp odinprop.cpp odinquant.cpp odinrare.cpp odinrefg.cpp odinspir.cpp odinswi.cpp \ tj_messer.cpp tj_gesse.cpp \ mk_prop.cpp if ONLY_LIBS else seqdir = $(datadir)/odin/sequences seq_DATA = $(EXTRA_DIST) test: rm -rf seqtestfiles if test ! -f seqtestfiles.tar.gz ; then wget od1n.sourceforge.net/seqtestfiles.tar.gz ; fi tar -xvzf seqtestfiles.tar.gz ./seqtest.sh committest: if test ! -d seqtestfiles; then ./seqtest.sh; fi tar -cvzf seqtestfiles.tar.gz seqtestfiles scp seqtestfiles.tar.gz wodan,od1n@web.sourceforge.net:/home/groups/o/od/od1n/htdocs/ endif clean-local: if test -f ./seqtest.sh; then ./seqtest.sh clean; fi -rm -rf *.o *.so seqtestfiles* scandir.* Makefile.idea Makefile.odin* odin*_* odin-1.8.5/sequences/Makefile.in0000644000175000017500000003046011734622602013445 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = sequences DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(seqdir)" DATA = $(seq_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = odindti.cpp odinepi.cpp odinfisp.cpp odingrech.cpp odinmdeft.cpp odinonep.cpp odinpilot.cpp odinprop.cpp odinquant.cpp odinrare.cpp odinrefg.cpp odinspir.cpp odinswi.cpp \ tj_messer.cpp tj_gesse.cpp \ mk_prop.cpp @ONLY_LIBS_FALSE@seqdir = $(datadir)/odin/sequences @ONLY_LIBS_FALSE@seq_DATA = $(EXTRA_DIST) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu sequences/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu sequences/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-seqDATA: $(seq_DATA) @$(NORMAL_INSTALL) test -z "$(seqdir)" || $(MKDIR_P) "$(DESTDIR)$(seqdir)" @list='$(seq_DATA)'; test -n "$(seqdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(seqdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(seqdir)" || exit $$?; \ done uninstall-seqDATA: @$(NORMAL_UNINSTALL) @list='$(seq_DATA)'; test -n "$(seqdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(seqdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(seqdir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(seqdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool clean-local mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-seqDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-seqDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ clean-local distclean distclean-generic distclean-libtool \ distdir dvi dvi-am html html-am info info-am install \ install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-seqDATA install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am uninstall uninstall-am uninstall-seqDATA @ONLY_LIBS_FALSE@test: @ONLY_LIBS_FALSE@ rm -rf seqtestfiles @ONLY_LIBS_FALSE@ if test ! -f seqtestfiles.tar.gz ; then wget od1n.sourceforge.net/seqtestfiles.tar.gz ; fi @ONLY_LIBS_FALSE@ tar -xvzf seqtestfiles.tar.gz @ONLY_LIBS_FALSE@ ./seqtest.sh @ONLY_LIBS_FALSE@committest: @ONLY_LIBS_FALSE@ if test ! -d seqtestfiles; then ./seqtest.sh; fi @ONLY_LIBS_FALSE@ tar -cvzf seqtestfiles.tar.gz seqtestfiles @ONLY_LIBS_FALSE@ scp seqtestfiles.tar.gz wodan,od1n@web.sourceforge.net:/home/groups/o/od/od1n/htdocs/ clean-local: if test -f ./seqtest.sh; then ./seqtest.sh clean; fi -rm -rf *.o *.so seqtestfiles* scandir.* Makefile.idea Makefile.odin* odin*_* # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/sequences/odinquant.cpp0000644000175000017500000004165411322062347014112 00000000000000#include #define T2_CPMG_ECHO_FACTOR 2.5 #define T1_IR_FACTOR 1.2 class METHOD_CLASS : public SeqMethod { public: METHOD_CLASS(const STD_string& label); void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); unsigned int numof_testcases() const {return 4;} private: JDXenum Mode; JDXdouble ExpectedT1; JDXdouble ExpectedT2; JDXdouble MinEchoTime; JDXdouble MaxEchoTime; JDXint NumOfEchoes; JDXint NumOfDummyEchoes; JDXdoubleArr EchoTimes; JDXdouble B1PulseDur; SeqPulsar exc; SeqPulsar refoc; SeqPulsar inv; SeqAcqRead acqread; SeqDelay acqdummy; SeqAcqDeph readdeph; SeqObjLoop echoloop; SeqObjLoop dummyecholoop; SeqObjLoop peloop; SeqGradConstPulse spoiler1; SeqGradVectorPulse spoiler2; // objects for fieldmap scan SeqAcqEPI epi; SeqAcqDeph epideph; SeqVector echovec; // index vector for echoes SeqDelay excdelay; SeqDelay echodelay1; SeqDelay echodelay2; SeqDelay invdelay; SeqGradPhaseEnc pe1; SeqGradPhaseEnc pe2; SeqObjList echopart; SeqObjList grechpart; SeqObjList dummyechopart; SeqObjList kernel; SeqObjList slicepart; SeqDelay relaxdelay; SeqDelay dummype; SeqObjLoop sliceloop; SeqObjLoop acculoop; SeqObjLoop fliploop; SeqObjList postexc; SeqObjList postrefoc; SeqObjList postrefoctmpl; SeqObjList postinv; SeqObjList baselinepart; SeqGradEcho grech; fvector b1flips; }; ////////////////////////////////////////////////////////////////////////////////////////// METHOD_CLASS::METHOD_CLASS (const STD_string& label) : SeqMethod(label) { set_description("A method to measure proton density, T1, T2, and frequency offset. " "T1 maps and proton density maps are acquired using a Look-Locher sequence. " "T2 maps are acquired using a CPMG sequence whereby each echo train acquires one line in k-space for all TEs. " "Field maps are acquired using a spoiled gradient-echo sequence with different TEs. " "B1 maps are acquired as described in Dowell et al., Magn Reson Med 58 (2007). " "Maps are generated automatically by the reco method in this sequence module. "); } void METHOD_CLASS::method_pars_init() { Log odinlog(this,"method_pars_init"); Mode.add_item("T2_CPMG"); Mode.add_item("T1_LookLocker"); Mode.add_item("FIELD_MAP"); Mode.add_item("B1"); Mode.set_actual(get_current_testcase()); // alternative default settings for sequence test Mode.set_description("The quantitiy (and sequence) to measure."); ExpectedT1.set_minmaxval(10.0,10000.0); ExpectedT1=1300.0; ExpectedT1.set_description("The T1 which is expected. The TR and inversion-recovery timing will be optimized for this value."); ExpectedT1.set_unit(ODIN_TIME_UNIT); ExpectedT2.set_minmaxval(10.0,10000.0); ExpectedT2=90.0; ExpectedT2.set_description("The T2 which is expected. The CPMG timing will be optimized for this value."); ExpectedT2.set_unit(ODIN_TIME_UNIT); commonPars->set_MatrixSize(readDirection,128); commonPars->set_FlipAngle(90.0); NumOfEchoes=8; NumOfDummyEchoes=1; B1PulseDur=6.4; // use 30.0 for 7 Tesla; EchoTimes.resize(NumOfEchoes); append_parameter(Mode,"Mode"); append_parameter(ExpectedT1,"ExpectedT1"); append_parameter(ExpectedT2,"ExpectedT2"); append_parameter(MinEchoTime,"MinEchoTime",noedit); append_parameter(MaxEchoTime,"MaxEchoTime",noedit); append_parameter(NumOfEchoes,"NumOfEchoes"); append_parameter(NumOfDummyEchoes,"NumOfDummyEchoes"); append_parameter(EchoTimes,"EchoTimes"); append_parameter(B1PulseDur,"B1PulseDur"); } void METHOD_CLASS::method_seq_init() { Log odinlog(this,"method_seq_init"); if(NumOfEchoes<2) NumOfEchoes=2; // adjust echo timings if(Mode=="T2_CPMG") { double te=ExpectedT2*T2_CPMG_ECHO_FACTOR/NumOfEchoes; commonPars->set_EchoTime(te,noedit); MinEchoTime=te; MaxEchoTime=NumOfEchoes*te; } if(Mode=="T1_LookLocker") { double ti_step=ExpectedT1*T1_IR_FACTOR/(NumOfEchoes-1); commonPars->set_EchoTime(ti_step,noedit); MinEchoTime=ExpectedT1/50.0; MaxEchoTime=MinEchoTime+(NumOfEchoes-1)*ti_step; float trwait=4.0*ExpectedT1; if(commonPars->get_RepetitionTime()set_RepetitionTime(trwait); } if(Mode=="FIELD_MAP") { if(NumOfEchoes%2) NumOfEchoes++; // even number of echoes (echo pairs) in EPI module // get TE later from EPI module } ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float spatres=slicethick/4.0; float gamma=systemInfo->get_gamma(); // Sinc Excitation Pulse exc=SeqPulsarSinc("exc",slicethick,true,4.0,commonPars->get_FlipAngle(),spatres,256); exc.set_freqlist( gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); if(Mode=="T1_LookLocker") exc.set_rephased(false); if(Mode=="B1") { exc.set_rephased(false); b1flips.resize(5); b1flips[0]=110.0; b1flips[1]=145.0; b1flips[2]=180.0; b1flips[3]=215.0; b1flips[4]=250.0; exc.set_flipangles(b1flips); exc.set_pulsduration(B1PulseDur); } // 90-180-90 Refocusing Pulse refoc=SeqPulsarBP("refoc", 1.0, 180.0); refoc.set_composite_pulse("90(x) 180(y) 90(x)"); refoc.set_pulse_type(refocusing); // Inversion Pulse inv=SeqPulsar("inv",false,false); inv.set_dim_mode(zeroDeeMode); inv.set_Tp(10.0); inv.resize(256); inv.set_spat_resolution(0.0); inv.set_shape("Wurst(2.96,26.48)"); // bandwidth ~ 1kHz inv.set_trajectory("Const(0.0,1.0)"); inv.set_filter("Gauss"); inv.set_pulse_type(inversion); inv.refresh(); ////////////////// Resolution: ///////////////////////////////// // uniform resolution in read and phase direction float Resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),Resolution)+0.5),noedit); //////////////// Phase Encoding: ////////////////////////// // Phase encoding before acquisition pe1=SeqGradPhaseEnc("pe1",commonPars->get_MatrixSize(phaseDirection),geometryInfo->get_FOV(phaseDirection), phaseDirection,0.25*systemInfo->get_max_grad(), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, commonPars->get_PartialFourier()); // Rephasing before the refocusing pulse for CPMG pe2=pe1; pe2.set_label("pe2"); pe2.invert_strength(); SeqObjList pe1dummy; pe1dummy+=pe1; dummype=SeqDelay("dummype",pe1dummy.get_duration()); //////////////// Readout: ////////////////////////////// float os_read=1.0; acqread=SeqAcqRead("acqread",commonPars->get_AcqSweepWidth(),commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), readDirection, os_read); dephaseMode dephmode=spinEcho; if(Mode=="T1_LookLocker" || Mode=="FIELD_MAP") dephmode=FID; readdeph=SeqAcqDeph("readdeph",acqread,dephmode); acqdummy=SeqDelay("acqdummy",acqread.get_duration()); //////////////// Gradient Echo Module: ////////////////////////////// grech=SeqGradEcho("grech", exc, commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, false, commonPars->get_PartialFourier()); //////////////// EPI module: ////////////////////////////// epi=SeqAcqEPI("epi",commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection), geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection), geometryInfo->get_FOV(phaseDirection), commonPars->get_MatrixSize(phaseDirection), 1, os_read,"",0,0,linear,false,1.0,0.0,NumOfEchoes/2); epideph=SeqAcqDeph("epideph",epi,FID); //////////////// Timng Delays: ////////////////////////////// excdelay=SeqDelay("excdelay",systemInfo->get_min_duration(delayObj)); echodelay1=SeqDelay("echodelay1",systemInfo->get_min_duration(delayObj)); echodelay2=SeqDelay("echodelay2",systemInfo->get_min_duration(delayObj)); relaxdelay=SeqDelay("relaxdelay",0.0); invdelay=SeqDelay("invdelay"); //////////////// Echo Vector: ////////////////////////////// // an index vector is used which is responsible for assigning // the ADCs to the correct k-space data in the reconstruction echovec=SeqVector("echovec",NumOfEchoes); //////////////// Loops: ////////////////////////////// echoloop=SeqObjLoop("echoloop"); dummyecholoop=SeqObjLoop("dummyecholoop"); peloop=SeqObjLoop("peloop"); sliceloop=SeqObjLoop("sliceloop"); acculoop=SeqObjLoop("acculoop"); fliploop=SeqObjLoop("fliploop"); //////////////// Spoiler: ////////////////////////////// double SpoilerDuration=2.0; double SpoilerStrength=60.0; float spoiler_strength_phys=(double)SpoilerStrength/100.0*systemInfo->get_max_grad(); spoiler1=SeqGradConstPulse("spoiler1",phaseDirection,spoiler_strength_phys,SpoilerDuration); fvector spoilertrims(NumOfEchoes); spoilertrims.fill_linear(-1.0,1.0); spoiler2=SeqGradVectorPulse("spoiler2",readDirection,spoiler_strength_phys,spoilertrims,SpoilerDuration*double(NumOfEchoes)); //////////////// Building the sequence: ////////////////////////////// postexc=SeqObjList("postexc"); postrefoc=SeqObjList("postrefoc"); postrefoctmpl=SeqObjList("postrefoctmpl"); echopart=SeqObjList("echopart"); grechpart=SeqObjList("grechpart"); dummyechopart=SeqObjList("dummyechopart"); kernel=SeqObjList("kernel"); slicepart=SeqObjList("slicepart"); if(Mode=="T2_CPMG") { postexc=excdelay + readdeph ; postrefoc= spoiler1 + echodelay1 + pe1; postrefoctmpl=spoiler1 + echodelay1 + dummype; echopart= spoiler1 + refoc + postrefoc + acqread + pe2 + echodelay2 ; dummyechopart= spoiler1 + refoc + postrefoctmpl + acqdummy + dummype + echodelay2 ; if (NumOfDummyEchoes>1) { kernel= exc + postexc + dummyecholoop(dummyechopart)[NumOfDummyEchoes] + echoloop(echopart)[echovec]; } else { kernel= exc + postexc + echoloop(echopart)[echovec]; } slicepart= sliceloop( kernel + relaxdelay )[exc]; set_sequence( acculoop( peloop( slicepart )[pe1][pe2] )[commonPars->get_NumOfRepetitions()] ); } if(Mode=="T1_LookLocker") { grechpart= sliceloop( grech )[exc]; echopart= grechpart + spoiler2 + echodelay1; kernel= inv + spoiler1 + invdelay + echoloop( echopart )[spoiler2]; slicepart= kernel + relaxdelay; set_sequence( acculoop ( peloop( slicepart )[grech.get_pe_vector()] )[commonPars->get_NumOfRepetitions()] ); } if(Mode=="FIELD_MAP") { kernel= exc + epideph + epi; slicepart= sliceloop( kernel + relaxdelay )[exc]; set_sequence( acculoop ( peloop( slicepart )[epideph.get_epi_segment_vector()] )[commonPars->get_NumOfRepetitions()] ); } if(Mode=="B1") { slicepart= sliceloop( grech + spoiler1 + relaxdelay )[exc]; set_sequence( fliploop( acculoop ( peloop( slicepart )[grech.get_pe_vector()] )[commonPars->get_NumOfRepetitions()] )[exc.get_flipangle_vector()] ); } } void METHOD_CLASS::method_rels() { Log odinlog(this,"method_rels"); //////////////// Timings: ////////////////////////////// float exc2refoc_duration; float refoc2acq_duration; float acq_shift; float min_echo_time=0.0; float mindelaydur=systemInfo->get_min_duration(delayObj); echodelay1.set_duration(mindelaydur); echodelay2.set_duration(mindelaydur); excdelay.set_duration(mindelaydur); EchoTimes.resize(NumOfEchoes); if(Mode=="T2_CPMG") { //////////////// Duration from the middle of the excitation pulse /////////////////// //////////////// to the middle of the refocusing pulse: ///////////////////////////// exc2refoc_duration=( exc.get_duration() - exc.get_magnetic_center() ) + postexc.get_duration() + echoloop.get_preduration() + spoiler1.get_duration() + refoc.get_magnetic_center(); if(min_echo_time < exc2refoc_duration*2.0 ) min_echo_time=exc2refoc_duration*2.0; float echoloopdur=echoloop.get_preduration()+echopart.get_duration(); if(min_echo_time < echoloopdur) min_echo_time=echoloopdur; if(commonPars->get_EchoTime()set_EchoTime(min_echo_time); echodelay1.set_duration( ( commonPars->get_EchoTime() - echoloopdur )/2.0 ); echodelay2.set_duration( ( commonPars->get_EchoTime() - echoloopdur )/2.0 ); //////////////// Duration from the middle of the refocusing pulse /////////////////// //////////////// to the middle of the acquisition window: /////////////////////////// refoc2acq_duration=( refoc.get_duration() - refoc.get_magnetic_center() ) + postrefoc.get_duration() + acqread.get_acquisition_center(); echoloopdur=echoloop.get_preduration()+echopart.get_duration(); acq_shift=refoc2acq_duration-echoloopdur/2.0; echodelay1.set_duration( echodelay1.get_duration() - acq_shift ); echodelay2.set_duration( echodelay2.get_duration() + acq_shift ); excdelay=commonPars->get_EchoTime()/2.0-exc2refoc_duration; EchoTimes.fill_linear(commonPars->get_EchoTime(),NumOfEchoes*commonPars->get_EchoTime()); } if(Mode=="T1_LookLocker") { float inv2acq_duration=( inv.get_duration() - inv.get_magnetic_center() ) +spoiler1.get_duration() +grech.get_acquisition_center(); if(MinEchoTimeget_RepetitionTime()set_RepetitionTime(slicepackdur); else relaxdelay=secureDivision(commonPars->get_RepetitionTime()-slicepackdur,n_slices_to_consider); float flipangle=90.0; if(Mode=="FIELD_MAP") { // calculate Ernst angle according to TR flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), ExpectedT1) ) ); commonPars->set_FlipAngle( flipangle, noedit ); } else if(Mode=="T1_LookLocker") { flipangle=commonPars->get_FlipAngle(); float maxflip=15.0; if(flipangle>maxflip) flipangle=maxflip; commonPars->set_FlipAngle( flipangle, edit ); } else { commonPars->set_FlipAngle( flipangle, noedit ); } if(Mode!="B1") { exc.set_flipangle( flipangle ); } } void METHOD_CLASS::method_pars_set() { Log odinlog(this,"method_pars_set"); if(Mode=="T2_CPMG") { // inform the readout about the used phase encoding and slice vector (for automatic reconstruction) acqread.set_reco_vector(line,pe1).set_reco_vector(slice,exc); // store different echoes in te dimension with echo times attached acqread.set_reco_vector(userdef, echovec, EchoTimes); recoInfo->set_PostProc3D("usercoll | expfit(true) "); } if(Mode=="T1_LookLocker") { // store different echoes in te dimension with echo times attached grech.set_reco_vector(userdef, spoiler2, EchoTimes); recoInfo->set_PostProc3D("usercoll | t1fit "); } if(Mode=="FIELD_MAP") { // inform the readout about the used slice vector (for automatic reconstruction) epi.set_reco_vector(slice,exc); // epi.set_te_offset(exc.get_duration()-exc.get_magnetic_center()+epideph.get_duration()); recoInfo->set_PreProc3D("tecoll | fieldmap "); // calculate fieldmap before summing up channels! } if(Mode=="B1") { // store different echoes in te dimension with echo times attached grech.set_reco_vector(userdef, exc.get_flipangle_vector(), fvector2dvector(b1flips)); recoInfo->set_PostProc3D("usercoll | b1fit "); } } /////////////////////////////////////////////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinprop.cpp0000644000175000017500000006071511625224371013744 00000000000000#include class METHOD_CLASS : public SeqMethod { private: JDXint Blades; JDXbool ShortAxis; JDXfloat BladeOversampling; JDXbool TakeMinEchoTime; JDXenum TemplateScan; JDXbool RampSampling; JDXenum RampMode; JDXfloat RampSteepness; JDXbool FatSaturation; JDXfloat T1Ernst; JDXenum EPIMode; JDXint DummyCycles; JDXint NumOfGradEchoes; JDXint NumOfSamples; JDXdouble PulseDur; JDXbool fMRITrigger; JDXbool UpDownBlade; JDXbool FieldMap; JDXbool InvertPartialFourier; SeqPulsar exc; SeqPulsar refoc; SeqSat fatsat; SeqAcqEPI epiacq; SeqDelay epiacq_dummy; SeqAcqEPI epiacq_template; SeqAcqEPI epiacq_grappa; SeqAcqDeph deph; SeqAcqDeph deph_template; SeqAcqDeph deph_grappa; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop bladeloop; SeqObjLoop grappaloop; SeqObjLoop dummyloop; SeqDelay trdelay; SeqObjList scan; SeqObjList dummypart; SeqObjList templatepart; SeqObjList grappapart; SeqObjList imagingpart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList slicepart_template; SeqObjList slicepart_grappa; SeqObjList preppart; SeqObjList bladepart; SeqDelay exc2acq; SeqDelay exc2refoc; SeqDelay refoc2acq; SeqGradConstPulse spoiler; SeqTrigger trigger; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqFieldMap fmapscan; SeqVecIter phaseiter; SeqGradTrapez deph3d; SeqGradTrapez blip3d_read; SeqGradTrapez blip3d_phase; SeqGradTrapez blip3d_template_read; SeqGradTrapez blip3d_template_phase; SeqGradTrapez blip3d_grappa_read; SeqGradTrapez blip3d_grappa_phase; SeqGradVectorPulse blip3d_slice; SeqGradChanParallel blip3d; SeqGradChanParallel blip3d_template; SeqGradChanParallel blip3d_grappa; SeqObjLoop loop3d; SeqVector index3d; SeqVector epiindex; SeqObjList epiacq_part; SeqObjList epiacq_dummy_part; SeqObjList epiacq_template_part; SeqObjList epiacq_grappa_part; SeqRotMatrixVector bladerot; SeqMagnReset reset; dvector bladeangels; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("EPI-based Periodically Rotated Overlapping ParallEL Lines with Enhanced Reconstruction (PROPELLER) sequence. See for example J. G. Pipe, Magn. Reson. Med. 42:963-969 (1999)"); } unsigned int numof_testcases() const {return 2;} void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,128); commonPars->set_MatrixSize(phaseDirection,128,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); Blades=8; Blades.set_description("Number of PROPELLER blades"); ShortAxis=false; ShortAxis.set_description("Readout direction along short axis of blades"); BladeOversampling=0.0; BladeOversampling.set_minmaxval(0.0,100.0); BladeOversampling.set_unit("%").set_description("Oversampling (overlap) in short direction of blade"); EPIMode.add_item("FIDMode"); EPIMode.add_item("SEMode"); EPIMode.set_actual("FIDMode"); EPIMode.set_description("Gradient-echo EPI (FIDMode) or spin-echo EPI (SEMode)"); TemplateScan.add_item("NoCorrection"); TemplateScan.add_item("PhaseCorrection"); TemplateScan.set_actual("PhaseCorrection"); TemplateScan.set_description("The type of template scan which is acquired beforehand"); RampSampling=false; RampSampling.set_description("Perform sampling during gradient ramps"); RampMode.add_item("linear",linear); RampMode.add_item("sinusoidal",sinusoidal); RampMode.add_item("half_sinusoidal",half_sinusoidal); RampMode.set_actual(linear); RampMode.set_description("The shape of the ramps of the read gradient"); RampSteepness=1.0; RampSteepness.set_description("Relative steepness (slew rate) of the EPI readout ramps"); FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); T1Ernst=0.0; T1Ernst.set_minmaxval(0.0,5000.0).set_description("If non-zero, the flip angle will be set to the Ernst angle using this T1 for optimum SNR"); TakeMinEchoTime=true; TakeMinEchoTime.set_description("Use minimum possible TE"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); fMRITrigger=true; fMRITrigger.set_description("External triggering"); InvertPartialFourier=false; InvertPartialFourier.set_description("Invert position in phase encoding direction at which partial Fourier cut off is performed (i.e. beginning or end of readout)"); UpDownBlade=false; UpDownBlade.set_description("Sample each blade twice with opposite phase-encoding direction"); FieldMap=false; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); PulseDur=4.0; // avoid initial high RF amplitude PulseDur.set_description("Pulse duration of excitation/refocusing pulse"); // register method parameters for user interface, parameter files, etc. append_parameter(Blades,"Blades"); append_parameter(ShortAxis,"ShortAxis"); append_parameter(EPIMode,"EPIMode"); append_parameter(TakeMinEchoTime,"TakeMinEchoTime"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(TemplateScan,"TemplateScan"); append_parameter(RampSampling,"RampSampling"); append_parameter(FatSaturation,"FatSaturation"); append_parameter(T1Ernst,"T1Ernst"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); append_parameter(UpDownBlade,"UpDownBlade"); append_parameter(PulseDur,"PulseDur"); append_parameter(fMRITrigger,"fMRITrigger"); append_parameter(InvertPartialFourier,"InvertPartialFourier"); if(systemInfo->get_platform()!=numaris_4) { append_parameter(BladeOversampling,"BladeOversampling"); append_parameter(RampMode,"RampMode"); append_parameter(RampSteepness,"RampSteepness"); append_parameter(NumOfGradEchoes,"NumOfGradEchoes",noedit); append_parameter(NumOfSamples,"NumOfSamples",noedit); } // alternative default settings for sequence test if(get_current_testcase()==1) { geometryInfo->set_Mode(voxel_3d); ShortAxis=false; BladeOversampling=0.0; TemplateScan.set_actual("NoCorrection"); } } void method_seq_init() { Log odinlog(this,"method_seq_init"); float gamma=systemInfo->get_gamma(); ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float slicegap=geometryInfo->get_sliceDistance()-slicethick; // Slightly thicker refocusing slice for better SNR // Since the same spatial resolution is used for exc and refoc, the gradient strengths will be the same float extra_slicethick_refoc=STD_min(0.5*slicethick, 0.3*slicegap); if(geometryInfo->get_Mode()==voxel_3d) { slicethick=0.8*geometryInfo->get_FOV(sliceDirection); extra_slicethick_refoc=0.2*slicethick; } float spatres=slicethick/4.0; // calculate Ernst angle accordng to TR float flipangle=commonPars->get_FlipAngle(); if(T1Ernst>0.0) { flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), T1Ernst) ) ); commonPars->set_FlipAngle( flipangle ); } // excitation pulse exc=SeqPulsarSinc("exc", slicethick, true,PulseDur,flipangle,spatres); exc.set_rephased(true, 0.8*systemInfo->get_max_grad()); // short rephaser exc.set_freqlist( gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); // refocusing pulse refoc=SeqPulsarSinc("refoc",slicethick+extra_slicethick_refoc,false,PulseDur,180.0,spatres); refoc.set_freqlist( gamma * refoc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); if(!commonPars->get_RFSpoiling()) refoc.set_phase(90.0); refoc.set_pulse_type(refocusing); // fat saturation module fatsat=SeqSat("fatsat",fat); //////////////// EPI-Readout: ////////////////////////////// // square FOV int sizeRadial=commonPars->get_MatrixSize(readDirection); commonPars->set_MatrixSize(phaseDirection,sizeRadial,noedit); int size3d=1; if(geometryInfo->get_Mode()==voxel_3d) { float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); size3d=int(secureDivision(geometryInfo->get_FOV(sliceDirection),resolution)+0.5); // isotropic resolution } commonPars->set_MatrixSize(sliceDirection,size3d,noedit); int readpts_blade=sizeRadial; int pelines_blade=sizeRadial; int bladewidth=sizeRadial; if(Blades>1) { float min_bladewidth=sizeRadial*tan(0.5*PII/Blades); // exact solution bladewidth=int( ( (1.0-0.01*BladeOversampling) * min_bladewidth + 0.01*BladeOversampling*sizeRadial ) +0.5 ); } if(ShortAxis) readpts_blade=bladewidth; else pelines_blade=bladewidth; float os_read=2.0; // For reduced undersampling artifacts float fov=geometryInfo->get_FOV(readDirection); // uniform FOV int epi_reduction=commonPars->get_ReductionFactor(); float epi_partfour=commonPars->get_PartialFourier(); if(geometryInfo->get_Mode()==voxel_3d) { epi_reduction=1; // 3D phase encoding gets the reduction epi_partfour=0.0; // 3D phase encoding gets the partial fourier } epiacq=SeqAcqEPI("epiacq",commonPars->get_AcqSweepWidth(), readpts_blade, fov, pelines_blade, fov, 1, epi_reduction, os_read, "", 0, 0, rampType(int(RampMode)), RampSampling, RampSteepness, epi_partfour, 0, InvertPartialFourier); // display sampling extents in read/phase direction NumOfGradEchoes=epiacq.get_numof_gradechoes(); NumOfSamples=epiacq.get_npts_read(); // Template scan fo EPI, begin with copy of actual EPI epiacq_template=epiacq; epiacq_template.set_label("epiacq_template"); // 1D phase correction if(TemplateScan=="PhaseCorrection") { epiacq_template.set_template_type(phasecorr_template); } // Full multi-shot EPI readout as GRAPPA training data epiacq_grappa=epiacq; epiacq_grappa.set_label("epiacq_grappa"); epiacq_grappa.set_template_type(grappa_template); // Delay instead of actual EPI readout for dummy scans epiacq_dummy=SeqDelay("epiacq_dummy",epiacq.get_duration()); // EPI pre-dephase gradient dephaseMode dephmode=FID; if (EPIMode=="SEMode") dephmode=spinEcho; deph=SeqAcqDeph("deph",epiacq,dephmode); deph_template=SeqAcqDeph("deph_template",epiacq_template,dephmode); deph_grappa=SeqAcqDeph("deph_grappa",epiacq_grappa,dephmode); //////////////// 3D encoding: ////////////////////////// if(geometryInfo->get_Mode()==voxel_3d) { // use SeqGradPhaseEnc as a template to calculate phase encoding SeqGradPhaseEnc pe3d("pe3d", commonPars->get_MatrixSize(sliceDirection), geometryInfo->get_FOV(sliceDirection), deph.get_gradduration(), sliceDirection, linearEncoding, noReorder, 1, commonPars->get_ReductionFactor(), DEFAULT_ACL_BANDS, commonPars->get_PartialFourier()); fvector gradints3d=pe3d.get_trims()*pe3d.get_constduration()*pe3d.get_strength(); ODINLOG(odinlog,normalDebug) << "gradints3d=" << gradints3d << STD_endl; const SeqVector& pe3dvec=pe3d; // access to vectorgrad ivector indexvec3d=pe3dvec.get_indexvec(); ODINLOG(odinlog,normalDebug) << "indexvec3d=" << indexvec3d << STD_endl; float strength3d=0.7*systemInfo->get_max_grad(); // dephaser before readout float dephintegral=0.0; if(gradints3d.size()) dephintegral=gradints3d[0]; deph3d=SeqGradTrapez("deph3d", dephintegral, strength3d, sliceDirection); deph/=deph3d; deph_template/=deph3d; deph_grappa/=deph3d; // rephasers inbetween readouts fvector rewind_integral=-epiacq.get_gradintegral(); fvector rewind_template_integral=-epiacq_template.get_gradintegral(); fvector rewind_grappa_integral=-epiacq_grappa.get_gradintegral(); blip3d_read= SeqGradTrapez("blip3d_read", rewind_integral[readDirection], strength3d, readDirection); blip3d_phase=SeqGradTrapez("blip3d_phase", rewind_integral[phaseDirection], strength3d, phaseDirection); blip3d_template_read= SeqGradTrapez("blip3d_template_read", rewind_template_integral[readDirection], strength3d, readDirection); blip3d_template_phase=SeqGradTrapez("blip3d_template_phase", rewind_template_integral[phaseDirection], strength3d, phaseDirection); blip3d_grappa_read= SeqGradTrapez("blip3d_grappa_read", rewind_grappa_integral[readDirection], strength3d, readDirection); blip3d_grappa_phase=SeqGradTrapez("blip3d_grappa_phase", rewind_grappa_integral[phaseDirection], strength3d, phaseDirection); // blip in slice direction fvector blipintegrals(gradints3d.size()); blipintegrals=0.0; for(unsigned int i=0; i<(gradints3d.size()-1); i++) blipintegrals[i]=gradints3d[i+1]-gradints3d[i]; // differences for blips ODINLOG(odinlog,normalDebug) << "blipintegrals=" << blipintegrals << STD_endl; float maxabsintegral=blipintegrals.maxabs(); float blipstrength_slice=sqrt(0.5*systemInfo->get_max_slew_rate()*maxabsintegral); // At least one half of the gradient as flat top float gradduration_slice=secureDivision(maxabsintegral, blipstrength_slice); blip3d_slice=SeqGradVectorPulse("blip3d_slice", sliceDirection, blipstrength_slice, blipintegrals/maxabsintegral, gradduration_slice); /* if(UpDownBlade) { deph3d.invert_strength(); blip3d_slice.invert_strength(); } */ blip3d=SeqGradChanParallel("blip3d"); blip3d_template=SeqGradChanParallel("blip3d_template"); blip3d_grappa=SeqGradChanParallel("blip3d_grappa"); blip3d += blip3d_read / blip3d_phase / blip3d_slice; blip3d_template += blip3d_template_read / blip3d_template_phase / blip3d_slice; blip3d_grappa += blip3d_grappa_read / blip3d_grappa_phase / blip3d_slice; index3d=SeqVector("index3d"); index3d.set_indexvec(indexvec3d); epiindex=SeqVector("epiindex",indexvec3d.size()); // to enumerate EPI readouts } /////////////////// Rotation of Blades //////////////////////////////////////////////// bladerot=SeqRotMatrixVector("bladerot"); bool full_cycle=UpDownBlade; //(geometryInfo->get_Mode()!=voxel_3d && UpDownBlade); int nangles=Blades; if(full_cycle) nangles=2*Blades; bladeangels.resize(nangles); for(int iangle=0; iangleget_RFSpoiling()) { // recommended by Goerke et al., NMR Biomed. 18, 534-542 (2005) int plistsize=16; double plistincr=45.0; exc.set_phasespoiling(plistsize, plistincr); refoc.set_phasespoiling(plistsize, plistincr, 90.0); epiacq.set_phasespoiling(plistsize, plistincr); epiacq_template.set_phasespoiling(plistsize, plistincr); epiacq_grappa.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(refoc.get_phaselist_vector()); phaseiter.add_vector(epiacq.get_phaselist_vector()); phaseiter.add_vector(epiacq_template.get_phaselist_vector()); phaseiter.add_vector(epiacq_grappa.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over blades bladeloop=SeqObjLoop("bladeloop"); // loop to iterate over GRAPPA interleaves to obtain training data grappaloop=SeqObjLoop("grappaloop"); // loop to iterate over dummy scans dummyloop=SeqObjLoop("dummyloop"); // loop to iterate over 3rd dimension phase encoding loop3d=SeqObjLoop("loop3d"); //////////////// Timing Delays: ////////////////////////////// trdelay=SeqDelay("trdelay"); //////////////// Spoiler Gradient: ////////////////////////////// double spoiler_strength=0.5*systemInfo->get_max_grad(); double spoiler_integral=4.0*fabs(deph.get_gradintegral().sum()); double spoiler_dur=secureDivision(spoiler_integral,spoiler_strength); spoiler=SeqGradConstPulse("spoiler",sliceDirection,spoiler_strength,spoiler_dur); //////////////// Crusher Gradient: ////////////////////////////// float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, spoiler_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// trigger: ////////////////////////////// trigger=SeqTrigger("fmri_trigger",1.0); reset=SeqMagnReset("reset"); //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0); } //////////////// Build the sequence: ////////////////////////////// preppart+=reset; epiacq_part=SeqObjList("epiacq_part"); epiacq_dummy_part=SeqObjList("epiacq_dummy_part"); epiacq_template_part=SeqObjList("epiacq_template_part"); epiacq_grappa_part=SeqObjList("epiacq_grappa_part"); if(geometryInfo->get_Mode()==voxel_3d) { epiacq_part += loop3d( epiacq + blip3d )[index3d][epiindex][blip3d_slice]; epiacq_dummy_part += loop3d( epiacq_dummy + blip3d )[index3d][epiindex][blip3d_slice]; epiacq_template_part += loop3d( epiacq_template + blip3d_template )[index3d][epiindex][blip3d_slice]; epiacq_grappa_part += loop3d( epiacq_grappa + blip3d_grappa )[index3d][epiindex][blip3d_slice]; } else { epiacq_part += epiacq; epiacq_dummy_part += epiacq_dummy; epiacq_template_part += epiacq_template; epiacq_grappa_part += epiacq_grappa; } // add fat saturation to template and repetitions if(FatSaturation) preppart += fatsat; if(fMRITrigger && (geometryInfo->get_Mode()!=voxel_3d) ) slicepart+= trigger; // trigger for each single blade if (EPIMode=="FIDMode") { dummypart= preppart + exc + deph + exc2acq + epiacq_dummy_part + crusherdelay + crusher; templatepart= preppart + exc + deph_template + exc2acq + epiacq_template_part + crusherdelay + crusher; grappapart= preppart + exc + deph_grappa + exc2acq + epiacq_grappa_part + crusherdelay + crusher; imagingpart= preppart + exc + deph + exc2acq + epiacq_part + crusherdelay + crusher; } if (EPIMode=="SEMode") { dummypart= preppart + exc + exc2refoc + deph + spoiler + refoc + spoiler + refoc2acq + epiacq_dummy_part + crusherdelay + crusher; templatepart= preppart + exc + exc2refoc + deph_template + spoiler + refoc + spoiler + refoc2acq + epiacq_template_part + crusherdelay + crusher; grappapart= preppart + exc + exc2refoc + deph_grappa + spoiler + refoc + spoiler + refoc2acq + epiacq_grappa_part + crusherdelay + crusher; imagingpart= preppart + exc + exc2refoc + deph + spoiler + refoc + spoiler + refoc2acq + epiacq_part + crusherdelay + crusher; } templatepart.set_gradrotmatrixvector(bladerot); grappapart. set_gradrotmatrixvector(bladerot); imagingpart. set_gradrotmatrixvector(bladerot); if (EPIMode=="FIDMode") { slicepart_dummy = sliceloop( dummypart + trdelay )[exc]; slicepart_template = sliceloop( templatepart + trdelay )[exc]; slicepart_grappa = sliceloop( grappapart + trdelay )[exc]; slicepart += sliceloop( imagingpart + trdelay )[exc]; } if (EPIMode=="SEMode") { slicepart_dummy = sliceloop( dummypart + trdelay )[exc][refoc]; slicepart_template = sliceloop( templatepart + trdelay )[exc][refoc]; slicepart_grappa = sliceloop( grappapart + trdelay )[exc][refoc]; slicepart += sliceloop( imagingpart + trdelay )[exc][refoc]; } if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; slicepart_template += phaseiter; slicepart_grappa += phaseiter; } if(FieldMap) scan += fmapscan + trdelay; if(DummyCycles>0) { scan+= dummyloop( slicepart_dummy )[DummyCycles]; } if(TemplateScan=="PhaseCorrection") { scan += bladeloop( slicepart_template )[bladerot]; } if(commonPars->get_ReductionFactor()>1) { // Fully sampled k-space scan+= grappaloop( bladeloop( slicepart_grappa )[bladerot] )[deph_grappa.get_epi_reduction_vector()]; } if(fMRITrigger && (geometryInfo->get_Mode()==voxel_3d) ) bladepart+= trigger; // trigger only for each full blade cycle bladepart+= bladeloop( slicepart )[bladerot]; scan+= reploop( bladepart )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { ////////////////// TE Timings: //////////////////////////////// double acq_center=epiacq.get_acquisition_center(); if(geometryInfo->get_Mode()==voxel_3d) acq_center= (1.0-commonPars->get_PartialFourier())*0.5*epiacq_part.get_duration(); double min_echo_time=0.0; if (EPIMode=="FIDMode") { min_echo_time=(exc.get_duration()-exc.get_magnetic_center())+deph.get_duration()+acq_center; if(commonPars->get_EchoTime()set_EchoTime(min_echo_time); if(TakeMinEchoTime) commonPars->set_EchoTime(min_echo_time); exc2acq=commonPars->get_EchoTime()-min_echo_time; } if (EPIMode=="SEMode") { //////////////// Duration from the middle of the excitation pulse /////////////////// //////////////// to the middle of the refocusing pulse: ///////////////////////////// double TE1=( exc.get_duration() - exc.get_magnetic_center() ) + deph.get_duration() + spoiler.get_duration() + refoc.get_magnetic_center(); if(min_echo_time<(2.0*TE1)) min_echo_time=2.0*TE1; //////////////// Duration from the middle of the refocusing pulse /////////////////// //////////////// to the middle of the acquisition window: /////////////////////////// double TE2=(refoc.get_duration() - refoc.get_magnetic_center()) + spoiler.get_duration() + acq_center; if(min_echo_time<(2.0*TE2)) min_echo_time=2.0*TE2; if (commonPars->get_EchoTime()set_EchoTime(min_echo_time); if(TakeMinEchoTime) commonPars->set_EchoTime(min_echo_time); exc2refoc=commonPars->get_EchoTime()/2.0-TE1; refoc2acq=commonPars->get_EchoTime()/2.0-TE2; } ////////////////// TR Timings: //////////////////////////////// // reset before recalculating timings trdelay=0.0; float slicedur=slicepart.get_duration(); if(commonPars->get_RepetitionTime()set_RepetitionTime(slicedur); trdelay=(commonPars->get_RepetitionTime()-slicedur)/double(geometryInfo->get_nSlices()); } void method_pars_set() { // extra information for the automatic reconstruction epiacq.set_reco_vector(slice,exc); epiacq_template.set_reco_vector(slice,exc); epiacq_grappa.set_reco_vector(slice,exc); if(geometryInfo->get_Mode()==voxel_3d) { epiacq.set_reco_vector(line3d,index3d); epiacq_template.set_reco_vector(line3d,index3d); epiacq_grappa.set_reco_vector(line3d,index3d); epiacq.set_reco_vector(epi, epiindex); epiacq_template.set_reco_vector(epi, epiindex); epiacq_grappa.set_reco_vector(epi, epiindex); // For multi-frequency distortion correction int nepi=epiindex.get_vectorsize(); dvector offsettime(nepi); double epidur=epiacq.get_duration() + blip3d.get_duration(); for(int i=0; iset_DimValues(epi,offsettime); } epiacq.set_reco_vector(cycle,bladerot); epiacq_template.set_reco_vector(cycle,bladerot); epiacq_grappa.set_reco_vector(cycle,bladerot); recoInfo->set_DimValues(cycle,bladeangels); // if(geometryInfo->get_Mode()==voxel_3d && UpDownBlade) recoInfo->set_CmdLineOpts("-ip -sflip"); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/odinrefg.cpp0000644000175000017500000001717011322062347013701 00000000000000#include class METHOD_CLASS : public SeqMethod { public: METHOD_CLASS(const STD_string& label); ~METHOD_CLASS() {delete_objs();} void method_pars_init(); void method_seq_init(); void method_rels(); void method_pars_set(); unsigned int numof_testcases() const {return 2;} private: void delete_objs(); JDXint NumOfRefgPulses; JDXdouble RefgainStartingValue; JDXdouble MaxFlipangle; JDXdoubleArr AttenuationVals; JDXdouble PulseGain; JDXdouble TemplPulseDuration; JDXdouble PulseDuration; JDXint NumOfDummyScans; JDXint NumOfReadPoints; JDXbool TestMode; SeqPulsar* exc_pulsar; SeqPulsNdim** exc; unsigned int numof_pulses; SeqPulsarReph reph; SeqAcqEPI* acqepi; SeqAcqEPI* acqtemplate; SeqAcq* acq; SeqAcqDeph deph; SeqAcqDeph dephtmpl; SeqObjLoop dummyloop; SeqDelay dummyacqdelay; SeqDelay relaxdelay; SeqObjVector exc_vector; SeqObjList slicepart; SeqObjLoop excloop; SeqObjLoop acculoop; }; ////////////////////////////////////////////////////////////////////////////////////////// void METHOD_CLASS::delete_objs() { if(exc_pulsar) delete exc_pulsar; exc_pulsar=0; // Use pointer-to-pointer because delete[] for objects does not work correctly on GCC2.9 if(exc) { for(unsigned int i=0; iset_MatrixSize(readDirection,48); commonPars->set_AcqSweepWidth(100.0); TestMode=false; TemplPulseDuration=4.0; // alternative default settings for sequence test if(get_current_testcase()==1) { TestMode=true; } if(systemInfo->get_platform()!=numaris_4) { append_parameter(RefgainStartingValue,"RefgainStartingValue"); append_parameter(MaxFlipangle,"MaxFlipangle"); append_parameter(NumOfRefgPulses,"NumOfRefgPulses"); append_parameter(AttenuationVals,"AttenuationVals",noedit); append_parameter(PulseGain,"PulseGain",noedit); append_parameter(TemplPulseDuration,"TemplPulseDuration"); append_parameter(PulseDuration,"PulseDuration",noedit); append_parameter(NumOfDummyScans,"NumOfDummyScans"); append_parameter(NumOfReadPoints,"NumOfReadPoints",noedit); } append_parameter(TestMode,"TestMode"); } void METHOD_CLASS::method_seq_init() { delete_objs(); relaxdelay=SeqDelay("relaxdelay",commonPars->get_RepetitionTime()); float resolution=secureDivision(geometryInfo->get_FOV(readDirection),commonPars->get_MatrixSize(readDirection)); commonPars->set_MatrixSize(phaseDirection,int(secureDivision(geometryInfo->get_FOV(phaseDirection),resolution))); commonPars->set_MatrixSize(phaseDirection,(commonPars->get_MatrixSize(phaseDirection)/2)*2); acqepi=new SeqAcqEPI("acqepi",commonPars->get_AcqSweepWidth(), commonPars->get_MatrixSize(readDirection),geometryInfo->get_FOV(readDirection), commonPars->get_MatrixSize(phaseDirection),geometryInfo->get_FOV(phaseDirection), 1,1,1.0,systemInfo->get_main_nucleus()); // use sagittal slice for reference gain Geometry sag; // dummy to calculate correct rotation matrix sag.set_orientation(sagittal); acqepi->set_gradrotmatrix(sag.get_gradrotmatrix()); acqtemplate=new SeqAcqEPI(*acqepi); acqtemplate->set_label("acqtemplate"); acqtemplate->set_template_type(phasecorr_template); acqtemplate->set_gradrotmatrix(sag.get_gradrotmatrix()); deph=SeqAcqDeph("deph",*acqepi); deph.set_gradrotmatrix(sag.get_gradrotmatrix()); dephtmpl=SeqAcqDeph("dephtmpl",*acqtemplate); dephtmpl.set_gradrotmatrix(sag.get_gradrotmatrix()); NumOfReadPoints=acqepi->get_npts_read(); numof_pulses=NumOfRefgPulses; if(!TestMode) exc=new SeqPulsNdim*[numof_pulses]; if(!TestMode) systemInfo->set_reference_gain(RefgainStartingValue); AttenuationVals.resize(NumOfRefgPulses); // allocate template pulse exc_pulsar=new SeqPulsarSinc("exc",5.0,true,TemplPulseDuration); exc_pulsar->set_nucleus(systemInfo->get_main_nucleus()); exc_pulsar->set_gradrotmatrix(sag.get_gradrotmatrix()); PulseGain=exc_pulsar->get_pulse_gain(); PulseDuration=exc_pulsar->get_pulsduration(); reph=SeqPulsarReph("reph",*exc_pulsar); float angle; int i,index; if(TestMode) { fvector flips(NumOfRefgPulses); for (i=0;iset_flipangles(flips); } else { // linear flipangle for (i=0;iset_flipangle(angle); exc[index]=new SeqPulsNdim(*exc_pulsar); exc[index]->set_gradrotmatrix(sag.get_gradrotmatrix()); AttenuationVals(index)=exc[index]->get_power(); } } slicepart=SeqObjList("slicepart"); dummyloop=SeqObjLoop("dummyloop"); dummyacqdelay=SeqDelay("dummyacqdelay",acqepi->get_duration()); if(NumOfDummyScans>0) { if(TestMode) { slicepart += dummyloop( *exc_pulsar + dephtmpl + dummyacqdelay + relaxdelay + *exc_pulsar + deph + dummyacqdelay + relaxdelay) [NumOfDummyScans]; } else { slicepart += dummyloop( *(exc[NumOfRefgPulses-1]) + reph + dephtmpl + dummyacqdelay + relaxdelay + *(exc[NumOfRefgPulses-1]) + reph + deph + dummyacqdelay + relaxdelay) [NumOfDummyScans]; } } exc_vector=SeqObjVector("exc_vector"); excloop=SeqObjLoop("excloop"); acculoop=SeqObjLoop("acculoop"); if(!TestMode) { for (i=0;iget_flipangle_vector()] + excloop ( *exc_pulsar + deph + (*acqepi) + relaxdelay ) [exc_pulsar->get_flipangle_vector()]; } else { slicepart += excloop ( exc_vector + reph + dephtmpl + (*acqtemplate) + relaxdelay ) [exc_vector] + excloop ( exc_vector + reph + deph + (*acqepi) + relaxdelay ) [exc_vector]; } set_sequence( acculoop(slicepart)[commonPars->get_NumOfRepetitions()] ); } void METHOD_CLASS::method_rels() { } void METHOD_CLASS::method_pars_set() { if(TestMode) { acqepi->set_reco_vector(userdef,exc_pulsar->get_flipangle_vector()); acqtemplate->set_reco_vector(userdef,exc_pulsar->get_flipangle_vector()); } else { acqepi->set_reco_vector(userdef,exc_vector,AttenuationVals); acqtemplate->set_reco_vector(userdef,exc_vector,AttenuationVals); recoInfo->set_PostProc3D("usercoll | refgain("+ftos(PulseDuration)+","+ftos(PulseGain)+")"); } } // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/sequences/mk_prop.cpp0000644000175000017500000004036611455553544013571 00000000000000#include class METHOD_CLASS : public SeqMethod { private: JDXint Blades; JDXbool ShortAxis; JDXfloat BladeOversampling; JDXbool TakeMinEchoTime; JDXbool RampSampling; JDXenum RampMode; JDXfloat RampSteepness; JDXbool FatSaturation; JDXfloat T1Ernst; JDXint DummyCycles; JDXint NumOfGradEchoes; JDXint NumOfSamples; JDXdouble PulseDur; JDXbool fMRITrigger; JDXbool UpDownBlade; JDXbool FieldMap; JDXbool EPIRef; SeqPulsar exc; SeqSat fatsat; SeqAcqEPI epiacq; SeqDelay epiacq_dummy; SeqAcqEPI epiacq_template; SeqAcqDeph deph; SeqAcqDeph deph_template; SeqObjLoop sliceloop; SeqObjLoop reploop; SeqObjLoop bladeloop; SeqObjLoop dummyloop; SeqDelay trdelay; SeqObjList scan; SeqObjList dummypart; SeqObjList templatepart; SeqObjList imagingpart; SeqObjList slicepart; SeqObjList slicepart_dummy; SeqObjList slicepart_template; SeqObjList preppart; SeqDelay exc2acq; SeqTrigger trigger; SeqGradTrapezParallel crusher; SeqDelay crusherdelay; SeqFieldMap fmapscan; SeqVecIter phaseiter; SeqRotMatrixVector bladerot; SeqMagnReset reset; // stuff for EPIRef SeqAcqEPI epiacq_ref; SeqDelay epiacq_ref_dummy; SeqAcqEPI epiacq_ref_template; SeqAcqEPI epiacq_ref_grappa; SeqAcqDeph deph_ref; SeqAcqDeph deph_ref_template; SeqAcqDeph deph_ref_grappa; SeqObjLoop grappaloop_ref; SeqDelay trdelay_ref; SeqObjList templatepart_ref; SeqObjList grappapart_ref; SeqObjList imagingpart_ref; SeqObjList slicepart_grappa_ref; SeqObjList slicepart_template_ref; SeqDelay exc2acq_ref; dvector bladeangels; public: // This constructor creates an empty EPI sequence METHOD_CLASS(const STD_string& label) : SeqMethod(label) { set_description("2D-PROPELLER-EPI with EPI reference scan."); } void method_pars_init() { // In this function, parameters are initialized and default values are set commonPars->set_MatrixSize(readDirection,128); commonPars->set_MatrixSize(phaseDirection,128,noedit); commonPars->set_NumOfRepetitions(1); commonPars->set_RepetitionTime(1000.0); commonPars->set_AcqSweepWidth(100.0); Blades=8; Blades.set_description("Number of PROPELLER blades"); ShortAxis=false; ShortAxis.set_description("Readout direction along short axis of blades"); BladeOversampling=1.0; BladeOversampling.set_minmaxval(0.0,100.0); BladeOversampling.set_unit("%").set_description("Oversampling (overlap) in short direction of blade"); RampSampling=false; RampSampling.set_description("Perform sampling during gradient ramps"); RampMode.add_item("linear",linear); RampMode.add_item("sinusoidal",sinusoidal); RampMode.add_item("half_sinusoidal",half_sinusoidal); RampMode.set_actual(linear); RampMode.set_description("The shape of the ramps of the read gradient"); RampSteepness=1.0; RampSteepness.set_description("Relative steepness (slew rate) of the EPI readout ramps"); FatSaturation=true; FatSaturation.set_description("Saturation of fat resonance prior to excitation"); T1Ernst=1300.0; T1Ernst.set_minmaxval(0.0,5000.0).set_description("If non-zero, the flip angle will be set to the Ernst angle using this T1 for optimum SNR"); TakeMinEchoTime=true; TakeMinEchoTime.set_description("Use minimum possible TE"); DummyCycles=3; DummyCycles.set_description("Number of dummy shots before actual acquisition"); fMRITrigger=true; fMRITrigger.set_description("External triggering"); UpDownBlade=false; UpDownBlade.set_description("Sample each blade twice with opposite phase-encoding direction"); FieldMap=false; FieldMap.set_description("Fieldmap pre-scan for distortion correction"); PulseDur=2.0; // avoid initial high RF amplitude PulseDur.set_description("Pulse duration of excitation/refocusing pulse"); EPIRef=false; EPIRef.set_description("Interleaved EPI reference scan"); // register method parameters for user interface, parameter files, etc. append_parameter(Blades,"Blades"); append_parameter(ShortAxis,"ShortAxis"); append_parameter(TakeMinEchoTime,"TakeMinEchoTime"); append_parameter(DummyCycles,"DummyCycles"); append_parameter(RampSampling,"RampSampling"); append_parameter(FatSaturation,"FatSaturation"); append_parameter(T1Ernst,"T1Ernst"); append_parameter(FieldMap,"FieldMap"); fmapscan.init("fmapscan"); append_parameter(fmapscan.get_parblock(),"FieldMapPars"); append_parameter(PulseDur,"PulseDur"); append_parameter(fMRITrigger,"fMRITrigger"); append_parameter(UpDownBlade,"UpDownBlade"); append_parameter(EPIRef,"EPIRef"); if(systemInfo->get_platform()!=numaris_4) { append_parameter(BladeOversampling,"BladeOversampling"); append_parameter(RampMode,"RampMode"); append_parameter(RampSteepness,"RampSteepness"); append_parameter(NumOfGradEchoes,"NumOfGradEchoes",noedit); append_parameter(NumOfSamples,"NumOfSamples",noedit); } } void method_seq_init() { Log odinlog(this,"method_seq_init"); float gamma=systemInfo->get_gamma(); ///////////////// Pulses: ///////////////////// float slicethick=geometryInfo->get_sliceThickness(); float spatres=slicethick/4.0; // calculate Ernst angle accordng to TR float flipangle=commonPars->get_FlipAngle(); if(T1Ernst>0.0) { flipangle=180.0/PII * acos( exp ( -secureDivision ( commonPars->get_RepetitionTime(), T1Ernst) ) ); commonPars->set_FlipAngle( flipangle ); } // excitation pulse exc=SeqPulsarSinc("exc", slicethick, true,PulseDur,flipangle,spatres); exc.set_rephased(true, 0.8*systemInfo->get_max_grad()); // short rephaser exc.set_freqlist( gamma * exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); exc.set_pulse_type(excitation); // fat saturation module fatsat=SeqSat("fatsat",fat); //////////////// EPI-Readout: ////////////////////////////// // square FOV int sizeRadial=commonPars->get_MatrixSize(readDirection); commonPars->set_MatrixSize(phaseDirection,sizeRadial,noedit); commonPars->set_MatrixSize(sliceDirection,1,noedit); int readpts_blade=sizeRadial; int pelines_blade=sizeRadial; int bladewidth=sizeRadial; if(Blades>1) { float min_bladewidth=sizeRadial*tan(0.5*PII/Blades); // exact solution bladewidth=int( ( (1.0-0.01*BladeOversampling) * min_bladewidth + 0.01*BladeOversampling*sizeRadial ) +0.5 ); } if(ShortAxis) readpts_blade=bladewidth; else pelines_blade=bladewidth; float os_read=2.0; // For reduced undersampling artifacts float fov=geometryInfo->get_FOV(readDirection); // uniform FOV epiacq=SeqAcqEPI("epiacq",commonPars->get_AcqSweepWidth(), readpts_blade, fov, pelines_blade, fov, 1, 1, os_read, "", 0, 0, rampType(int(RampMode)), RampSampling, RampSteepness, 0.0); // display sampling extents in read/phase direction NumOfGradEchoes=epiacq.get_numof_gradechoes(); NumOfSamples=epiacq.get_npts_read(); // Template scan fo EPI, begin with copy of actual EPI epiacq_template=epiacq; epiacq_template.set_label("epiacq_template"); // 1D phase correction epiacq_template.set_template_type(phasecorr_template); // Delay instead of actual EPI readout for dummy scans epiacq_dummy=SeqDelay("epiacq_dummy",epiacq.get_duration()); // EPI pre-dephase gradient deph=SeqAcqDeph("deph",epiacq); deph_template=SeqAcqDeph("deph_template",epiacq_template); /////////////////// Rotation of Blades //////////////////////////////////////////////// bladerot=SeqRotMatrixVector("bladerot"); bool full_cycle=UpDownBlade; int nangles=Blades; if(full_cycle) nangles=2*Blades; bladeangels.resize(nangles); for(int iangle=0; iangleget_AcqSweepWidth(), sizeRadial, fov, sizeRadial, fov, 1, commonPars->get_ReductionFactor(), os_read, "", 0, 0, rampType(int(RampMode)), RampSampling, RampSteepness, commonPars->get_PartialFourier()); // Template scan fo EPI, begin with copy of actual EPI epiacq_ref_template=epiacq_ref; epiacq_ref_template.set_label("epiacq_ref_template"); // 1D phase correction epiacq_ref_template.set_template_type(phasecorr_template); // Full multi-shot EPI readout as GRAPPA training data epiacq_ref_grappa=epiacq_ref; epiacq_ref_grappa.set_label("epiacq_ref_grappa"); epiacq_ref_grappa.set_template_type(grappa_template); // Delay instead of actual EPI readout for dummy scans epiacq_ref_dummy=SeqDelay("epiacq_ref_dummy",epiacq_ref.get_duration()); // EPI pre-dephase gradient deph_ref=SeqAcqDeph("deph_ref",epiacq_ref); deph_ref_template=SeqAcqDeph("deph_ref_template",epiacq_ref_template); deph_ref_grappa=SeqAcqDeph("deph_ref_grappa",epiacq_ref_grappa); } /////////////////// RF Spoiling /////////////////////////////////////////////////////// if(commonPars->get_RFSpoiling()) { // recommended by Goerke et al., NMR Biomed. 18, 534-542 (2005) int plistsize=16; double plistincr=45.0; exc.set_phasespoiling(plistsize, plistincr); epiacq.set_phasespoiling(plistsize, plistincr); epiacq_template.set_phasespoiling(plistsize, plistincr); epiacq_ref.set_phasespoiling(plistsize, plistincr); epiacq_ref_template.set_phasespoiling(plistsize, plistincr); epiacq_ref_grappa.set_phasespoiling(plistsize, plistincr); phaseiter=SeqVecIter("phaseiter"); phaseiter.add_vector(exc.get_phaselist_vector()); phaseiter.add_vector(epiacq.get_phaselist_vector()); phaseiter.add_vector(epiacq_template.get_phaselist_vector()); phaseiter.add_vector(epiacq_ref.get_phaselist_vector()); phaseiter.add_vector(epiacq_ref_template.get_phaselist_vector()); phaseiter.add_vector(epiacq_ref_grappa.get_phaselist_vector()); } //////////////// Loops: ////////////////////////////// // loop to iterate over slices sliceloop=SeqObjLoop("sliceloop"); // loop to iterate over repetitions reploop=SeqObjLoop("reploop"); // loop to iterate over blades bladeloop=SeqObjLoop("bladeloop"); // loop to iterate over dummy scans dummyloop=SeqObjLoop("dummyloop"); grappaloop_ref=SeqObjLoop("grappaloop_ref"); //////////////// Timing Delays: ////////////////////////////// trdelay=SeqDelay("trdelay"); trdelay_ref=SeqDelay("trdelay_ref"); //////////////// Crusher Gradient: ////////////////////////////// double spoiler_strength=0.5*systemInfo->get_max_grad(); double spoiler_integral=4.0*fabs(deph.get_gradintegral().sum()); float crusher_integral=2.0*spoiler_integral; crusher=SeqGradTrapezParallel("crusher",crusher_integral,crusher_integral,crusher_integral, spoiler_strength); crusherdelay=SeqDelay("crusherdelay",0.1); // Small delay to avoid gradient-induced stimulation //////////////// trigger: ////////////////////////////// trigger=SeqTrigger("fmri_trigger",1.0); reset=SeqMagnReset("reset"); //////////////// Field-map template: ////////////////////////////// if(FieldMap) { if(FatSaturation) fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0,fatsat); // pass fat saturation on to field-map scan else fmapscan.build_seq(commonPars->get_AcqSweepWidth(),1.0); } //////////////// Build the sequence: ////////////////////////////// preppart+=reset; // add fat saturation to template and repetitions if(FatSaturation) preppart += fatsat; dummypart= preppart + exc + deph + exc2acq + epiacq_dummy + crusherdelay + crusher; templatepart= preppart + exc + deph_template + exc2acq + epiacq_template + crusherdelay + crusher; imagingpart= preppart + exc + deph + exc2acq + epiacq + crusherdelay + crusher; if(EPIRef) { templatepart_ref= preppart + exc + deph_ref_template + exc2acq_ref + epiacq_ref_template + crusherdelay + crusher; grappapart_ref= preppart + exc + deph_ref_grappa + exc2acq_ref + epiacq_ref_grappa + crusherdelay + crusher; imagingpart_ref= preppart + exc + deph_ref + exc2acq_ref + epiacq_ref + crusherdelay + crusher; } templatepart.set_gradrotmatrixvector(bladerot); imagingpart. set_gradrotmatrixvector(bladerot); if(fMRITrigger) slicepart+= trigger; // trigger for PROPELLER interleave slicepart_dummy = sliceloop( dummypart + trdelay )[exc]; slicepart_template = sliceloop( templatepart + trdelay )[exc]; slicepart += sliceloop( imagingpart + trdelay )[exc]; if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_dummy += phaseiter; slicepart_template += phaseiter; } if(EPIRef) { if(fMRITrigger) slicepart+= trigger; // trigger for EPIRef interleave slicepart_template_ref = sliceloop( templatepart_ref + trdelay_ref )[exc]; slicepart_grappa_ref = sliceloop( grappapart_ref + trdelay_ref )[exc]; slicepart += sliceloop( imagingpart_ref + trdelay_ref )[exc]; if(commonPars->get_RFSpoiling()) { slicepart += phaseiter; slicepart_template_ref += phaseiter; slicepart_grappa_ref += phaseiter; } } if(FieldMap) scan += fmapscan + trdelay; if(DummyCycles>0) { scan+= dummyloop( slicepart_dummy )[DummyCycles]; } scan += bladeloop( slicepart_template )[bladerot]; if(EPIRef) { scan += slicepart_template_ref; if(commonPars->get_ReductionFactor()>1) { // Fully sampled k-space scan+= grappaloop_ref( slicepart_grappa_ref )[deph_ref_grappa.get_epi_reduction_vector()]; } } scan+= reploop( bladeloop( slicepart )[bladerot] )[commonPars->get_NumOfRepetitions()]; set_sequence( scan ); } void method_rels() { ////////////////// TE Timings: //////////////////////////////// double exc_te=exc.get_duration()-exc.get_magnetic_center(); double min_echo_time_blade= exc_te + deph.get_duration()+epiacq.get_acquisition_center(); double min_echo_time_ref=0.0; if(EPIRef) { min_echo_time_ref=exc_te + deph_ref.get_duration()+epiacq_ref.get_acquisition_center(); } double min_echo_time=STD_max(min_echo_time_blade, min_echo_time_ref); if(commonPars->get_EchoTime()set_EchoTime(min_echo_time); if(TakeMinEchoTime) commonPars->set_EchoTime(min_echo_time); exc2acq= commonPars->get_EchoTime()-min_echo_time_blade; exc2acq_ref=commonPars->get_EchoTime()-min_echo_time_ref; ////////////////// TR Timings: //////////////////////////////// double slicedur =imagingpart.get_duration()*geometryInfo->get_nSlices(); double slicedur_ref=imagingpart_ref.get_duration()*geometryInfo->get_nSlices(); double mintr=STD_max(slicedur, slicedur_ref); if(commonPars->get_RepetitionTime()set_RepetitionTime(mintr); trdelay =secureDivision(commonPars->get_RepetitionTime()-slicedur, geometryInfo->get_nSlices()); trdelay_ref=secureDivision(commonPars->get_RepetitionTime()-slicedur_ref, geometryInfo->get_nSlices()); } void method_pars_set() { // extra information for the automatic reconstruction epiacq. set_default_reco_index(userdef,0).set_reco_vector(slice,exc); epiacq_template.set_default_reco_index(userdef,0).set_reco_vector(slice,exc); epiacq_ref. set_default_reco_index(userdef,1).set_reco_vector(slice,exc); epiacq_ref_template.set_default_reco_index(userdef,1).set_reco_vector(slice,exc); epiacq_ref_grappa. set_default_reco_index(userdef,1).set_reco_vector(slice,exc); epiacq.set_reco_vector(cycle,bladerot); epiacq_template.set_reco_vector(cycle,bladerot); recoInfo->set_DimValues(cycle,bladeangels); } }; ///////////////////////////////////////////////////// // entry point for the sequence module ODINMETHOD_ENTRY_POINT odin-1.8.5/install.win0000755000175000017500000001250311665172216011577 00000000000000#!/bin/sh # installation wrapper-script to compile and install ODIN # on Windows using an MSYS UNIX shell command="`basename $0`" usage="usage: $command [-d (debug mode)] [-n (no multi-threading)] [-j ] [-a ] " # parse options EXTRA_CONFIG_OPTS="--disable-unit-test" EXTRA_CXXFLAGS="-mthreads" EXTRA_LDFLAGS="-mthreads" MFLAGS="" ACMLDIR="" dist="yes" continue="yes" while [ $continue = "yes" ] ; do case "$1" in -d) EXTRA_CONFIG_OPTS="--enable-debug" ; dist="no" ; shift 1 ;; -n) EXTRA_CXXFLAGS="" ; EXTRA_LDFLAGS="" ; EXTRA_CONFIG_OPTS="--disable-threads $EXTRA_CONFIG_OPTS" ; shift 1 ;; -j) shift 1 ; MFLAGS="-j $1" ; shift 1 ;; -a) shift 1 ; ACMLDIR="$1" ; EXTRA_BUILD_LDFLAGS="-L${ACMLDIR} $EXTRA_BUILD_LDFLAGS" ; EXTRA_CONFIG_OPTS="--enable-acmlsupport $EXTRA_CONFIG_OPTS" ; shift 1 ;; *) continue="no" ;; esac done case $# in 2) MR_SOFTWARE_DIR="$1" INSTALLDIR="$2";; *) echo $usage; exit;; esac for checkpath in "$MR_SOFTWARE_DIR" "$INSTALLDIR" "$ACMLDIR" ; do if test ! -z $checkpath ; then if ! (echo $checkpath | grep -q "^.:/") ; then echo "ERROR: Please use the drive letter notation X:/somedir instead of $checkpath" ; exit -1; fi fi done # -O2 does not work withc GCC 3.4.5 EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -O1" EXTRA_BUILD_CXXFLAGS="-I${MR_SOFTWARE_DIR}/include $EXTRA_BUILD_CXXFLAGS" EXTRA_BUILD_LDFLAGS="-L${MR_SOFTWARE_DIR}/lib $EXTRA_BUILD_LDFLAGS" QTDIR_SLASH="`echo $QTDIR | sed 's/\\\\/\\//g'`" echo "EXTRA_CXXFLAGS=$EXTRA_CXXFLAGS" echo "EXTRA_LDFLAGS =$EXTRA_LDFLAGS" echo "EXTRA_BUILD_CXXFLAGS=$EXTRA_BUILD_CXXFLAGS" echo "EXTRA_BUILD_LDFLAGS =$EXTRA_BUILD_LDFLAGS" echo "EXTRA_CONFIG_OPTS =$EXTRA_CONFIG_OPTS" if [ ! -f Makefile ] ; then if ! CXXFLAGS="$EXTRA_CXXFLAGS" LDFLAGS="$EXTRA_LDFLAGS" ./configure \ --with-extra-build-cxxflags="$EXTRA_BUILD_CXXFLAGS" \ --with-extra-build-ldflags="$EXTRA_BUILD_LDFLAGS" \ --prefix=$INSTALLDIR \ --with-qt-dir="$QTDIR_SLASH" \ --enable-static --disable-shared \ $EXTRA_CONFIG_OPTS then echo "ERROR: MinGW configure failed" exit -1 fi fi if ! make $MFLAGS install ; then echo "ERROR: MinGW build failed" exit -1 fi if [ $dist = "yes" ] ; then # Modify doxygen file: Add dot path cat odin.doxygen | grep -v DOT_PATH > odin.doxygen.tmp mv odin.doxygen.tmp odin.doxygen echo "DOT_PATH = c:/Programme/ATT/Graphviz/bin" >> odin.doxygen # Add path for extra DLLs required during printing usage for manual export PATH="$PATH":"$MR_SOFTWARE_DIR/bin" if [ ! -d manual ] ; then echo -n "Creating Manual ..." if ! (cp /c/Programme/Doxygen/doxygen.exe . && make manual && mkdir -p $INSTALLDIR/share/doc/odin && cp -r manual $INSTALLDIR/share/doc/odin/) then echo "ERROR: Manual failed" exit -1 fi fi fi echo -n "Copying ODIN source code to $INSTALLDIR ..." if ! (make dist && mkdir -p $INSTALLDIR/src && cp odin-*.tar.gz $INSTALLDIR/src/) then echo "ERROR: Copy source failed" exit -1 fi echo "done" echo -n "Copying MR-Software stuff to $INSTALLDIR ..." for mrsoftbin in notepad2.exe ; do cp $MR_SOFTWARE_DIR/bin/$mrsoftbin $INSTALLDIR/bin done for mrsoftinclude in blitz ; do cp -r $MR_SOFTWARE_DIR/include/$mrsoftinclude $INSTALLDIR/include done for mrsoftlib in libniftiio.a libznz.a libz.a libgsl.a libgslcblas.a libblitz.a libofstd.a libdcmdata.a libdcmimgle.a ; do cp $MR_SOFTWARE_DIR/lib/$mrsoftlib $INSTALLDIR/lib done echo "done" echo -n "Copying MinGW stuff to $INSTALLDIR ..." MINGWDIR=$(dirname $(dirname $(which g++))) for subdir in bin include lib libexec mingw32 ; do cp -r $MINGWDIR/$subdir $INSTALLDIR/ done echo "done" echo -n "Copying MSYS stuff to $INSTALLDIR ..." mkdir -p $INSTALLDIR/msys for subdir in /bin /etc ; do cp -r $subdir $INSTALLDIR/msys done echo "done" echo -n "Setting up $INSTALLDIR/bin/shell.bat ..." echo 'set PATH=%1\bin;%PATH%' > $INSTALLDIR/bin/shell.bat echo 'set LD_LIBRARY_PATH=%1\lib;%LD_LIBRARY_PATH%' >> $INSTALLDIR/bin/shell.bat echo 'set LIBRARY_PATH=%1\lib;%LIBRARY_PATH%' >> $INSTALLDIR/bin/shell.bat echo 'set CPLUS_INCLUDE_PATH=%1\include;%CPLUS_INCLUDE_PATH%' >> $INSTALLDIR/bin/shell.bat echo 'set MANPATH=%1\man;%MANPATH%' >> $INSTALLDIR/bin/shell.bat echo 'start %1%\msys\bin\rxvt.exe -backspacekey  -sl 2500 -fg White -bg Black -sr -fn Courier-12 -tn msys -e /bin/sh --login -i' >> $INSTALLDIR/bin/shell.bat echo "done" echo -n "Creating dummy cygpath ..." echo "#!/bin/sh" > $INSTALLDIR/msys/bin/cygpath echo "eval echo \\\"\\\$\\{\$#\\}\\\"" >> $INSTALLDIR/msys/bin/cygpath echo "done" echo -n "Copying Qt stuff to $INSTALLDIR ..." for qtbin in QtCore4.dll QtGui4.dll ; do cp $QTDIR_SLASH/bin/$qtbin $INSTALLDIR/bin done echo "done" if test ! -z $ACMLDIR ; then echo -n "Copying AMD Core Math Lib to $INSTALLDIR ..." cp $ACMLDIR/libacml.a $INSTALLDIR/lib echo "done" fi if [ $dist = "yes" ] ; then echo -n "Creating NSIS distribution ..." rm -f $INSTALLDIR/bin/odintestsuite.exe # Remove obsolete stuff before distributing VERSION=`grep "VERSION=[0-9].[0-9].[0-9]" configure | sed s/\ *VERSION=//` cat odin.nsi | sed s/VERSION/$VERSION/ > $INSTALLDIR/odin.nsi OLDPWD=$PWD pushd $INSTALLDIR if ! /c/Programme/NSIS/makensis.exe odin.nsi then echo "ERROR: NSIS failed" fi mv odin-${VERSION}.exe $OLDPWD pushd $OLDPWD fi odin-1.8.5/coils/0000755000175000017500000000000011735135552010577 500000000000000odin-1.8.5/coils/radialInhomogen.coi0000644000175000017500000053226111322062355014314 00000000000000##TITLE=Coil Sensitivity ##$FOV=( 3 ) 200.0 200.0 200.0 ##$SensitivityMap=( 1, 1, 128, 128 ) Encoding:base64,littleEndian,complex AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAALA7AAAAAAAAMDwAAAAAAAB4PAAAAAAAAJg8AAAAAAAArDwAAAAA AAC4PAAAAAAAALw8AAAAAAAAuDwAAAAAAACsPAAAAAAAAJg8AAAAAAAAeDwAAAAAAAAwPAAA AAAAALA7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAADAOwAAAAAAAIw8AAAAAAAA4DwAAAAAAAAWPQAAAAAAADg9 AAAAAAAAVj0AAAAAAABwPQAAAAAAAIM9AAAAAAAAjD0AAAAAAACTPQAAAAAAAJg9AAAAAAAA mz0AAAAAAACcPQAAAAAAAJs9AAAAAAAAmD0AAAAAAACTPQAAAAAAAIw9AAAAAAAAgz0AAAAA AABwPQAAAAAAAFY9AAAAAAAAOD0AAAAAAAAWPQAAAAAAAOA8AAAAAAAAjDwAAAAAAADAOwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGA7AAAAAAAAmDwAAAAA AAAGPQAAAAAAADw9AAAAAAAAbj0AAAAAAACOPQAAAAAAAKM9AAAAAAAAtj0AAAAAAADHPQAA AAAAANY9AAAAAAAA4z0AAAAAAADuPQAAAAAAAPc9AAAAAAAA/j0AAAAAAIABPgAAAAAAAAM+ AAAAAACAAz4AAAAAAAADPgAAAAAAgAE+AAAAAAAA/j0AAAAAAAD3PQAAAAAAAO49AAAAAAAA 4z0AAAAAAADWPQAAAAAAAMc9AAAAAAAAtj0AAAAAAACjPQAAAAAAAI49AAAAAAAAbj0AAAAA AAA8PQAAAAAAAAY9AAAAAAAAmDwAAAAAAABgOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABgOwAAAAAAALA8AAAAAAAAHj0AAAAAAABgPQAAAAAAAI89AAAAAAAA rD0AAAAAAADHPQAAAAAAAOA9AAAAAAAA9z0AAAAAAAAGPgAAAAAAgA8+AAAAAAAAGD4AAAAA AIAfPgAAAAAAACY+AAAAAACAKz4AAAAAAAAwPgAAAAAAgDM+AAAAAAAANj4AAAAAAIA3PgAA AAAAADg+AAAAAACANz4AAAAAAAA2PgAAAAAAgDM+AAAAAAAAMD4AAAAAAIArPgAAAAAAACY+ AAAAAACAHz4AAAAAAAAYPgAAAAAAgA8+AAAAAAAABj4AAAAAAAD3PQAAAAAAAOA9AAAAAAAA xz0AAAAAAACsPQAAAAAAAI89AAAAAAAAYD0AAAAAAAAePQAAAAAAALA8AAAAAAAAYDsAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwPAAA AAAAAA49AAAAAAAAXD0AAAAAAACTPQAAAAAAALY9AAAAAAAA1z0AAAAAAAD2PQAAAAAAgAk+ AAAAAAAAFz4AAAAAAIAjPgAAAAAAAC8+AAAAAACAOT4AAAAAAABDPgAAAAAAgEs+AAAAAAAA Uz4AAAAAAIBZPgAAAAAAAF8+AAAAAACAYz4AAAAAAABnPgAAAAAAgGk+AAAAAAAAaz4AAAAA AIBrPgAAAAAAAGs+AAAAAACAaT4AAAAAAABnPgAAAAAAgGM+AAAAAAAAXz4AAAAAAIBZPgAA AAAAAFM+AAAAAACASz4AAAAAAABDPgAAAAAAgDk+AAAAAAAALz4AAAAAAIAjPgAAAAAAABc+ AAAAAACACT4AAAAAAAD2PQAAAAAAANc9AAAAAAAAtj0AAAAAAACTPQAAAAAAAFw9AAAAAAAA Dj0AAAAAAABwPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACsPAAAAAAAADA9AAAAAAAAgz0AAAAA AACsPQAAAAAAANM9AAAAAAAA+D0AAAAAAIANPgAAAAAAAB4+AAAAAACALT4AAAAAAAA8PgAA AAAAgEk+AAAAAAAAVj4AAAAAAIBhPgAAAAAAAGw+AAAAAACAdT4AAAAAAAB+PgAAAAAAwII+ AAAAAAAAhj4AAAAAAMCIPgAAAAAAAIs+AAAAAADAjD4AAAAAAACOPgAAAAAAwI4+AAAAAAAA jz4AAAAAAMCOPgAAAAAAAI4+AAAAAADAjD4AAAAAAACLPgAAAAAAwIg+AAAAAAAAhj4AAAAA AMCCPgAAAAAAAH4+AAAAAACAdT4AAAAAAABsPgAAAAAAgGE+AAAAAAAAVj4AAAAAAIBJPgAA AAAAADw+AAAAAACALT4AAAAAAAAePgAAAAAAgA0+AAAAAAAA+D0AAAAAAADTPQAAAAAAAKw9 AAAAAAAAgz0AAAAAAAAwPQAAAAAAAKw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAC4PAAAAAAAAD49AAAAAAAAjj0AAAAAAAC7PQAAAAAAAOY9AAAAAACA Bz4AAAAAAAAbPgAAAAAAgC0+AAAAAAAAPz4AAAAAAIBPPgAAAAAAAF8+AAAAAACAbT4AAAAA AAB7PgAAAAAAwIM+AAAAAACAiT4AAAAAAMCOPgAAAAAAgJM+AAAAAADAlz4AAAAAAICbPgAA AAAAwJ4+AAAAAACAoT4AAAAAAMCjPgAAAAAAgKU+AAAAAADApj4AAAAAAICnPgAAAAAAwKc+ AAAAAACApz4AAAAAAMCmPgAAAAAAgKU+AAAAAADAoz4AAAAAAIChPgAAAAAAwJ4+AAAAAACA mz4AAAAAAMCXPgAAAAAAgJM+AAAAAADAjj4AAAAAAICJPgAAAAAAwIM+AAAAAAAAez4AAAAA AIBtPgAAAAAAAF8+AAAAAACATz4AAAAAAAA/PgAAAAAAgC0+AAAAAAAAGz4AAAAAAIAHPgAA AAAAAOY9AAAAAAAAuz0AAAAAAACOPQAAAAAAAD49AAAAAAAAuDwAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACcPAAA AAAAADg9AAAAAAAAjz0AAAAAAADAPQAAAAAAAO89AAAAAAAADj4AAAAAAIAjPgAAAAAAADg+ AAAAAACASz4AAAAAAABePgAAAAAAgG8+AAAAAAAAgD4AAAAAAMCHPgAAAAAAAI8+AAAAAADA lT4AAAAAAACcPgAAAAAAwKE+AAAAAAAApz4AAAAAAMCrPgAAAAAAALA+AAAAAADAsz4AAAAA AAC3PgAAAAAAwLk+AAAAAAAAvD4AAAAAAMC9PgAAAAAAAL8+AAAAAADAvz4AAAAAAADAPgAA AAAAwL8+AAAAAAAAvz4AAAAAAMC9PgAAAAAAALw+AAAAAADAuT4AAAAAAAC3PgAAAAAAwLM+ AAAAAAAAsD4AAAAAAMCrPgAAAAAAAKc+AAAAAADAoT4AAAAAAACcPgAAAAAAwJU+AAAAAAAA jz4AAAAAAMCHPgAAAAAAAIA+AAAAAACAbz4AAAAAAABePgAAAAAAgEs+AAAAAAAAOD4AAAAA AIAjPgAAAAAAAA4+AAAAAAAA7z0AAAAAAADAPQAAAAAAAI89AAAAAAAAOD0AAAAAAACcPAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 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 AAAAAAAAzj0AAAAAAACTPQAAAAAAACw9AAAAAAAAODwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvDwAAAAA AABgPQAAAAAAAK89AAAAAAAA7D0AAAAAAIATPgAAAAAAADA+AAAAAACASz4AAAAAAABmPgAA AAAAgH8+AAAAAAAAjD4AAAAAAMCXPgAAAAAAAKM+AAAAAADArT4AAAAAAAC4PgAAAAAAwME+ AAAAAAAAyz4AAAAAAMDTPgAAAAAAANw+AAAAAADA4z4AAAAAAADrPgAAAAAAwPE+AAAAAAAA +D4AAAAAAMD9PgAAAAAAgAE/AAAAAADgAz8AAAAAAAAGPwAAAAAA4Ac/AAAAAACACT8AAAAA AOAKPwAAAAAAAAw/AAAAAADgDD8AAAAAAIANPwAAAAAA4A0/AAAAAAAADj8AAAAAAOANPwAA AAAAgA0/AAAAAADgDD8AAAAAAAAMPwAAAAAA4Ao/AAAAAACACT8AAAAAAOAHPwAAAAAAAAY/ AAAAAADgAz8AAAAAAIABPwAAAAAAwP0+AAAAAAAA+D4AAAAAAMDxPgAAAAAAAOs+AAAAAADA 4z4AAAAAAADcPgAAAAAAwNM+AAAAAAAAyz4AAAAAAMDBPgAAAAAAALg+AAAAAADArT4AAAAA AACjPgAAAAAAwJc+AAAAAAAAjD4AAAAAAIB/PgAAAAAAAGY+AAAAAACASz4AAAAAAAAwPgAA AAAAgBM+AAAAAAAA7D0AAAAAAACvPQAAAAAAAGA9AAAAAAAAvDwAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGPQAAAAAAAIY9AAAAAAAA xz0AAAAAAAADPgAAAAAAgCE+AAAAAAAAPz4AAAAAAIBbPgAAAAAAAHc+AAAAAADAiD4AAAAA AICVPgAAAAAAwKE+AAAAAACArT4AAAAAAMC4PgAAAAAAgMM+AAAAAADAzT4AAAAAAIDXPgAA AAAAwOA+AAAAAACA6T4AAAAAAMDxPgAAAAAAgPk+AAAAAABgAD8AAAAAAMADPwAAAAAA4AY/ AAAAAADACT8AAAAAAGAMPwAAAAAAwA4/AAAAAADgED8AAAAAAMASPwAAAAAAYBQ/AAAAAADA FT8AAAAAAOAWPwAAAAAAwBc/AAAAAABgGD8AAAAAAMAYPwAAAAAA4Bg/AAAAAADAGD8AAAAA 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 AAAA4Aw/AAAAAACADT8AAAAAAOANPwAAAAAAAA4/AAAAAADgDT8AAAAAAIANPwAAAAAA4Aw/ AAAAAAAADD8AAAAAAOAKPwAAAAAAgAk/AAAAAADgBz8AAAAAAAAGPwAAAAAA4AM/AAAAAACA AT8AAAAAAMD9PgAAAAAAAPg+AAAAAADA8T4AAAAAAADrPgAAAAAAwOM+AAAAAAAA3D4AAAAA AMDTPgAAAAAAAMs+AAAAAADAwT4AAAAAAAC4PgAAAAAAwK0+AAAAAAAAoz4AAAAAAMCXPgAA AAAAAIw+AAAAAACAfz4AAAAAAABmPgAAAAAAgEs+AAAAAAAAMD4AAAAAAIATPgAAAAAAAOw9 AAAAAAAArz0AAAAAAABgPQAAAAAAALw8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADg8AAAAAAAALD0AAAAA AACTPQAAAAAAAM49AAAAAACAAz4AAAAAAAAfPgAAAAAAgDk+AAAAAAAAUz4AAAAAAIBrPgAA AAAAgIE+AAAAAADAjD4AAAAAAICXPgAAAAAAwKE+AAAAAACAqz4AAAAAAMC0PgAAAAAAgL0+ AAAAAADAxT4AAAAAAIDNPgAAAAAAwNQ+AAAAAACA2z4AAAAAAMDhPgAAAAAAgOc+AAAAAADA 7D4AAAAAAIDxPgAAAAAAwPU+AAAAAACA+T4AAAAAAMD8PgAAAAAAgP8+AAAAAADgAD8AAAAA AMABPwAAAAAAYAI/AAAAAADAAj8AAAAAAOACPwAAAAAAwAI/AAAAAABgAj8AAAAAAMABPwAA AAAA4AA/AAAAAACA/z4AAAAAAMD8PgAAAAAAgPk+AAAAAADA9T4AAAAAAIDxPgAAAAAAwOw+ AAAAAACA5z4AAAAAAMDhPgAAAAAAgNs+AAAAAADA1D4AAAAAAIDNPgAAAAAAwMU+AAAAAACA vT4AAAAAAMC0PgAAAAAAgKs+AAAAAADAoT4AAAAAAICXPgAAAAAAwIw+AAAAAACAgT4AAAAA AIBrPgAAAAAAAFM+AAAAAACAOT4AAAAAAAAfPgAAAAAAgAM+AAAAAAAAzj0AAAAAAACTPQAA AAAAACw9AAAAAAAAODwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 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 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALg8AAAAAAAAPj0AAAAAAACOPQAA AAAAALs9AAAAAAAA5j0AAAAAAIAHPgAAAAAAABs+AAAAAACALT4AAAAAAAA/PgAAAAAAgE8+ AAAAAAAAXz4AAAAAAIBtPgAAAAAAAHs+AAAAAADAgz4AAAAAAICJPgAAAAAAwI4+AAAAAACA kz4AAAAAAMCXPgAAAAAAgJs+AAAAAADAnj4AAAAAAIChPgAAAAAAwKM+AAAAAACApT4AAAAA AMCmPgAAAAAAgKc+AAAAAADApz4AAAAAAICnPgAAAAAAwKY+AAAAAACApT4AAAAAAMCjPgAA AAAAgKE+AAAAAADAnj4AAAAAAICbPgAAAAAAwJc+AAAAAACAkz4AAAAAAMCOPgAAAAAAgIk+ AAAAAADAgz4AAAAAAAB7PgAAAAAAgG0+AAAAAAAAXz4AAAAAAIBPPgAAAAAAAD8+AAAAAACA LT4AAAAAAAAbPgAAAAAAgAc+AAAAAAAA5j0AAAAAAAC7PQAAAAAAAI49AAAAAAAAPj0AAAAA AAC4PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAArDwAAAAA AAAwPQAAAAAAAIM9AAAAAAAArD0AAAAAAADTPQAAAAAAAPg9AAAAAACADT4AAAAAAAAePgAA AAAAgC0+AAAAAAAAPD4AAAAAAIBJPgAAAAAAAFY+AAAAAACAYT4AAAAAAABsPgAAAAAAgHU+ AAAAAAAAfj4AAAAAAMCCPgAAAAAAAIY+AAAAAADAiD4AAAAAAACLPgAAAAAAwIw+AAAAAAAA jj4AAAAAAMCOPgAAAAAAAI8+AAAAAADAjj4AAAAAAACOPgAAAAAAwIw+AAAAAAAAiz4AAAAA AMCIPgAAAAAAAIY+AAAAAADAgj4AAAAAAAB+PgAAAAAAgHU+AAAAAAAAbD4AAAAAAIBhPgAA AAAAAFY+AAAAAACAST4AAAAAAAA8PgAAAAAAgC0+AAAAAAAAHj4AAAAAAIANPgAAAAAAAPg9 AAAAAAAA0z0AAAAAAACsPQAAAAAAAIM9AAAAAAAAMD0AAAAAAACsPAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABwPAAAAAAAAA49AAAAAAAAXD0AAAAAAACTPQAAAAAAALY9AAAAAAAA1z0AAAAA AAD2PQAAAAAAgAk+AAAAAAAAFz4AAAAAAIAjPgAAAAAAAC8+AAAAAACAOT4AAAAAAABDPgAA AAAAgEs+AAAAAAAAUz4AAAAAAIBZPgAAAAAAAF8+AAAAAACAYz4AAAAAAABnPgAAAAAAgGk+ AAAAAAAAaz4AAAAAAIBrPgAAAAAAAGs+AAAAAACAaT4AAAAAAABnPgAAAAAAgGM+AAAAAAAA Xz4AAAAAAIBZPgAAAAAAAFM+AAAAAACASz4AAAAAAABDPgAAAAAAgDk+AAAAAAAALz4AAAAA AIAjPgAAAAAAABc+AAAAAACACT4AAAAAAAD2PQAAAAAAANc9AAAAAAAAtj0AAAAAAACTPQAA AAAAAFw9AAAAAAAADj0AAAAAAABwPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGA7AAAAAAAAsDwAAAAAAAAePQAAAAAAAGA9AAAAAAAA jz0AAAAAAACsPQAAAAAAAMc9AAAAAAAA4D0AAAAAAAD3PQAAAAAAAAY+AAAAAACADz4AAAAA AAAYPgAAAAAAgB8+AAAAAAAAJj4AAAAAAIArPgAAAAAAADA+AAAAAACAMz4AAAAAAAA2PgAA AAAAgDc+AAAAAAAAOD4AAAAAAIA3PgAAAAAAADY+AAAAAACAMz4AAAAAAAAwPgAAAAAAgCs+ AAAAAAAAJj4AAAAAAIAfPgAAAAAAABg+AAAAAACADz4AAAAAAAAGPgAAAAAAAPc9AAAAAAAA 4D0AAAAAAADHPQAAAAAAAKw9AAAAAAAAjz0AAAAAAABgPQAAAAAAAB49AAAAAAAAsDwAAAAA AABgOwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgOwAAAAAAAJg8 AAAAAAAABj0AAAAAAAA8PQAAAAAAAG49AAAAAAAAjj0AAAAAAACjPQAAAAAAALY9AAAAAAAA xz0AAAAAAADWPQAAAAAAAOM9AAAAAAAA7j0AAAAAAAD3PQAAAAAAAP49AAAAAACAAT4AAAAA AAADPgAAAAAAgAM+AAAAAAAAAz4AAAAAAIABPgAAAAAAAP49AAAAAAAA9z0AAAAAAADuPQAA AAAAAOM9AAAAAAAA1j0AAAAAAADHPQAAAAAAALY9AAAAAAAAoz0AAAAAAACOPQAAAAAAAG49 AAAAAAAAPD0AAAAAAAAGPQAAAAAAAJg8AAAAAAAAYDsAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAADAOwAAAAAAAIw8AAAAAAAA4DwAAAAAAAAWPQAAAAAAADg9 AAAAAAAAVj0AAAAAAABwPQAAAAAAAIM9AAAAAAAAjD0AAAAAAACTPQAAAAAAAJg9AAAAAAAA mz0AAAAAAACcPQAAAAAAAJs9AAAAAAAAmD0AAAAAAACTPQAAAAAAAIw9AAAAAAAAgz0AAAAA AABwPQAAAAAAAFY9AAAAAAAAOD0AAAAAAAAWPQAAAAAAAOA8AAAAAAAAjDwAAAAAAADAOwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAsDsAAAAAAAAwPAAAAAAAAHg8AAAAAAAAmDwAAAAAAACsPAAAAAAAALg8 AAAAAAAAvDwAAAAAAAC4PAAAAAAAAKw8AAAAAAAAmDwAAAAAAAB4PAAAAAAAADA8AAAAAAAA sDsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA= ##END= odin-1.8.5/coils/Makefile.am0000644000175000017500000000021011455553545012551 00000000000000EXTRA_DIST = radialInhomogen.coi Array8Channel.coi if ONLY_LIBS else coildir = $(datadir)/odin/coils coil_DATA = $(EXTRA_DIST) endif odin-1.8.5/coils/Makefile.in0000644000175000017500000002670111734622602012566 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = coils DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(coildir)" DATA = $(coil_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = radialInhomogen.coi Array8Channel.coi @ONLY_LIBS_FALSE@coildir = $(datadir)/odin/coils @ONLY_LIBS_FALSE@coil_DATA = $(EXTRA_DIST) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu coils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu coils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-coilDATA: $(coil_DATA) @$(NORMAL_INSTALL) test -z "$(coildir)" || $(MKDIR_P) "$(DESTDIR)$(coildir)" @list='$(coil_DATA)'; test -n "$(coildir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(coildir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(coildir)" || exit $$?; \ done uninstall-coilDATA: @$(NORMAL_UNINSTALL) @list='$(coil_DATA)'; test -n "$(coildir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(coildir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(coildir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(coildir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-coilDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-coilDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-coilDATA install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-coilDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/coils/Array8Channel.coi0000644000175000017500000126440111322062355013652 00000000000000##TITLE=Coil Sensitivity ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 200.0 200.0 200.0 ##$SensitivityMap=( 8, 1, 64, 64 ) Encoding:base64,littleEndian,complex nbS/vTY5Kr1XY8O9N7kvvR4nx70kcDW9RgDLvWtgO70G7869dYxBvaPz0r3P9ke9Zw7XvSui Tr1wP9u9Q5FVvdiG3739xly91uTjvVxGZL1aWei9ahJsvWrk7L1dLnS94YXxvYydfL2nPfa9 s7GCvXEL+726QYe93u7/vbIAjL3BcwK+ePCQvWD6BL78Epa96IoHvjZqm73pJAq+L/igvdfH DL72vqa9DXMPvp3ArL3OJRK+Q/+yvTDfFL4Lfbm9K54XvhM8wL2UYRq+cj7Hvf4nHb48hs69 5+8fvoYV1r13tyK+Ku7dvZh8Jb4IEua99TwovsqC7r3d9Sq+50H3vT6kLb5NKAC+kUQwvuTX BL7p0jK+9q8Jvr1KNb6HsA6+6qY3vkHZE76M4Tm+cCkZvvTzO77nnx6+Z9Y9vto6JL5HgD++ x/cpvnrnQL5A0y++igBCvrHINb43vkK+EdI7vkoRQ76M50G+SOhCvgv/R77gLkK+ggtOvrbN QL41/FO+0Kk+vpe7Wb7zozu+2C1fvmeYN74YL2S+a14yvtOQaL4syCu+nBZsvnKjI77GcW6+ V7sZvu47b75W3A2+M/BtvnO4/73u42m+WVDfvRxAYr7Ct7q91f9VvibIkr1b+0O+LaZSvewM K75n2wK9Ql4KviFze7x0xMO9DSqEu/RfS73ZucO9KyUovUaUx73+pS298YXLvdBeM71Aj8+9 EVI5vZOw071ggj+9VOrXvWnyRb3WPNy99qRMvXio4L34nFO9ii3lvX/dWr04zOm9qGlivduE 7r3PRGq9gFfzvVlycr1pRPi94fV6vW9L/b2L6YG9WjYBvuWGhr0D1AO++1SLvZZ+Br7dVZC9 8TUJvq6Llb3T+Qu+mPiave/JDr7enqC95KURvsyApr0/jRS+xaCsvWx/F74rAbO9r3savnqk ub1EgR2+L43AvSePIL7Lvce9O6QjvtE4z70rvya+xQDXvXbeKb4mGN+9QwAtvlqB572PIjC+ wD7wvfVCM76JUvm9y142vmNfAb7pcjm+okIGvrZ7PL7IUwu+HHU/vmuTEL5xWkK+4wEWvi8m Rb49nxu+OdJHvh5rIb5UV0q+xWQnvkutTL7Iii2+l8pOvv3aM74dpFC+TVI6vi0tUr597EC+ sFZTvrGjR75fD1S+LnBOvsZCVL6mR1W+49hTvoccXL5wtVK+7NxivhO3UL47cWm+SLZNvj26 b76JhEm+dY51vufqQ75htnq+hKk8vmnnfr4/dzO+YN6AvlIDKL7NVoG+gvoZvjWAgL5aEwm+ SLt7vuNO6r2FlHG+3sK8veLrYL51Dou9nOFHvvVgMb0/sCS+w3SuvKvk7L0Scbq7jAR5vS+6 x70V1iW9usDLvexUK72p4M+9owwxvZsa1L3C/za9Hm/YvRIxPb2Z3ty9UKNDvZlp4b1yWUq9 qBDmvYNWUb1E1Oq9wp1Yvcu0772GMmC9prL0vUkYaL1Gzvm9tlJwveoH/72T5Xi98i8CvnDq gL026wS+VpKFvdS1B76lbIq9x48KvpB7j70deQ2+asGUvbtxEL6VQJq9fXkTvof7n70ykBa+ 0vSlvZC1Gb4LL6y9P+kcvvKssr3FKiC+SnG5vYN5I77rfsC9ytQmvrTYx725Oyq+oIHPvUmt Lb6rfNe9OygxvsbM370jqzS+AHXovUw0OL5XePG9wsE7vrLZ+r07UT++9k0Cvv7fQr7hYAe+ D2tGvuCmDL7H7km+GSESvgtnTb6N0Be+G89Qvga2Hb5pIVS+CNIjvoRXV76+JCq+AGpavumt ML4lUF2+tGw3vtX/X76SXz6+PW1ivg2ERb5FimS+fdZMvotGZr6uUVS+fo5nvmPuW763Smi+ u6JjvldfaL40YWu+japnvpYXc76xA2a+CK16vv84Y77R/4C+0w1fvlxwhL4bOFm+yIeHvntd Ub6pGIq+KBFHvprii75i0zm+bomMvrIWKb5miIu+EVIUvsAgiL4ZYPa9d0WBvjLou73OHWu+ Z8F4vZ2rRr7Kbv28aWwSvrsIC7yNzJy9wrPLvTJLI72u5s+9JcUovUk11L2peC69P6DYvXFo NL1FKN29S5c6vQTO4b0gCEG9JpLmvQG+R71Qdeu9KLxOvTV48L3lBVa9ZJv1vb6eXb1+3/q9 X4plvZIiAL6wzG29ceYCvqhpdr2WuwW+cmV/vUKiCL4+YoS9spoLvqNFib0LpQ6+VF+OvXHB Eb62sZO9A/AUvnc/mb3HMBi+LgufvcWDG76rF6W94egevshnq737XyK+if6xvdfoJb743ri9 JIMpvkMMwL1sLi2+q4nHvSLqML6KWs+9kbU0vkyC173Zjzi+cwTgvfB3PL6E5Oi9iGxAvh0m 8r0ibES+z8z7vet0SL4h7gK+0oRMvv8rCL5OmVC+xaENvnqvVL4jURO+98NYvrU7Gb640ly+ +2IfvijXYL5EyCW+w8tkvq1sLL5Hqmi+C1Ezvh5rbL7NdTq+iwVwvuraQb4zb3O+qH9Jvrmb dr6RYlG+eHx5vvqAWb7M/3u+1dZhvpoQfr4YXmq+6ZR/vh4Oc76hNoC+pNp7vkY5gL4tWYK+ GnR/vnC+hr6zNH2+zQuLvqZmeb5sKI++baZzvjPwkr4TdGu+uC2WvigrYL51kJi+J/tQvpuc mb7V5Ty+gpCYvn7VIr6FOpS+dvYBvkm+ir5jarW9PsZyvqtgQ729xTm+wlVgvJ9Lzb2vpM+9 04MgvSIE1L3S9SW9ioHYvfyhK73RHd29E4sxvcLZ4b3vsze9IbbmvaQfPr3Fs+u9VtFEvY3T 8L1ZzEu9Uxb2vSgUU73gfPu9cqxavQiEAL4NmWK9TFwDvgPear2zRwa+hn9zvZRGCb7ygXy9 VlkMvv/0gr1YgA++NN6HveW7Er4h/4y9UQwWvmVakr3ncRm+vvKXveTsHL4Ry529eX0gvlTm o73OIyS+nkeqvQDgJ74t8rC9E7Irvlfpt70Cmi++mjC/vaSXM76Ky8a9yKo3vtq9zr360ju+ ZAvXvd0PQL4YuN+9wmBEvvzH6L3cxEi+OD/yvSo7Tb4CIvy9hcJRvlQ6A75AWVa+v50Ivr/9 Wr5wPQ6+ta1fvpcbFL6zZmS+XToavqklab7gmyC+7eZtvitCJ75jpnK+Ny8uvvxed77JZDW+ wQp8vnjkPL5mUYC+mK9EvlWPgr4Rx0y+NLqEvl0rVb4AzIa+PNxdvoS9iL6U2Ga+6IWKvgce cL5YGoy+oKh5vmRtjb4FuYG+NG6Ovmi4hr5uB4++WMuLvoIdj75Q55C+eYyOvpz8lb6PJI2+ hPOavjqlir5qp5++w7WGvnLeo76D2oC+BjqnvtLLcL7yGam+s85Yvh1kqL7iTze+6Rajvo/w Cb4kg5W+QbCivVO/cr6LsMu8Oj4OvgGL071yfx299xbYvXfmIr1Xw9y9BogovQyR4b3yZi69 AoHmvTCGNL02lOu94eg6vbDL8L1DkkG9dSj2vcuFSL2Jq/u9IsdPve2qAL4BWle9VJQDvnBC X71rkga+k4Rnvb6lCb7QJHC9084Mvswneb0yDhC+K0mBvVxkE767NIa9zdEWvj5Zi70EVxq+ dbmQvX30Hb5LWJa9qqohvsQ4nL35eSW+D16ivcxiKb6Ay6i9gGUtvoOEr71lgjG+roy2vbu5 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 1r41gjq/fWfPvrCdXr+gsqO+kZHivR0JD73qzee9DiQUvUY07b0neRm9CsbyvW8LH73uhPi9 +t0kvY5y/r0s9Cq9UEgCvohRMb1+cAW+ufk3vbSyCL6p8D696Q8MvoQ6Rr0qiQ++m9tNvW0f E76N2FW9ydMWvig2Xr1hpxq+lvlmvVObHr4tKHC9z7AivpXHeb0P6Sa+7u6BvVxFK76ZOIe9 BMcvviHEjL1dbzS+CpWSvdY/Ob7rrpi93Dk+vqkVn732XkO+Qs2lvaawSL712ay9lTBOvjJA tL1o4FO+kAS8vcfBWb71K8S9kNZfvmK7zL2PIGa+IrjVvbGhbL6qJ9+9B1xzvqEP6b2MUXq+ BXbzvUbCgL7UYP69rnuEvi/rBL4vVoi+ke4KviFTjL7XPRG+5XOQvmLcF74OupS+oc0evjsn mb4GFSa+TL2dvga2Lb5OfqK+DbQ1vpdsp753Ej6+z4qsvoXURr4h3LG+Pf1Pvh9kt75xj1m+ LCe9vnWNY76EKsO+Jfltvpp0yb6J03i+bQ3Qvk0Ogr4T/9a+aOmHvmNW3r45+Y2+ICTmvlE6 lL5jfu6+7KaavsaC976wNaG+Dq0Av5/Xp763Hga/dXSuvmg/DL8k5LS+rUsTvyXiur5gnxu/ 2vO/vmPJJb+oMMO+SKkyv4DAwr40iEO/5KC6vm6nWb/4zqG+hsByv6TLTb5GJOa9NdMKvZ6L 673w0g+9Sh/xvTUMFb3+4Pa9EIIavYTS/L2oNyC90noBvlAwJr0npgS+jW8svT/sB74X+TK9 Ik4LvvjQOb3lzA6+NvtAvalpEr5FfEi9iyUWvsdYUL3PARq+oJVYvbD/Hb7xN2G9giAivi1F ar2eZSa+HMNzvXHQKr65t329bWIvvr8UhL0lHTS+hI+JvTECOb62T4+9LhM+vgFZlb3lUUO+ XK+bvRPASL7RVqK9rF9OvrFTqb2NMlS+baqwvdM6Wr7FX7i9knpgvo94wL0P9Ga+7fnIvaqp bb466dG9uJ10vvRL273w0nu+xCflvQSmgb6mgu+99oWFvpli+r3Ziom+8OYCvly2jb5o5Qi+ PwqSvuwvD76IiJa+u8kVvkozm74Vthy+6Aygvib4I777F6W+FZMrvnxXqr7QiTO+vM6vvh/f O76YgbW+ZpVEvnt0u76srk2+nqzBvlEsV741MMi+2Q5hvqUGz760VWu++zjWvrb+db5H0t2+ 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 E727vx2+xZsZvQckIr684x+9sbMmvqN8Jr2/cCu+7GotvVpdML6DszS9y3s1vmRbPL1wzjq+ 4GdEvdZXQL6/3ky9ohpGvtLFVb2bGUy+XSNfvbtXUr7i/Wi9M9hYvjpcc70wnl++iUV+vUWt Zr6f4IS9Iwluvnbrir2ftXW+X0eRvdS2fb5c+Je9nwiDvqkCn72zZIe+hGqmvRnyi74yNK69 bbOQvv9jtr1vq5W+F/6+vRPdmr6SBsi9d0ugvkGB0b30+aW+jnHbvRjsq76J2uW9riWyvnG+ 8L3Qqri+rx78vdt/v77E/QO+g6nGvuQpCr7ZLM6+HJIQvk8P1r6uMxe+z1bevkkKHr6sCee+ sQ8lvsAu8L5UOyy+as35vpSBM77A9gG/HtM6vrhLB7/6G0K+/ekMv2tCSb4X1hK/hyVQvokU Gb+Lm1a+hKkfv+ZvXL6XmCa/uWBhvgTkLb9XHGW+xIs1v2k+Z74mjD2/c01nvtfbRb9xuWS+ GmlOv53cXr5sFle/5ABVvqm2X7+EbEa+ewlov0l5Mr7yuW+/LrgYvhBhdr+cPvK9N497vwJw qL0E3X6/Luksve4z/L29G868PVYBvvro1byMsAS+bRXevEkqCL5cpua8zsQLvlGh77yzgQ++ TQz5vHpiE77NdgG93mgXvtylBr2alhu+5BYMvZLtH76ezRG9pW8kvvzNF738Him+HBwevbH9 Lb50vCS9Gw4zvqGzK72TUji+fwYzvbbNPb5Jujq9KYJDvnnUQr3Nckm+rFpLvY6iT77vUlS9 qhRWvn7DXb11zFy+9LJnvWfNY74eKHK9SRtrvhIqfb3/uXK+HmCEvbmter4GeYq9cn2Bvqrj kL0S04W++KOXvS1air7kvZ69aBWPvmk1pr2EB5S+dA6uvWozmb7BTLa9PZyevuvzvr1ARaS+ MgfIvfgxqr5jidG9H2awvrp8272V5ba+reLlvZy0vb6Mu/C9pNfEvmwG/L1tU8y+WeADvvcs 1L7J8gm+qGncvtM2EL4jD+W+DacWvmkj7r4DPB2+yKz3vrTrI77l2AC/8agqvqYcBr+vYjG+ EKULvxUDOL6JdRG/kW4+vkqRF7+BgkS+F/sdv80TSr76tCS/Ru1Ovru/K7/uzVK+MhozvzZn Vb5PwDq/ZVtWvq6pQr/9PFW++cdKv0GPUb64BFO/aMlKvv4+W7/hXUC+EEljvwnHMb4V52q/ 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 aL43YWs+kapnvpoXcz6sA2a+CK16Pv44Y77S/4A+2A1fvl5whD4cOFm+y4eHPnxdUb6nGIo+ IxFHvpjiiz5g0zm+b4mMPq8WKb5miIs+EVIUvr8giD4UYPa9ekWBPhbou73RHWs+QsF4vaSr Rj58bv28a2wSPhQIC7ySzJw907nDvSQlKD1ElMe99aUtPe6Fy73JXjM9PY/PvQ9SOT2OsNO9 WoI/PVHq171p8kU91zzcvfmkTD14qOC9+JxTPYAt5b163Vo9PszpvahpYj3XhO69xERqPYVX 871ecnI9ZET4vev1ej1tS/29hemBPVo2Ab7khoY9AtQDvvpUiz2Yfga+5VWQPe81Cb6yi5U9 0vkLvpn4mj3uyQ6+356gPemlEb7QgKY9QI0UvsWgrD1qfxe+LwGzPbF7Gr6ApLk9RIEdvjSN wD0mjyC+zL3HPTykI77OOM89L78mvscA1z1y3im+IRjfPUEALb5cgec9jiIwvsE+8D34QjO+ iVL5PcxeNr5kXwE+43I5vqNCBj67ezy+x1MLPiB1P75skxA+alpCvuUBFj4xJkW+OZ8bPjbS R74iayE+WFdKvsRkJz5KrUy+y4otPpXKTr7+2jM+HqRQvlBSOj4jLVK+fuxAPrBWU76yo0c+ Yg9UvjFwTj7CQlS+rEdVPuDYU76THFw+cLVSvuncYj4Qt1C+P3FpPky2Tb5Aum8+g4RJvnGO dT7k6kO+WbZ6PoOpPL5q534+PnczvmTegD5QAyi+zlaBPn36Gb40gIA+WRMJvku7ez7WTuq9 g5RxPtfCvL3k62A+aw6LvaDhRz7cYDG9RbAkPpl0rry25Ow9T3C6u5MEeT3EmIq9x5iKvXC5 i73/Eo69cs+MvYWfkb3b2Y29Pz6VvaPXjr357pi9xcePvXGxnL0uqZC9XoWgvcN6kb1caqS9 SzuSvfZfqL2p6ZK9r2WsvZaEk73perC90QqUvfWetL0Ve5S9ENG4vQXUlL1bEL29VxSVvd5b wb2dOpW9i7LFvXhFlb0vE8q9fDOVvYh8zr1CA5W9Je3SvWSzlL2CY9e9b0KUvfvd273rrpO9 v1rgvYT3kr3i1+S90BqSvVtT6b12F5G98srtvRHsj71LPPK9bJeOveqk9r1JGI29LwL7vX5t i71GUf+995WJvabHAb6wkIe9j9wDvstchb3F5QW+d/mCvZThB74OZoC9O84JvjtEe73oqQu+ aFp1vbhyDb5NDm+9uiYPvhBgaL3pwxC+209hvUBIEr7V3lm9obETvisOUr31/RS+yd9JvRQr Fr79VUG91jYXvt9zOL0ZHxi+5zwvvbXhGL5itSW9lnwZvhfiG72o7Rm+mMgRvfAyGr4rbwe9 ikoavq25+bynMhq+BzLkvJ7pGb52WM68620ZvgE/uLxCvhi+9vihvHfZF777mou8sb4Wvth1 arw/bRW+5t49vNTkE76LoBG8WCUSvjTWy7sZLxC+QMJru6wCDr6VFYe6D6ELvqxowDqdCwm+ n7N+OwxEBr6cmss7ckwDvvYSjr1wuYu9MEyPvS9Mj70He5C9hfKSvYaekb1NrJa9obWSvW15 mr0/v5O9qlmevUi6lL28TKK9i6WVvVBSpr3Wf5a992mqvfBHl708k669g/yXvYbNsr04nJi9 Lhi3vcUlmb12cru9tpeZvYLbv72o8Jm9YVLEvRkvmr0D1si9m1GavTdlzb2eVpq9uv7Rva08 mr0Zoda9OgKavdBK273BpZm9KvrfvaUlmb1UreS9cYCYvV5i6b2ttJe9IhfuvcbAlr1hyfK9 VKOVvbV2973oWpS9exz8vSTmkr3/WwC+vkORvTCjAr6Dco+9Q+IEvjZxjb2aFwe+6j6LvYVB Cb6k2oi9Q14Lvo5Dhr3yaw2+EHmDvadoD76keoC9ZVIRvgOQer0XJxO+98FzvZ7kFL5yi2y9 yYgWvvnsZL1dERi+yedcvRF8Gb6AfVS9lMYavmawS72V7hu+cINCvb3xHL4J+ji9ss0dvnQY L70wgB6+neMkvesGH745YRq9sF8fvpyXD71liB++EI4EvQR/H77+mPK8q0Efvoy327ykzh6+ 34rEvGUkHr53J628l0EdvkijlbwvJRy+Myx8vFjOGr7TL028mTwZvquFHrzDbxe+UsPguwpo Fb4y9YW7+yUTvls1tLqOqhC+eBemOib3Db4ksno7iw0LvtMAzjv87we+hp+RvXPPjL2E8pK9 BXuQvXw7lL18O5S9b3mVvcEQmL0/q5a9vfqbvcvPl71C+Z+99OWYvRcMpL2M7Jm97DKovTni mr1ibay9s8WbvQe7sL2jlZy9URu1vbhQnb2ajbm9YfWdvS4Rvr04gp69OqXCvbH1nr3LSMe9 VE6fvdj6y71zip+9MLrQvYqon72RhdW96aafvYlb2r39g5+9iTrfvSM+n73gIOS9lNOevbkM 6b3XQp69BfztvSGKnb2p7PK93qecvUfc9717mpu9asj8vWlgmr0x1wC+JPiYva1FA74sYJe9 KK4FviqXlb0MDwi+4puTvalmCr4AbZG9N7MMvoAJj73b8g6+b3CMvaMjEb7yoIm9hkMTvmSa hr1lUBW+W1yDvQ5IF74IzX+9QigZvr5xeL2o7hq+HqdwvdeYHL4qbmi9YSQevlTIX73Hjh++ rbdWvYLVIL75Pk29DPYhvrZhQ73Z7SK++SM5vWW6I769ii69LFkkvsSbI73FxyS+tl0YvcoD Jb7f1wy9BAslvrYSAb1P2yS+vC7qvLhyJL7a39G8ds8jvrBOubz/7yK+uZKgvAjTIb7pxIe8 lncgvtr/Xbz+3B6+sb4svPECHb6o//e7fukavqL8l7sqkRi+967nuub6Fb6d5YY6EygTvmX3 dDuUGhC+pOXPO8XUDL4/PpW91tmNvU6slr2FnpG9xBCYvWx5lb2Iapm9iGqZvYm4mr3OcZ29 jPmbvRyPob15LJ29QsKlve1Pnr0BC6q9s2KfvQJprr1iY6C92duyvYtQob0NY7e9viiivfr9 u72A6qK9/KvAvTGUo709bMW9USSkvdU9yr0vmaS9xR/PvRfxpL3bENS9biqlvdAP2b1rQ6W9 OxvevU06pb2RMeO9Sw2lvQ1R6L2ouqS90nftvZJApL3go/K9WJ2jvffS970Nz6K9wQL9vRXU ob1TGAG+r6qgvfesA74pUZ+91T0Gvu/Fnb1ayQi+cgecveRNC74qFJq9q8kNvs7ql73bOhC+ HIqVvYKfEr7b8JK9jPUUvigekL3dOhe+IBGNvTNtGb4dyYm9P4obvrhFhr2Xjx2+woaCvb56 H76MGH29JkkhvvqsdL0t+CK+RsxrvSCFJL40eGK9Te0lvlWzWL3wLSe+4IBOvUZEKL4g5UO9 ii0pvuvkOL0B5ym++YUtvfNtKr4bzyG9yb8qvvTHFb312Sq+OXkJvRu6Kr7q2Pm89F0qvnhY 4LyCwym+ZojGvPHoKL6+gay8vcwnvjNfkryqbSa++3pwvN3KJL6ydDy82OMivp3qCLyRuCC+ pTmsu2xJHr7lNBG7R5cbvgAYRDqXoxi+IDZtO0FwFb43K9E7xP8RvvnumL2j1469b3mavZ21 kr26+pu9OquWvc9xnb2FuJq9ft2evXzdnr2WPKC9CRqjvdiNob0Rbqe9+s+ivVTZq72VAaS9 k1uwvUMhpb1s9LS9jy2mvWyjub3oJKe9AGi+vbYFqL2FQcO9cc6ovTMvyL1Lfam9LzDNvaQQ qr1vQ9K9o4aqvddn172L3aq9I5zcvW0Tq73f3uG9hSarvYUu573iFKu9V4nsvZrcqr1s7fG9 xXuqvbpY971t8Km9+sj8vbM4qb3jHQG+qFKovT/XA75vPKe9Jo8Gvjj0pb0XRAm+KXikvXb0 C76TxqK9iZ4OvszdoL1/QBG+S7yevWrYE76IYJy9PmQWvlPJmb3V4Ri+X/WWvfROG76v45O9 O6kdvnSTkL0y7h++EgSNvVQbIr4jNYm98y0kvoEmhb1TIya+V9iAvaj4J74rlni9Eqspvj3/ br2VNyu+Be5kvUSbLL61ZVq9ENMtvlpqT7382y6+sABEvQKzL76oLji9KFUwvt/6K72GvzC+ X20fvUfvML4KjxK9wOEwvtZpBb1flDC+0xHwvNEEML7t8NS8ADEvvquLubwVFy6+9P6dvJa1 LL4/aYK8bwsrvvrVTbzmFym+ekwXvMLaJr6F+MK7UFQkvoW4MrtdhSG+/6vaOU5vHr5MEmM7 HBQbvhWu0Ttpdhe+crGcvcfHj72sWZ69PL+TvT35n73Qz5e9HY+hvZD5m70NGqO9lDygvdKY pL3QmKS9LQqmvTYOqb2ubKe9nJytvQK/qL3GQ7K9pv+pvWEDt70ELau9CNu7vZZFrL08ysC9 rketvVfQxb2PMa69qezKvXUBr71WHtC9lbWvvWNk1b0QTLC9s73avfXCsL0LKeC9UBixvQWl 5b0tSrG9CzDrvX5Wsb1lyPC9OjuxvSls9r1C9rC9RRn8vZyFsL245gC+KeevvRXDA77TGK+9 aqAGvoEYrr09fQm+TeSsvQZYDL4xequ9HC8Pvi7Yqb20ABK+hPynvejKFL5k5aW9uosXvi2R o70HQRq+SP6gvZLoHL5jK569/H8fvjcXm73LBCK+xsCXvWN0JL4uJ5S9FcwmvuVJkL0KCSm+ hCiMvV8oK74Ow4e9CyctvtYZg733AS++11p8vfy1ML65/XG93T8yvjcfZ71XnDO+FcNbvRrI NL4I7k+92781vtWlQ71WgDa+ZvE2vUkGN76L2Cm9k043vpVkHL0jVje+7J8OvSYaN74XlgC9 5Jc2vhSo5LzxzDW+ys/HvCe3NL7iwaq8v1QzvmOfjbxPpDG+2RZhvOWkL77fVSe8F1YtviqR 3Lv6tyq++vpYu0vLJ76Dx+03YJEkvuwcVjtDDCG+rULRO6w+Hb5XhaC9MamQvbpMor1FupS9 GAykvfvlmL1BwqW9eSydvQlup73XjaG9NA6pvSkKpr1goaq9ZKGqvTEmrL10U6+9H5utvSsg tL21/q69RQe5vUNPsL1sCL69M4uxvSojw73BsLK97lbIvRq+s70Po829c7G0vb4G073WiLW9 BYHYvUpCtr3XEN69z9u2vf60471OU7e9E2zpvaymt72HNO+9tdO3vaoM9b1Q2Le9h/L6vSuy t70FcgC+E1+3vXJvA77X3La9S3AGvhgptr0wcwm+wEG1vad2DL6IJLS9GnkPvj3Psr3QeBK+ 0z+xvfZzFb4mdK+9kWgYvk1qrb2QVBu+TyCrvbw1Hr6PlKi9uQkhvkfFpb0LziO+FbGivR+A Jr6vVp+9LR0pvgm1m71ioiu+T8uXvcAMLr7xmJO9KVkwvqwdj71ohDK+lVmKvS6LNL4PTYW9 E2o2vhTyf72THTi+nL10vS2iOb70/2i9SvQ6vvi9XL08EDy+G/1PvXXyPL5KxEK9X5c9vnYb Nb11+z2+EgwnvU8bPr7LoBi9ovM9vtTlCb1ugT2+HdH1vNfBPL4gcNe8WLI7vinJuLzOUDq+ pf+ZvHibOL5Mc3a8GpE2vr89Obz6MDS+pmf5uwZ7Mb6VWIK7z28uvhwM4LmYECu+DdVFO25f J77uts87Il8jvlRqpL3AepG9VFKmvYqllb3oMqi9h+yZvQILqr3zT569T9mrvfbPor2YnK29 smynvW9Tr70sJqy9b/ywvWn8sL3+lbK9RO+1vYYetL2T/rq9dpS1vQEqwL0J9ra9NXHFvWRB uL2o08q9sHS5vbtQ0L3wjbq9tOfVvSuLu72ll9u9TWq8vYxf4b05Kb29Oj7nvaHFvb1SMu29 ZD2+vUk6870wjr69blT5vZG1vr3Vfv+9SbG+vbPbAr7mfr695/0Fvgocvr2/JAm+Loa9vdlO DL71ury9s3oPvvi3u72tphK+y3q6vQLRFb4dAbm9zvcYvqBIt70QGRy+NU+1vZcyH76bErO9 G0IivueQsL0kRSW+LMitvSE5KL7Mtqq9Txsrvh5bp73X6C2+5rOjvaueML4EwJ+9qTkzvq5+ m71/tjW+X++WvcUROL7wEZK970c6vpLmjL1RVTy+7G2HvS82Pr4DqYG9qeY/vv4yd73XYkG+ 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 /a0FvXLofr6Djdm8bTt8vhV2p7xl6Hi+VuFqvFvrdL5AwAe84UFwvid/Gbtm62q+53ZhO3Pp ZL6BssW9mTqVvQjWyL0dL5q90/rLvU9On73KH8+9LZmkvW9D0r2iEKq9XGTVvZS1r70Egdi9 1oi1vaOX270wi7u9Z6bevVe9wb1jq+G95h/IvXek5L1es869ZI/nvS541b3baeq9mm7cvUsx 7b3RluO9GePvvcjw6r1ffPK9WnzyvUP69L05Ofq9oln3vWoTAb5Gl/m9NiIFvsqv+72CSAm+ rp/9vbOFDb42Y/+9CNkRvll7AL6fQRa+EisBvnC+Gr66vgG+Qk4fvk40Ar677yO+qIkCvkmh KL6VvAK+L2EtvuLKAr57LTK+UrICvgcEN76ScAK+bOI7vmMDAr4SxkC+Z2gBviOsRb5gnQC+ fJFKvu8//73Ack++1Nv8vUpMVL7rCfq9KBpZvt3F9r0t2F2+aQvzvb+BYr5m1u69DBJnvh0j 6r3ig2u+3u3kvbTRb75hM9+9pfVzvtDw2L1y6Xe+tiPSvX+me74qysq91yV/vu7iwr0HMIG+ jW26vbqmgr5darG99PKDvtTap72BEIW+YcGdvfz6hb4dIpO9562GvkcCiL2gJIe+QtJ4vX9a h77Bv2C9zUqHvl7jR73t8Ia+l1guvV1Ihr64PxS94kyFvi5987yU+oO+MgG+vBlOgr7EbYi8 vESAvodfJrwwuXu+L+91u7Ipdr4iQSM7t9tvvi4Tyr1wRZW9PGXNvZpRmr0vutC9c4qfvd4Q 1L0e8aS90mfXvaOGqr23vdq9CkywvdwQ3r1LQra9hF/hvVRqvL33p+S98cTCvRLo573uUsm9 zh3rvfMU0L3XRu69hgvXvbdg8b0jN96982j0vQyY5b28XPe9by7tvTI5+r1B+vS9VPv8vVT7 /L3jn/+9oZgCvrMRAb61zQa+RkECvn0cC767XAO+aYQPvjpiBL7GBBS+u08FvsOcGL4wIwa+ XksdvnPaBr5uDyK+WnMHvp/nJr6e6we+adIrvu9ACL4MzjC+9XAIvqTYNb5CeQi+++86vmdX CL64EUC+5wgIvjM7Rb5Miwe+jmlKvg7cBr6YmU++sfgFvuPHVL6p3gS+wfBZvoqLA74fEF++ 4/wBvqchZL5EMAC+qSBpvs1G/L0cCG6+KKj3vavScr5TgPK9gnp3vmPL7L2G+Xu+x4XmvZUk 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 i705swy+AW2Rvd46EL7V6pe9atgTvkm8nr26ixe+Z+WlvZFUG75Kaq29mTIfvjNPtb1SJSO+ b5i9vScsJ75oSsa9WkYrvoppz70Fcy++UvrYvRSxM740AeO9Qv83vq2C7b0nXDy+FIP4vRbG QL5hAwK+MztFvusICL5wuUm+J1QOvn8+Tr7w5hS+x8dSvgfDG76EUle+9OkivrTbW74YXSq+ BmBgvpYdMr4C3GS+Tiw6vthLab7UiUK+mqttvnk2S74P93G+IjJUvt4pdr5gfF2+ZT96vmkU Z77uMn6+9vhwvtD/gL5fKHu+QdCCvkDQgr4uiIS+Yy+IvhYlhr4WsI2+VKSHvphQk75KA4m+ 7Q6Zvlo/ir7l6J6+5FWLvg7cpL5DRIy+yOWqvuMHjb4/A7G+Fp6Nvmkxt74/BI6+Cm29vrs3 jr65ssO+yTWOvt7+yb6o+42+vU3QvmCGjb5cm9a+3dKMvpDj3L7T3Yu+9SHjvp+jir7lUem+ PiCJvmNu774uT4e+EnL1vlErhb4PV/u+vK6CvmSLAL8QpX+++VQDv1kdeb78Awa/XrNxvn6T CL+OUGm+if0Kv0TaX77mOg2/rjBVvppCD78zLkm+XAkRv1KmO76xgBK/MGUsvsWVE79sLxu+ 2C8Uv7XDB74ILhS/kuEHvnj5gr1CXgu+oNqIvdvyDr6ACY+9gp8SvhqKlb0/ZBa+lGCcvQVB Gr4pkaO9uzUevlsgq70bQiK+nBKzvcFlJr6nbLu9MqAqvi8zxL2/8C6+CWvNvZhWM74VGde9 vdA3vjtC4b0DXjy+Wuvrvf/8QL5JGfe9HaxFvmtoAb6OaUq+T4sHvjYzT76N9w2+ugZUvkKv FL6q4Vi+bLQbvhzBXb7WCCO+66Fivh2uKr7WgGe+maUyvjVabL5u8Dq+Lipxvl+PQ76c7HW+ 5oJMvjKder4Wy1W+YTd/vqhnX74224G+4ldpvq0KhL6RmnO+myeGvhwufr5fL4i+MoiEvmQf ir5lH4q+/fSLviHbj75+rY2+lLmVvkNGj765uJu+o7yQvk3Wob71DZK+yw+ovqo3k76GYq6+ JzeUvovLtL7tCZW+z0e7vmytlb7+08G+IB+WvrZsyL6LXJa+VQ7Pvhpjlr4mtdW+IzCWvlNd 3L7ewJW+0gLjvl0Slb53oem+XSGUvvo08L5N6pK+wrj2vidpkb4BKP2+P5mPvsW+Ab8mdY2+ 29kEv3f2ir4i4ge/nBWIvgzUCr9jyYS+f6sNv7wGgb6PYxC/PIB5vlD2Er8Xym++TVwVv3XC ZL4VjBe/dDdYvld5Gb+960m+qhMbv16UOb7YRBy/odYmvjLuHL88zgm+FGaAvfNrDb6QQ4a9 oyMRvmtwjL2K9RS+4PCSvdXhGL5SyZm9l+gcvkr+oL28CSG+jJSovSZFJb7skLC9lJopvmD4 uL2XCS6+FNDBvbKRMr49Hcu9DDI3vh7l1L3Y6Tu+EC3fvfW3QL50+um9+5pFvpxS9b13kUq+ Y50AvpiZT74Q3Aa+ULFUvtpnDb5J1lm+GUMUvv8FX74WcBu+gT1kvt3wIr62eWm+Uccqvh23 br4I9TK+I/JzvmB7O76cJnm+VVtEvnVQfr6TlU2+jLWBvlsqV77eOIS+hBlhvs+vhr5wYmu+ vBeJvgMEdr4Hbou+Un6AvhSwjb4YJYa+IduPvv/0i75z7JG+cuyRvkvhk76QCZi++baVvj9K nr7Pape+JKykvjD6mL6iLKu+imKavuPIsb5ZoZu+6324vjG0nL59SL++sJidvj8lxr6NTJ6+ thDNvn/Nnr4vB9S+Phmfvv0E276DLZ++SgbivvgHn74uB+m+KKaevrUD8L5ZBZ6+vvf2vp8i nb4u3/2+nvqbvtdaAr9yiZq+YLsFv5LKmL7PDgm/gLiWvpVSDL+cTJS+24MPv9B+kb5knxK/ CUWOvnOhFb/Nkoq+g4UYv3NYhr74RRu/KYKBvqvbHb927Xe+MD0gv88ra77NXSK/PWxcvsgr JL9mQ0u+440lv+qpC74vRHu9qmgPvhJ5g72EQxO+8aCJvds6F74nHpC99U4bvlv1lr38fx++ ZyuevQzOI75JxaW9ITkovjHIrb0PwSy+gjm2vZVlMb6zHr+9QCY2vmZ9yL1mAju+UlvSvT/5 P75Ovty90QlFvjCs573MMkq+zCrzvb5yT77zP/+94MdUvq74Bb5FMFq+TqIMvoqpX76GnxO+ KDFlvtzyGr4nxGq+sJ4ivmJfcL4jpSq+Vv91vhkIM74koHu+Jsk7vtiegL6N6US+zmmDvipq Tr6bLoa+bEtYvsTqiL5OjWK+wJuLvkwvbb7jPo6+XTB4vmzRkL5tx4G+l1CTvlSkh76TuZW+ ga2NvpAJmL5M4ZO+uz2avr49mr5fU5y+n8CgvrNHnr5tZ6e+Jhigvmsvrr40wqG+nBW1vm5D o77SFry+i5mkvq8vw75TwqW+q1zKvsK7pr4mmtG+1oOnvl3k2L6vGKi+izfgvm94qL7Lj+e+ UqGovj7p7r5ukai+CkD2vsxGqL5GkP2+Tr+nvgxrAr96+Ka+zAYGv4vvpb5umQm/HaGkvvIg Db8bCaO+SJsQv3Yiob5CBhS/zOaevoJfF78qTpy+XaQav05Omb680R2/INqVvubjIL+N4JG+ HtYjv0tLjb4+oia/vvyHvt8/Kb9TzYG+MaMrv0wOdb7Uui2/uHINvl9adb1mUhG+rHqAvWNQ Fb5omoa9NW0ZviARjb07qR2+r+OTvcgEIr4/F5u9H4Amvhmxor1SGyu+xLaqvWbWL74ELrO9 LbE0vrQcvL1Pqzm+54jFvV/EPr7CeM+9oftDvpzy2b0oUEm+0/zkveHATr7FnfC9SkxUvtfb /L3A8Fm+qt4EvlesX746pAu+t3xlvpXBEr5JX2u+kTkavi9Rcb7bDiK+GU93vuhDKr58VX2+ 49oyvjCwgb6o1Tu+tbWEvr01Rb4WuYe+LfxOvta3ir6jKVm+ca+Nvji+Y74knZC+h7luvjZ+ k76EGnq+yU+WvtHvgr7sDpm+SwOJvre4m75ERo++Pkqevvq2lb6fwKC+XFOcvgAZo74DGaO+ qFClvkEFqr4BZae+JRWxvolTqb6ERbi+7BmrvuiSv74Htqy+y/nGvuUlrr5eds6+vGevvsoE 1r7lebC+IaHdvvJasb5tR+W+kAmyvrDz7L6IhLK+/qH0vrTKsr5uTvy++dqyvpr6Ab8etLK+ SskFv+hUsr52kQm/xbuxvmNRDb/j5rC+WAcRv/LTr76nsRS/6X+uvq5OGL/45qy+s9wbv/MD q74BWh+/LdCovrDEIr+yQqa+pxomv41Po75ZWSm/quafvpp9LL8S8pu+MYMvvy9Tl74wZDK/ At+RvtgXNb+5Jg++Sw5vvRonE74IkHq9EEgXvlxcg71Aihu+HsmJvTTuH753k5C9YXQkvsbA l70tHSm+tlafvdPoLb4fW6e9f9cyviDUr70q6Te+/8e4vaQdPb5IPcK9kHRCvpo6zL1s7Ue+ ysbWvWGHTb6/6OG9X0FTvnqn7b0jGlm+8wn6vR8QX76OiwO+WCFlvuRqCr6KS2u+T6YRvi2M cb7+QBm+RuB3vvE9Ib6KRH6+9J8pvp9agr6AaTK+MZeFvsWcO77A1Yi+hTtFvugTjL4YR0++ IE+PvknAWb66hJK+ZadkvuCxlb4c/G++m9OYvm29e7745pu+3/SDvuXonr5bP4q+SdahvqK8 kL4irKS+1WqXvm1np761R56+QAWqvq1Qpb7Xgqy+1IKsvovdrr752rO+8xKxvqZVu77XILO+ Je/CvjwFtb6Ho8q+W762vsdu0r68Sri+ukzaviqpub4lOeK+mdi6vtMv6r5n2Lu+hizyvvin vL4eK/q+80a9vsgTAb8/tb2+/w4Fv6/yvb5VBQm/Zf+9vgP1DL9I272+Y9wQvzyGvb7juRS/ DQC9vhKMGL86SLy+llEcv9Jdu74vCSC/Yj+6vrexI7+d6ri+GUonvx1ct75H0Sq/+Y61vjhG Lr8afLO+yKcxv0sZsb629DS/yVeuvmMrOL/OIau+lkk7v+nDEL4GYGi9nuQUvv7Bc709KBm+ Ec1/vZKPHb7DRYa9VhsivhMEjb0VzCa+MSeUvWCiK74OtZu9q54wvuazo71BwTW+MyqsvTwK O76qHrW9qHlAvkeYvr1JD0a+MZ7Ivb/KS77JN9O9ZKtRvols3r0/sFe+CkTqvSzYXb7jxfa9 pCFkvuD8Ab7Simq+lvMIvosRcb6/ShC+IrN3vukFGL65bH6+dSggvnSdgr6HtSi+9AyGvvWv Mb7Egom+QRo7vpX8jL589kS+6XeQvjpGT74X8pO+iwpavkxol77aQ2W+hteavvvxcL6wPJ6+ 5xN9vpqUob7/04S+DtykvuJVi77KD6i++A2SvqIsq742+pi+aS+uvioYoL4kFbG+BGWnvvna s76O3a6+Q362vkR+tr6V/Li+WEO+vtdTu76vKMa+LoK9vvYpzr4Nhr++zELWvmFewb6Rbt6+ QArDvq+o5r5MicS+guzuvlzbxb58Nfe+oQDHvh9//76u+ce+kOIDv1DHyL6rAQi/r2rJvuUa DL8p5cm+cCwQv2w4yr6MNBS/NGbKvqcxGL+XcMq+WCIcv7dZyr5UBSC/DSTKvnDZI7/80cm+ uZ0nv1Vmyb5JUSu/6ePIvmrzLr/6Tci+hYMyv/Gnx74RATa/5/XGvrZrOb+HPMa+IMM8v8WB xb4fB0C/PUgSvutPYb3JiBa+aotsvafuGr64cXi9wHofvseGgr3yLSS+JDWJvQ8JKb7iSZC9 ugwuvk/Ll72uOTO+BsCfvUSQOL7ZLqi94hA+vv0esb20u0O+3Je6vbCQSb4locS9oY9PvtFC z737t1W+4YTavRoJXL6lb+a9v4Fivm0L872mIGm+RjAAvgfkb76rOwe+tcl2vverDr42z32+ H4UWvrx4gr7myh6+lBaGvtuAJ74kv4m+NKowvklwjb7QSTq+nyeRvhFiRL6B4pS+4vROviye mL6BA1q+lVecvpOOZb6SC6C+8JVxvuC2o76+GH6+FVanvpKKhb7F5aq+RUSMvoFirr6qN5O+ 4Mixvo5imr6fFbW+NcKhvoRFuL6HU6m+qFW7vvgSsb5dQ76+l/y4viUMwb4oDMG+D67Dvh49 yb5cJ8a+porRvs52yL7U79m+k5vKvotn4r41lcy+sezqvtljzr4fevO+9QfQvr8K/L6MgtG+ 00wCvxLV0r4GkQa/bAHUvqvPCr/8CdW+kwYPv4zx1b67MxO/XLvWvjVVF79Ha9e+PGkbv4YF 2L4ubh+/KI/YvoZiI7+5Ddm+5EQnv+CH2b7xEyu/PQXavm3OLr8Lj9q+FXMyv2gw276QADa/ bffbvmB1Ob8T9ty+ns88v0tE3r62DEC/5wLgvu4oQ7+gsRO+195ZvVsRGL777GS92ZgcviSn cL0oSSG+jRh9vVMjJr6BJoW9XSgrvocojL0nWTC+85iTvYC2Nb6xfpu9EkE7vgLho71r+UC+ ksesvenfRr5DOra9s/RMvk9BwL2+N1O+OOXKvcmoWb67Lta9L0dgvsom4r0SEme+c9buvRwI br7XRvy9uyd1vohABb7gbny+D8cMvnjtgb5nuxS+g7SFvsYhHb7Piom+JP4lvlxujb4mVC++ 7lyRvhEnOb4FVJW+rnlDvt9Qmb4wTk6+iVCdviKmWb7GT6G+WoJlvjtLpb7O4nG+ZD+pvpnG fr6hKK2+7xWGvkEDsb7hB42+j8u0vis3lL7pfbi+WqGbvtQWvL5yQ6O+75K/vu0Zq74f78K+ 3CCzvqwoxr7WU7u+Gz3JvhKuw75vKsy+cCrMvhjvzr6Mw9S+EYrRvtJz3b7X+tO+hzXmvmFB 1r7nAu++YF7YvhvW977vUtq+wlQAv9Qg3L6+uwS/c8rdvlMdCb++Ut++4HYNv0e94L7sxRG/ TA7ivhgIFr+qSuO+Izsavwt45L7uXB6/+pzlvmBrIr/rwOa+h2Qmv5/s575LRiq/PCrpvq8O Lr8Ghuq+X7sxv4oO7L7KSTW/6dXtvtG2OL/Q8u++af47v4OC8r4TGz+/jKv1vgEFQr8govm+ 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 NL8MjjW/0qw2vwwkM79l6Di/VNgvv6QyGr6qufm8A38fvg6OBL0DCyW+4tcMvfPZKr7+xxW9 Se8wvmFtH72STje+kdgpvXn7Pb57GzW9sflEvuhJQb0tTUy+WHlOvZ35U75iwVy9+AJcvq87 bL35bGS+HwR9vUI7bb5ynIe9THF2vm99kb0lCYC+lTacvX4Qhb7S2qe930+KvlR+tL0HyI++ cjbCvWN5lb6xGdG94GObvnc/4b3OhqG+3r/yvc3gp7682QK+s2+uvloZDb55MLW+vyoYvggf vL5EGSS+SDbDvkfvML4CcMq+sbU+vtLE0b6Kc02+RCzZvl4tXb67nOC+wuRtvt0L6L7Hl3++ Z27vvkIgib69uPa+VOqSvizf/b6iIp2+C2sCv02/p75JyQW/I7SyvlUFCb+68r2+6BoMv7Bq yb6VBg+/AArVvuzFEb9NveC+jFcUv3Rw7L44uxa/5g74vsDxGL8TwgG/Cf0avwleB7/p3xy/ nNEMvw6eHr+dExK/2jsgv1AbF78vviG/leAbv1cqI7/TWyC/zIUkv8+FJL9C1iW/xVcovzQh J78Ryyu/D2wovxPZLr/Uuym/JXsxvzAVK78pqjO/HHwsv5peNb/M8y2/MJA2v3R+L7/NNTe/ +Bwxv0VFN7+JzjK/XLM2v1WQNL+8czW/0lw2vzt5M79DKzi/EbYwvwbvOb+vHC2/mukZvhAy 5LyuQR++DJnyvE/bJL65EgG9FroqvjV5Cb3D4TC+Bo8SvSVWN76SZBy9Txs+vhEMJ71dNUW+ aZkyvYioTL54Ij+9L3lUvkO/TL2Zq1y+KYpbvTVEZb76n2u9HUduvh0gfb2TuHe+WBaIvTHO gL53dZK9AfuFvm7Bnb01ZIu+vQ+qvQMLkb5qd7e9LfCWvtUQxr3rE52+pfXVvdl1o75/QOe9 2xSqvsUM+r3s7rC+BjsHvv4AuL7aSxK+/ka/vgFGHr51u8a+qzUrvrlXzr6cJTm+wRPWvn4e SL4J5t2+YiZYvvjD5b74P2m+jqHtvvdpe74QcvW+NE+Hvv4n/b4raZG+1loCv576m77PBga/ fPimvneRCb/oVLK+A/UMv2r/vb5uLBC/NOXJvrozE7+J8dW+GggWv08O4r7+pxi/cyTuviwT G7+mHPq+ukodv+jvAr/lUB+/wqsIvwcpIb86Nw6/Utciv0eIE7/IYCS/rZUYv8bKJb/nVh2/ KBsnvynEIb/FVyi/RNYlv4uGKb+Lhim/Ga0qv6nOLL/O0Cu/eKgvv2j2LL/JDTK/KSIuv0z4 M79rVy+/P2E1v5WYML9+QTa/5uYxvzCRNr8lQjO/yUc2v1uoNL8fXDW/dhU2v2vEM7/9gje/ mXYxv2/nOL+zaC6/FTY6v5SRKr/vbRm+e1jOvKvOHr6St9u8t3Ikvscu6rz0XSq+8Nj5vF+U ML7SaQW9Ixo3vvGfDr2j8z2+16AYvWklRb6dgCO9HrRMvlhVL72NpFS+cDc8vZX7XL6yQUq9 Lb5lvrmRWb0r8W6+/UdqvXuZeL4JiHy9yF2BvlU8iL3nrYa+FSKTvfw+jL4qDJ+9oRKSvjQT rL0IKpi+jVG6vdCFnr4948m9+SWlvqbl2r2vCay+PnftvS0vs76W2wC+g5O6vlPiC76RMsK+ D98Xvq4Gyr4v4CS+pwjSvp/yMr7HL9q+LyFCvopx4r7Mc1K+4sHqvq/uY75QE/O+g5F2vglX +75UK4W+yL4Bv0CZj75iuwW/dImavm2ZCb+M76W+Y1ENv8i7sb5n3BC/R9u9voo0FL9uOMq+ M1UXv2G71r4kOxq/pkrjvq7kHL/3y+++qVEfv8ck/L5/gyG/ih0Ev/d8I78C+wm/BkIlvxif D7+r1ya/Ef8Uv4hDKL8jERq/y4spv5jMHr/atiq/nSkjvxHLK784ISe/q84svx6tKr+Axy2/ gcctv9u6Lr/gajC/ZK0vv++RMr/oojC/RDc0v02eMb9IVTW/SqEyvxfmNb9KrDO/YOM1v02+ NL9xRjW/fNQ1v0AINL8M6ja/jiEyv+r3N79Biy+/hfQ4v9I+LL+T0zm/4zYov0K+GL4RP7i8 ZCQevtuKxLx2zyO+7N/RvIfDKb5/WOC81AQwvuIR8Lzflza+F5YAvXSBPb7U5Qm9XMZEvgMM FL3Ya0y+9B4fvSp3VL4SNyu9tu1cvptvOL0Y1WW+weZGveYyb77VvVa9mQx5vokZaL3Vs4G+ XSJ7vaEkh75HAoi9DtuMvk94k7032ZK+hg2gvb8gmb5Y3q29z7KfvjQJvb3aj6a+Ya7NvXa3 rb7H79+9LCi1vnXw871Y37y+/ukEvtLYxL7S3hC+zQ7Nvq7nHb6vedW+JBQsvvUP3r6pcTu+ EcbmvosKTL5iju++FeVdvq9Z+L5gAnG+Y4sAv8Cugr7c2QS/KHWNvs8OCb+Wypi+9CANvyOh pL5XBxG/5+awvuO5FL9Bhr2+qzEYvzRmyr45aRu/RGvXvu5cHr8PeOS+8Aohv1pu8b5YcyO/ DjD+vgOYJb/rTwW/dHwnvxZRC79+JSm/zg4Rvw2ZKr+YfRa/tN0rv1STG7+H+iy/O0cgv6P2 Lb+kkSS/Fdkuvw9sKL91qC+/ytArv+JqML/Zui6/syUxv7YlMb9v3TG/Dw0zv52VMr+4bDS/ p1Azv3BANb/DDzS/zIM1v87SNL8oMjW/CZg1v7dGNL8mXDa/m7wyv+kZN7/8jjC/HMo3v325 Lb9kYzi/lDgqv0LaOL8UCia/edkXvgL5obyaQR2+cietvPrvIr7ATrm88+govleIxrz7MC++ 8PDUvPPMNb4PqOS828E8vizR9bz/FES+6UkEvQrMS771jQ69v+xTvl3NGb0cfVy+diMmvVOD Zb7RrjO9wQVvvmeRQr2jCnm+6/BSvS3Mgb4o92S9fVqHvlTSeL0vM42+q1qHveBYk74EbJO9 0c2Zvo+7oL22k6C+UWqvvaKrp76am7+9rBWvvvd00b3W0La+vB3lvdbavr5zvvq9tS/HvvQ/ Cb6Cyc++BEUWvmSg2L42gSS+CKrhvjMFNL642eq+aN5EvlQg9L7SFVe+OGz9vqmuar79VAO/ GaV/viDiB79+9oq+lVIMv4C4lr5LmxC/HQmjvqexFL/x06++EowYvxUAvb5XIhy/mXDKvi1u H7+OBdi+Ymsiv/qc5b4iGCW/ExTzvtJ0J789JAC/EYQpv6CMBr9ZSiu/8bMMv6PNLL9mjBK/ ExUuv+sJGL9yKC+/KSIdv+oPML9qzCG/ktMwv5oBJr8gezG/27spv8oNMr9o9iy/8pEyv2St L78ODTO/bd0xv5GDM7+VgzO/yvgzvwSdNL/EbjS/Byc1v0vmNL/IHjW/s141v2yBNL/j1TW/ EUwzvyJINr/gezG/ELA2v1IOL7+PBje/cgEsv7lCN785VCi/Blo3vyAHJL+uvha+DZuLvC4l HL5co5W8CNMhvs2SoLy+zCe+xoGsvBgXLr65i7m8Krc0vr/Px7xcsju+KHDXvGEOQ76ik+i8 P9FKvr5l+7xDAVO+iQsIvQ+lW74ubxO9ecNkvm78H717Y26+ldUtvWSMeL4fIT29r6KBvucJ Tr3PSoe+vL9gvQhCjb7Zd3W9o4uTvnY2hr2AKpq+7O+SvQ0hob7OC6G9CXGovn2wsL1BG7C+ fwfCvVYfuL7FPNW9fHvAvk5+6r0ULMm+m/0Avkkr0r458Q2+AnHbvpswHL5Y8uS+aNArvkWh 7r774Ty+7mz4vu1xT76vIAG/ZIZjvvwDBr9iHXm+DdQKv6AViL7egw+/oUyUvkQGFL94IqG+ qE4Yv+1/rr6PURy/Pki8vlMFIL+/Wcq+hWIjvyiP2L6DZCa/7cDmvn0JKb/QxvS+c1Irv708 Ab8OQy2/79kHvxfhLr8gKg6/ETQwv34eFL+1RDG/bqoZv0wcMr+ewx6/XsQyv8ZhI78aRjO/ kn4nvyWqM781FSu/SvgzvykiLr9ENzS/66Iwv7VsNL+glTK/B500v8v4M79EyzS/QMs0vzT5 NL/sCzW/Qic1v6a5NL9lVDW/a9MzvyV+Nb8kWDK/qKA1v/VGML9/tjW/ZJ8tv8+4Nb+NYSq/ QZ81v5+OJr9SYDW/DSkiv0FtFb7gdWq8XM4avgwsfLyadyC+4MSHvKttJr4yX5K8nbUsvvz+ nbzAVDO+58GqvM9QOr4rybi84K9BvoE6yLxceEm+PkDZvByxUb4eCuy8SGFavhVnAL1jkGO+ vuQLvUdGbb5OoBi994p3vp/AJr1gM4G+SnE2vevwhr5j40e9RgKNvgtOW71Xa5O+o+5wvdgv mr7fhIS98lKhvpT1kb1B16i+JfOgvW2+sL7xqrG96Qi5vvNNxL2ctcG+FBDZvYPByr6QJ/C9 IyfUvsDlBL443t2+FRkTvlnb575HxyK+dA/yvqEGNL62Z/y+gehGvsxmA78cd1u+e5MIv2Sz cb5+qw2/Z8mEvmWfEr/SfpG+hl8Xv9Lmnr6x3Bu/+easvisJIL/ZXbu+ddkjvw0kyr7hRCe/ wQ3Zvk5GKr+e7Oe+H9wsv9OR9r5KCC+/H2gCv9nPML/4Pgm/ajoyv/K6D7+eUTO/NcwVvw0g NL/eZRu/+LA0v9h9IL+BDzW/tAwlvyxGNb87DSm/mV41vx98LL9CYTW/a1cvv0pVNb9QnjG/ bEA1v6dQM78FJzW/x240v+0LNb86+TS/lfA0v5XwNL8X1TS/kVU0vxO4NL/NKDO/1JY0vwVr Mb9ZbTS/Jx0vv0k2NL+JQCy/GuszvxPXKL8UhDO/qeMkv4/4Mr9caiC/1OQTvvHePbycPBm+ vS9NvP3cHr7L/1284MokvuN6cLxuCyu+QGmCvE6kMb5gn428fps4vrP/mbxY9z++La6nvNO+ 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 D75CCpK+LJ8Mvlmyl75PjAm+NkSdvgP5Bb7duKK+RugBvoQJqL4ivPq9zC+tvm2+8L2rJbK+ qOLlvZbltr49Ndq9dGq7vpfDzb2xr7++4JvAvTaxw76bzLK9dWvHvp1kpL1C28q+3nKVvfr9 zb4jBoa9VdHQvn1abL1qU9O+1uxLvaGC1b7n3yq9vl3Xvk9PCb2/49i+ZqzOvNET2r5cHoq8 bO3avuNRCrwicNu+JKX3Mq2b277+UQo8JXDbvm4eijxr7dq+eazOPNQT2r5nTwk9vePYvuTf Kj3CXde+5exLPaGC1b5tWmw9ZlPTvjEGhj1U0dC+3nKVPf39zb6nZKQ9QtvKvpvMsj1za8e+ 55vAPTexw76kw809ra+/vkQ12j1xaru+reLlPZXltr51vvA9ryWyvim8+j3NL62+S+gBPoUJ qL4A+QU+2riivkmMCT43RJ2+NZ8MPliyl77tLw8+PwqSvtc9ET4eU4y+mMkSPiyUhr4b1RM+ ndSAvoZjFD7lNna+MnkUPsjear6XGxQ+ta1fviNREz56r1S+GSESPsbuSb5rkxA+G3U/vkXZ E77qpje+5gEWvmxaQr6H0Be+EWdNvrc7Gb7zw1i+XjoavrlmZL4/xBq+kkNwviTSGr5wTXy+ z10avhs7hL5qYhm+b1eKvmPcF77qc5C+vskVvoiIlr7WKRO+RY2cvpH9D742eqK+JUcMvptH qL4PCgi+E+6tvuxKA76hZrO+sB78vdGquL6Nu/C9mrS9vm965L2qfsK+l2rXvTkEx76Pm8m9 AEHLvoodu71dMc++uACsvTHS0r49VZy9yiDWvggrjL3+Gtm+SSN3vQG/276zMFW9Vwvevrmb Mr3a/t++CIEPvZ6Y4b7O+Ne899fivh9SkLxmvOO+H4YQvJ1F5L7GumcybXPkvk6GEDydReS+ NVKQPGu8477Z+Nc89dfivhSBDz2emOG+zpsyPd7+377EMFU9WgvevlMjdz0Ev9u+BSuMPQEb 2b48VZw9yCDWvrcArD0w0tK+jx27PV8xz76Pm8k9AkHLvpZq1z03BMe+e3rkPa1+wr6Mu/A9 nLS9vrMe/D3Qqri+6koDPqVms74MCgg+Eu6tviRHDD6XR6i+lP0PPjJ6or7ZKRM+Ro2cvrzJ FT6IiJa+YtwXPuRzkL5nYhk+cVeKvtFdGj4dO4S+JNIaPmtNfL5GxBo+j0Nwvl46Gj6zZmS+ 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 ynkFv/ig/jxN8gS/9FApPYk0BL/U7lI9Y0ADv/kNfD3PFQK/DEiSPcC0AL8lKqY9qTr+vnmb uT1tn/q+zYjMPZSY9r5b3d49USfyvhCD8D14Te2+S7EAPocN6L7hsQg+1WrivtY2ED6oady+ rzMXPk8P1r5AnB0+OmLPvtpkIz75aci+4oIoPkIvwb4M7Sw+6ru5vtabMD7JGrK+0YkzPnlX qr4OtDU+TX6ivjoaNz7hm5q+1L43Pvq8kr4Wpzc+Ge6KvvPaNj4wO4O+yWQ1Pvxed74NUTM+ RapovuqtMD79aVq+x4otPkqtTL460y++fOdAvv7aM76Xyk6+uGw3vi1QXb7KdTq+Imtsvnzk PL7KCny+Tqg+vqcNhr7Tsj++1kKOvjL4P75EmJa+TG8/vkcAn755Ej6+mGynvhvfO76+zq++ H9Y4vmEYuL5y+zS+tjvAvvZVML62K8i+3e4qvnjcz75t0SS+R0PXvkkKHr7OVt6+CacWviMP 5b7ftQ6+uGXrvgZFBr5IVfG+0cT6vcfZ9r4RN+i9MfD7vlP61L0+SwC/OibBvallAr/X0Ky9 /UYEvygOmL0e7wW/T/CCvRdeB7/gD1u9DpQIv7fHL703kQm/XCMEvdJVCr/ud7C8FOIKvx+j MLwsNgu/iosoMyRSC79MozA8KjYLvx94sDwX4gq/fSMEPdNVCr+7xy89N5EJv9wPWz0NlAi/ WvCCPRZeB78pDpg9Hu8Fv+HQrD0ARwS/RybBPallAr9b+tQ9PUsAvxs36D018Pu+28T6PcXZ 9r4HRQY+R1Xxvua1Dj66Zeu+D6cWPiEP5b5KCh4+zlbevnHRJD5GQ9e+4u4qPnTcz77zVTA+ uCvIvnP7ND60O8C+GtY4PmEYuL4f3zs+u86vvnsSPj6UbKe+WG8/PkMAn74x+D8+RJiWvtey Pz7TQo6+Sag+PqQNhr545Dw+wAp8vs51Oj4da2y+tGw3PiJQXb792jM+lcpOvrXINb6GAEK+ UFI6viCkUL6TXz6+3f9fvuvaQb6PBXC+n69EvmhRgL5/yka+oOCIvuAaSL5so5G+35JIvkaL mr42KEi+jIijvobURr7Viqy+Y5VEvpaBtb5ybEG+gFy+vglfPb7vC8e+yHU4vlmBz74vvDK+ kK/XvsA/LL75it++rg8lvq4J574GPB2+byPuvhzVFL6e0fS+Q+sLvkAP+744jgK+TWwAv8eZ 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 ob5Yz5++sqe2vrMyor7WJ8y+2qqivlr04b6wNaG+x4L3vnzznb7UKQa/Ox+Zvpz/D7+XA5O+ Sx4Zv9/vi74IcSG/HS+Evr7wKL8aBXi+zaAvv2o+Z77AizW/aVtWvlHAOr/rlkW+/k4/v+4Y Nb6oSEO/mPokvmK9Rr9eSRW+/7tJv1wKBr63UUy/MnnuvRiKTr9htdG9Lm9Qv724tb1iCVK/ wW6avd1fU7/AgH+9fnhUvwAqS736V1W/L6YXvRkCVr8pgsm8qnlWv9sXSbyfwFa/VfkEMyHY Vr85GEk8osBWv0OCyTyreVa/RKYXPR4CVr8ZKks9+ldVv9KAfz15eFS/xW6aPd5fU7/DuLU9 YglSv3C10T0tb1C/QXnuPRuKTr9nCgY+tFFMv2FJFT7/u0m/mPokPmG9Rr/4GDU+pUhDv+6W RT79Tj+/aVtWPk/AOr9tPmc+xIs1vyEFeD7LoC+/IC+EPrjwKL/k74s+B3Ehv5sDkz5IHhm/ Ox+ZPp7/D799850+0SkGv7E1oT7Fgve+1qqiPlX04b6uMqI+0CfMvlfPnz6rp7a+p6abPgn5 ob6b/JU+eIyOvmsojz6jZnm+yIeHPhc4Wb5o534+hKk8vus7b75Yuxm+Zt6AvkJ3M76oGIq+ gF1Rvjbwkr5vpnO+ffOavpUkjb7tpaG+5HGiviqQpr5dV7m+a1SpvkRC0b6qwKm+pYDpvp7X p74RrQC/R82jvr0UDL9n+Z2+87cWvyTFlr5+biC/D5qOvmYmKb9n1oW+Zd8wv1SOeb6OpTe/ dU1nviiMPb/3PFW+rqlCv5qTQ74fFUe/CHIyvmDkSr+96CG+UitOv7z8Eb6N+1C/DqsCvihk U78N1+e9FXJVvzRly70tMFe/leWvvXmnWL/HOpW9cd9Zv+iMdr0d3lq/stNDvV2oW78vDBK9 8EFcv9jywby0rVy/A3tBvJjtXL9TzxQzvQJdvz17QTyZ7Vy/+/LBPLatXL9GDBI98EFcv7vT Qz1cqFu/C412PSDeWr/SOpU9cd9Zv53lrz17p1i/RWXLPS0wV78Y1+c9FXJVvxerAj4pZFO/ xPwRPor7UL/G6CE+VStOvwxyMj5d5Eq/opNDPh0VR78DPVU+ralCv3hNZz4mjD2/YY55Po6l N79t1oU+Z98wvxWajj5hJim/JsWWPn1uIL9n+Z0+7bcWv0PNoz67FAy/n9enPgytAL+uwKk+ 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 i2BDvWu/cr47sKK9UlSivul7FL6J8tO+JAKRvhts7L6eYQO/d2fPvjyCOr/zzqG+dadZv0qu er4B32i/E99GvrSxcL/R3iG+Zhd1v82XBr5XxXe/CJTjvYaDeb/l28K9IrV6v/9vqL06j3u/ w5uSvRowfL84NoC97ql8v53eYL0fCH2/OWJFvUdSfb8nGi29aY19v09fF735vH2/67ADvYvj fb9+U+O87gJ+vw3xwbxqHH6/+rWivPkwfr90M4W8aUF+v7UWUrwwTn6/NtcbvMdXfr+xLM67 X15+v4M3TbtMYn6/Vg7uMq1jfr+eOE07TGJ+vyktzjtmXn6/edcbPL1Xfr/qFlI8LE5+v5Az hTxnQX6/E7aiPPowfr8z8cE8Zxx+v5dT4zzqAn6//rADPZLjfb9hXxc9+bx9vzoaLT1jjX2/ UWJFPUlSfb+u3mA9JQh9v0M2gD3oqXy/zpuSPRcwfL8JcKg9OY97v+zbwj0dtXq/GpTjPYOD eb/TlwY+VsV3v+HeIT5lF3W/J99GPrGxcL9arno+AN9ovwDPoT5qp1m/hWfPPi+COr8VbOw+ i2EDv3ry0z4JApG+PlSiPtl7FL5Hv3I+PLCivbfFOT6QYEO9ZmwSPsRu/bym5Ow9wXSuvPZf S704KYS7mAR5vRRwuruSzJy9AAgLvK1Lzb0oVWC8Qz4Ovjewy7x59la+mlBfveCmtr6ZJyW+ hKH9vqHUDr+SsqO+tJ1ev5jLTb6LwHK/cVsQvtcVeb9FEtq9X7p7v8jErL2TEH2/9laNvR/V fb+Ffmy9clB+v1cNSb0Bo36/HuksvQTdfr/k8BW9Vgd/v7XBAr0WJ3+/XdXkvHk/f7/yhMi8 mlJ/v7mcr7zPYX+/FGaZvPptf7/iVYW803d/v4z/ZbzWf3+/PhtEvFaGf7/pciS8k4t/v6uS Bry/j3+/nzDUu/ySf79tXZ27aZV/v4UoULsal3+/VizPuhWYf7//dccyc5h/v9UtzzoZmH+/ YSlQOxiXf7/OXZ07Z5V/vwsx1Dv9kn+/5pIGPLuPf78ecyQ8lIt/v24bRDxWhn+/wf9lPNd/ f7/7VYU81Hd/vzFmmTz+bX+/2ZyvPMVhf78Thcg8mVJ/v3vV5Dx9P3+/w8ECPREnf7/18BU9 Sgd/vzrpLD0B3X6/aQ1JPQWjfr+dfmw9d1B+vwRXjT0f1X2/18SsPY4Qfb9TEto9ZLp7v4Fb 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 dD0vojk+FfJ/PZUdOD4UTYU9E2o2PpZZij0tizQ+rB2PPWmEMj7xmJM9KVkwPlTLlz3ADC4+ CrWbPWKiKz6zVp89LR0pPhixoj0fgCY+SMWlPQvOIz6QlKg9uAkhPlEgqz29NR4+TWqtPZFU Gz4odK89kmgYPtM/sT32cxU+Qc+yPdF4Ej6LJLQ9GXkPPsBBtT2ndgw+GCm2PTBzCT7Y3LY9 SnAGPhRftz1ybwM+KbK3PQVyAD5Q2Lc9hfL6PbjTtz2pDPU9qqa3PYU07z1RU7c9E2zpPdDb tj39tOM9TUK2PdcQ3j3UiLU9BIHYPXaxtD29BtM9GL6zPQ2jzT3BsLI97lbIPTKLsT0qI8M9 R0+wPWwIvj25/q49RAe5PSObrT0rILQ9NiasPXNTrz1koao9Y6GqPTYOqT0oCqY9DG6nPdeN oT1CwqU9eCydPRcMpD365Zg9ukyiPUW6lD0udxm8AywZPq9C0butPh0+Ch1Wu0UMIT6K0e23 YJEkPjn7WDtLyyc+WZHcO/y3Kj7cVSc8GFYtPtIWYTznpC8+Xp+NPE6kMT7pwao8wFQzPtvP xzwotzQ+FajkPPDMNT4blgA95Zc2PvSfDj0mGjc+mWQcPSNWNz6L2Ck9k043PmjxNj1KBjc+ 3KVDPVeANj4J7k893b81PhvDWz0ayDQ+Oh9nPVecMz66/XE93T8yPtxafD3/tTA+2hmDPfkB Lz4Tw4c9CyctPocojD1fKCs+5kmQPQoJKT4vJ5Q9FcwmPsfAlz1kdCQ+PBebPckEIj5lK549 /H8fPkz+oD2S6Bw+L5GjPQdBGj5n5aU9u4sXPoj8pz3oyhQ+L9ipPbQAEj4zeqs9HC8PPlHk rD0GWAw+gxiuPTx9CT7SGK89aqAGPinnrz0VwwM+noWwPbjmAD5C9rA9Qxn8PTo7sT0pbPY9 flaxPWTI8D0uSrE9CzDrPVAYsT0EpeU99cKwPQsp4D0QTLA9tr3aPZa1rz1jZNU9dQGvPVQe 0D2MMa49puzKPa5HrT1X0MU9lkWsPT3KwD0ELas9Ctu7PaX/qT1iA7c9Ar+oPcVDsj2rbKc9 nJytPS0Kpj02Dqk90ZikPdCYpD0QGqM9lDygPR2PoT2Q+Zs9PfmfPdDPlz2sWZ49O7+TPX3G FrxlmRM+863Ru2h2Fz56EmO7HBQbPjOt2rlObx4+XbgyO1yFIT6x+MI7UlQkPoNMFzzG2iY+ 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 ARvZPlEjd70Ev9s+vTBVvVwL3j7EmzK93v7fPhGBD72fmOE+2PjXvPTX4j4oUpC8a7zjPkCG ELydReQ+aYUlsW1z5D46hhA8nUXkPipSkDxnvOM+4fjXPPfX4j4NgQ89npjhPrubMj3a/t8+ uzBVPVUL3j5NI3c9Ab/bPgkrjD39Gtk+QVWcPcog1j66AKw9MNLSPowduz1dMc8+lJvJPf9A yz6datc9OQTHPnJ65D2ofsI+jbvwPZq0vT6wHvw90Kq4PuxKAz6hZrM+DwoIPhLurT4pRww+ mkeoPpH9Dz41eqI+1ikTPkWNnD6+yRU+h4iWPmPcFz7pc5A+amIZPm5Xij7TXRo+GzuEPiXS Gj5uTXw+P8QaPo9DcD5eOho+uGZkPrc7GT7yw1g+htAXPhFnTT7lARY+alpCPoewDr69SjU+ a5MQvhx1Pz4ZIRK+x+5JPiNRE756r1Q+lxsUvrWtXz4xeRS+yN5qPoVjFL7lNnY+G9UTvp7U gD6YyRK+LpSGPtc9Eb4hU4w+7C8Pvj8Kkj4znwy+WLKXPkmMCb44RJ0+//gFvty4oj5L6AG+ iAmoPia8+r3NL60+cb7wva4lsj6t4uW9leW2PkE12r1xars+oMPNva+vvz7nm8C9OLHDPpnM sr10a8c+pGSkvUPbyj7dcpW9/f3NPi4Ghr1V0dA+ZVpsvWZT0z7b7Eu9o4LVPuDfKr3CXdc+ XE8Jvb3j2D5TrM681BPaPlQeirxr7do++1EKvCVw2z7dpf4wrZvbPvFRCjwicNs+Yh6KPGzt 2j56rM480RPaPldPCT2/49g+798qPb9d1z7c7Es9o4LVPn1abD1qU9M+JAaGPVXR0D7ecpU9 +v3NPqBkpD1A28o+m8yyPXVrxz7jm8A9NrHDPpvDzT2vr78+PTXaPXRquz6r4uU9luW2Pm++ 8D2qJbI+Irz6PcwvrT5I6AE+hAmoPgP5BT7cuKI+UIwJPjZEnT4tnww+V7KXPu0vDz5CCpI+ 1z0RPiJTjD6ayRI+MJSGPhzVEz6e1IA+g2MUPuM2dj4xeRQ+0N5qPpwbFD68rV8+IlETPoKv VD4aIRI+x+5JPmyTED4gdT8+9q8JvunSMj7IUwu+tns8PuCmDL4Pa0Y+xaENvk6ZUD5wPQ6+ v/1aPnZzDr6PjmU+Ij4OvhhBcD6gmA2+vwl7Pg5/DL407oI+ke4Kvi9WiD5o5Qi+XLaNPuhi Br4kCJM+hGcDvhNFmD5z6f+9w2adPgUa+L0LZ6I+lmfvvQFApz6J2uW9GOyrPrp8270fZrA+ MVnQvUmptD7le8S9QLG4PpPxt70cerw+ZceqvV4AwD79Cp29+UDDPiXKjr00OcY+rBKAvc7m yD605GG90kfLPs/tQr2fWs0+nlsjvdUdzz7RSAO9YpDQPkifxbx0sdE+HxSEvFaA0j7BRgS8 pvzSPggSLzIhJtM+y0YEPKr80j4SFIQ8VoDSPjufxTxvsdE+2EgDPWKQ0D6nWyM91h3PPsrt Qj2eWs0+s+RhPdNHyz63EoA9z+bIPhvKjj02OcY+9QqdPfdAwz5lx6o9XgDAPo7xtz0Zerw+ 4nvEPT6xuD42WdA9SKm0PsB82z0dZrA+jNrlPRTsqz6UZ+89AECnPgQa+D0LZ6I+a+n/PcRm nT6EZwM+EUWYPuliBj4pCJM+ZeUIPlm2jT6Q7go+MFaIPgx/DD427oI+npgNPsEJez4hPg4+ FEFwPnpzDj6QjmU+cj0OPrv9Wj7FoQ0+TZlQPt+mDD4Ra0Y+x1MLPrt7PD7k1wS+kUQwPqJC Br7pcjk+4WAHvv7fQj7/Kwi+0oRMPr+dCL5AWVY+brAIvnNUYD79Xgi+kWxqPiClB743l3Q+ Y38GvknJfj4v6wS+rnuEPvDmAr7Ziok+9nEAvjmMjj4zGfu94nmTPh5w9L0FTpg++uzsvfYC nT6qleS9VpOhPo5x2730+aU+Y4nRvfgxqj7s5sa97zauPuGUu720BLI+z56vvYuXtT6zEKO9 FOy4PgP3lb1Z/7s+gF6IvbHOvj4SqHS92lfBPj/JV73ZmMM+Pzo6vQOQxT67FBy99TvHPunk +ryUm8g+Ntm8vOutyT5RcXy8XXLKPknU/Ltr6Mo+ofaGsdEPyz5i1Pw7bejKPkVxfDxecso+ Qdm8POytyT775Po8kJvIProUHD3yO8c+Ojo6PQWQxT4+yVc91JjDPhyodD3cV8E+fl6IPbTO vj7/9pU9WP+7Pq0Qoz0T7Lg+y56vPYeXtT7flLs9sASyPvHmxj3uNq4+Y4nRPfoxqj6Tcds9 9PmlPrGV5D1Xk6E++OzsPfsCnT4VcPQ9BE6YPiYZ+z3geZM+9HEAPjiMjj7w5gI+2IqJPjbr BD6ue4Q+X38GPkjJfj4bpQc+MJd0Pv1eCD6RbGo+bbAIPnBUYD7AnQg+RVlWPv0rCD7RhEw+ 32AHPgTgQj6jQgY+43I5Pk0oAL4+pC0+Y18BvsteNj72TQK+O1E/PiHuAr7rdEg+VDoDvoXC UT6ALQO+uDFbPifDAr64uWQ+cvcBvuxQbj5NxwC+We13PtRg/r1GwoA+mWL6vfaFhT6mkvW9 TTyKPnzx7730344+JYHpvZRrkz5gReK9/dmXPjZD2r00Jpw+QYHRvXdLoD4xB8i9QEWkPs7d vb1lD6g+wg6zvfSlqz55pKe9awWvPuSpm72RKrI+gSqPvYEStT4aMoK9p7q3Pj+Zab3EILo+ mQxOvedCvD581jG9ZR++PnUPFb3UtL8+vJ/vvBACwT7sX7S8JwbCPugfcbxuwMI+8X/xu2Qw wz6DRFWyyFXDPup/8TtkMMM+7x9xPGzAwj4DYLQ8KAbCPqmf7zwMAsE+cw8VPdO0vz5+1jE9 Yx++Po8MTj3nQrw+SJlpPcUguj4YMoI9p7q3Pnsqjz2CErU+3ambPZgqsj50pKc9bwWvPscO sz30pas+xd29PWIPqD41B8g9QEWkPkCB0T13S6A+MUPaPTQmnD5bReI9/dmXPiqB6T2Ra5M+ fvHvPfPfjj6wkvU9UTyKPpti+j31hYU+1mD+PUrCgD5SxwA+XO13Pnb3AT7xUG4+KMMCPrW5 ZD6DLQM+tjFbPlI6Az59wlE+Hu4CPup0SD73TQI+N1E/PmRfAT7MXjY+50H3vdz1Kj6JUvm9 9UIzPrLZ+r3CwTs+z8z7vSJsRD4CIvy9KjtNPkHQ+71tJ1Y+i8/6vbQoXz4LGfm9UDZoPjyn 9r0WR3E+BXbzvYxRej6mgu+9BKaBPvfL6r1YFoY+WFLlvdJ0ij6CF9+9oLyOPrAe2L356JI+ dmzQvUP1lj6SBsi9E92aPuvzvr09nJ4+YTy1vdQuoj606Kq9LJGlPk8CoL3tv6g+VZOUvfu3 qz5Bpoi9m3auPvuLeL1O+bA+aftevdw9sz6YsUS9ZkK1Po/FKb03Bbc+XU4OvfiEuD6axuS8 esC5PgM3rLzMtro+4jhmvENnuz59lea7VdG7Pt1aTLK59Ls+UJXmO1LRuz7nOGY8RGe7Pgk3 rDzQtro+qMbkPHfAuT5bTg49+oS4Pp7FKT02Bbc+lLFEPWdCtT5s+1493z2zPveLeD1K+bA+ PqaIPZt2rj5Tk5Q9/rerPl0CoD3ov6g+s+iqPSuRpT5lPLU90y6iPuvzvj0+nJ4+kgbIPRHd mj5tbNA9QPWWPrQe2D326JI+fxffPaC8jj5OUuU903SKPu7L6j1YFoY+pILvPQamgT4EdvM9 kVF6PkKn9j0ZR3E+Ehn5PU82aD6Qz/o9tyhfPkXQ+z1xJ1Y+AyL8PTM7TT7YzPs9IWxEPsDZ +j3FwTs+iVL5PfhCMz7Kgu699TwoPsA+8L2PIjA+V3jxvUo0OD4eJvK9iGxAPjg/8r3cxEg+ nrvxvWg2UT4plPC9n7lZPsPC7r2ZRmI+gkLsve/Uaj6hD+m9B1xzPsQn5b3w0ns+1ongvWIY gj4CNtu9PTaGPuYt1b2VPoo+VHTOvQctjj5cDce9VP2RPhf+vr1vq5U+wUy2vWozmT52AK29 oJGcPiIho72gwp8+ZbeYvTvDoj6AzI29j5ClPhxqgr3iJ6g+wjRtveeGqj51z1S9c6usPpS5 O72pk64+vggives9sD7l0ge946ixPiBc2rxb07I+n2CkvHC8sz7Ev1u8cmO0PuAY3LvWx7Q+ EY75sVHptD7mGNw718e0PsO/WzxwY7Q+nmCkPHO8sz4AXNo8WtOyPurSBz3fqLE+yAgiPe89 sD6PuTs9qJOuPmfPVD1uq6w+yDRtPeaGqj4jaoI94ieoPoDMjT2LkKU+XreYPTzDoj4jIaM9 pcKfPnQArT2hkZw+wUy2PWwzmT4i/r49bauVPmcNxz1W/ZE+WXTOPQUtjj7mLdU9kD6KPvQ1 2z09NoY+zongPWIYgj7GJ+U99dJ7PqUP6T0DXHM+g0LsPfPUaj7Lwu49lUZiPimU8D2euVk+ nLvxPWc2UT40P/I94sRIPh0m8j2HbEA+WnjxPU40OD7BPvA9jiIwPggS5r2YfCU+WoHnvUMA LT4Adei9I6s0PoTk6L3wdzw+/MfovcJgRD42GOi9O19MPsrO5r1wbFQ+UebkvQWBXD5iWuK9 bJVkPqon372xoWw+9kvbvbiddD5Ixta9QIF8Pt2W0b0GIoI+Er/LvfruhT5pQcW9daOJPn8h vr2HO40+/2O2vW2zkD50Dq69hAeUPlsnpb1kNJc+57WbvdM2mj4NwpG91AudPjFUh72jsJ8+ sep4vbgioj7NXWK90V+kPhIVS73gZaY+hCQzvR8zqD6AoBq97MWpPo6dAb34HKs+cGHQvC03 rD7i3Zy8mROtPqi1UbyBsa0+3ArSu3oQrj7ZHKcyLzCuPuUK0jt4EK4+u7VRPIaxrT7x3Zw8 lxOtPnFh0DwuN6w+kZ0BPfwcqz5yoBo98cWpPpYkMz0cM6g+ExVLPeBlpj7YXWI901+kPqvq eD23IqI+LFSHPZ+wnz4GwpE90QudPui1mz3RNpo+WielPWE0lz5wDq49ggeUPvVjtj1qs5A+ fCG+PYc7jT5gQcU9dKOJPgq/yz397oU+3ZbRPQkigj5VxtY9P4F8PvNL2z27nXQ+pyffPbSh bD5gWuI9cJVkPlDm5D0JgVw+0c7mPWZsVD40GOg9NF9MPgDI6D3DYEQ+ieToPe53PD4Ddeg9 Iqs0PlyB5z1BAC0+Ku7dvXe3Ij4mGN+9dt4pPsfM3707KDE+cwTgvdiPOD4YuN+93Q9APjzh 3r1Rokc+N3rdveFATz4mftu91ORWPhzp2L0rh14+IrjVvY8gZj466dG9qqltPpV7zb3JGnU+ T2/IvXlsfD6qxcK9ncuBPvGAvL3ISYU+XqS1vRatiD40NK69GfKLPmk1pr1oFY8++a2dvdYT kj51pJS9ZOqUPhYgi70zlpc+uCiBvb0Umj4yjW29i2OcPv8EWL2AgJ4+5MpBvaBpoD6O8Sq9 Kh2iPhOME72tmaM+AVz3vMndpD4x1sa8b+ilPoeulby+uKY+nhpIvANOpz7Na8i7yKenPrDP 0DG2xac+92vIO8mnpz6gGkg8BU6nPpCulTy9uKY+N9bGPG7opT4bXPc8yN2kPgqMEz2pmaM+ iPEqPSsdoj7nykE9nWmgPvcEWD1+gJ4+OY1tPZBjnD64KIE9vBSaPhUgiz02lpc+daSUPWDq lD79rZ091ROSPms1pj1pFY8+MzSuPRbyiz5dpLU9Fq2IPveAvD3CSYU+rMXCPZvLgT5Qb8g9 hGx8Po97zT3OGnU+POnRPZ6pbT4juNU9kCBmPhPp2D0jh14+IH7bPdTkVj5Aet0930BPPkXh 3j1Pokc+FLjfPdsPQD58BOA93Y84PrnM3z0/KDE+IRjfPXLeKT6GFda95+8fPsUA170rvyY+ q3zXvUmtLT5Mgte9kbU0PmQL17360js+IRLWvQAAQz5xkdS90zZKPvKE0r0mcVE+I+nPvZ+o WD5ju8y9kNZfPu35yL0P9GY+DaTEvTP6bT7aub+9F+J0Pn08ur2rpHs+BS60vZkdgT5qka29 ck+EPoRqpr2zZIc+5L2evS1aij78kJa96SyNPtHpjb0g2o8+Es+EvSRfkj7pj3a9g7mUPla4 Yr375pY+lSdOvYDlmD6l7ji9NLOaPuIeI71lTpw+VsoMva61nT6uBuy8yeeePjy5vbys458+ 5NGOvHOooD7b7T68eTWhPhY7v7tHiqE+ZrEMsommoT4kO787RoqhPtztPjx4NaE+6NGOPG+o oD4vub08qOOfPrYG7DzM554+WcoMPbC1nT7dHiM9Zk6cPqfuOD0xs5o+mydOPX/lmD5guGI9 /OaWPviPdj2EuZQ+Gs+EPSVfkj7W6Y09INqPPvaQlj3tLI0+572ePSpaij58aqY9s2SHPm+R rT13T4Q+Ay60PZYdgT55PLo9q6R7Ptq5vz0Q4nQ+CKTEPTr6bT7l+cg9EfRmPmS7zD2U1l8+ HenPPaioWD75hNI9KXFRPmeR1D3KNko+IxLWPf7/Qj5rC9c999I7PlWC1z2RtTQ+nXzXPUmt LT7HANc9L78mPj6Gzr3+Jx0+0TjPvTukIz6ggc+9uTsqPotaz70i6jA+2r3OvciqNz5hps29 cHg+Po0PzL3STUU+hvXJvTIlTD4eVce9j/hSPvUrxL3HwVk+j3jAvZJ6YD46Ory9jBxnPiBx t706oW0+VB6yvVICdD63Q6y9cjl6Pv3jpb03IIA+qQKfvZ8Igz74o5e9EtOFPtjMj729fIg+ 44KHvQgDiz54mH29fmONPiBfa73Em48+AWhYvb6pkT5AwkS9gouTPpJ9ML07P5U+WaobvWTD lj5yWQa9khaYPlo44byXN5k+TQi1vG8lmj5IRoi8R9+aPistNrx3ZJs+1Xa2u4+0mz7Bx4Ox RM+bPsx2tjuQtJs+Ky02PHdkmz5RRog8Qt+aPkIItTxvJZo+UjjhPJg3mT5rWQY9kRaYPl+q Gz1iw5Y+mn0wPTs/lT4uwkQ9fIuTPgloWD2+qZE+HF9rPcWbjz54mH09emONPuiChz0JA4s+ 1MyPPb58iD70o5c9DtOFPqQCnz2hCIM++eOlPTcggD63Q6w9cjl6PlEesj1TAnQ+I3G3PTyh bT46Orw9iRxnPpd4wD2OemA+9yvEPcvBWT4SVcc9j/hSPoD1yT0zJUw+lA/MPdZNRT5lps09 cXg+PtG9zj27qjc+ilrPPSHqMD6jgc89uzsqPs44zz08pCM+cj7HvZRhGj7Lvce9J48gPrTY x73K1CY+rInHvWwuLT6Ky8a9pJczPqmZxb20Czo+8u/DvaKFQD71ysG9BQBHPtsnv72KdU0+ kAS8vWjgUz7FX7i90jpaPso4tL3qfmA++I+vvb+mZj4oZqq9baxsPiu9pL0jinI+fpeevSo6 eD5c+Je91LZ9PqrjkL1yfYE+9V2JvYYAhD5lbIG9PWKGPk8pcr1CoIg+37lgvWq4ij7Bl069 s6iMPv7QO71Nb44+WXQovYcKkD4nkRS933iRPi03AL0KuZI+XO3WvOPJkz6jwKy8baqUPskJ grzfWZU+MdYtvKrXlT6nG667TCOWPqonHzGJPJY+yhuuO0sjlj411i08pteVPsIJgjzlWZU+ pcCsPHGqlD5r7dY85MmTPio3AD0NuZI+IJEUPeF4kT5gdCg9hgqQPvvQOz1Ob44+y5dOPbOo jD7quWA9ariKPkkpcj1CoIg+ZmyBPT1ihj7zXYk9igCEPqzjkD1wfYE+XPiXPdq2fT6Cl549 KDp4Pie9pD0linI+MWaqPXKsbD7wj689wKZmPtQ4tD3rfmA+wV+4Pc46Wj6XBLw9ZeBTPt4n vz2KdU0++srBPQsARz7778M9l4VAPqeZxT22Czo+hsvGPaSXMz6wicc9aS4tPrnYxz3N1CY+ zL3HPSePID4TPMC9K54XPi+NwL1EgR0+637AvYN5Iz5DDMC9JIMpPpowv70Cmi8+xOe9vbu5 NT4cLry9oN07PoYAur3WAEI+fly3vT0eSD4yQLS9lTBOPm2qsL2NMlQ+tZqsvakeWj5GEai9 e+9fPhUPo72Fn2U+r5WdvWgpaz50p5e92YdwPl9Hkb2ftXU+BnmKvbmtej6mQIO9ZWt/PvRF d70C9YE+nkpnvaMShD7Pmla9jAyGPsxCRb3b4Ic+x08zvdyNiT5uzyC97xGLPj3QDb21a4w+ 1cH0vOuZjT6vIc28cZuOPjLfpLxrb48+gzR4vBIVkD6/5SW8zYuQPpgnprs205A+0VUbMgXr kD6IJ6Y7ONOQPtPlJTzOi5A+NTR4PBEVkD4r36Q8a2+PPqUhzTx2m44+6cH0POqZjT5A0A09 tmuMPnPPID3xEYs+u08zPduNiT7NQkU94OCHPsuaVj2MDIY+qkpnPaIShD7rRXc9AvWBPqRA gz1ma38+AnmKPbytej5jR5E9n7V1PnGnlz3Uh3A+spWdPWopaz4WD6M9h59lPk0RqD17718+ vZqsPaseWj5wqrA9izJUPjNAtD2aME4+gly3PTweSD6DALo90ABCPiQuvD2d3Ts+wOe9Pbq5 NT6fML89AJovPjwMwD0kgyk+5n7APYN5Iz40jcA9RIEdPgt9ub0w3xQ+eqS5va97Gj5Kcbm9 xSogPvjeuL3X6CU+V+m3vROyKz6ujLa9ZYIxPrbFtL1uVTc+qJGyvZ8mPT5H7q+9WPFCPvXZ rL2msEg+sVOpvaxfTj4KW6W9SflTPkTwoL19eFk+TBScvT3YXj6jyJa9gxNkPnYPkb1qJWk+ duuKvSMJbj4eYIS9/7lyPnPier2LM3c+hEZsvYlxez419ly9329/Pj78TL1klYE+KWQ8vWFP gz4lOiu9QuSEPgiLGb2FUoY+YGQHvdyYhz4pqOm8G7aIPtjQw7wxqYk+YGCdvExxij6B6Wy8 qQ2LPldYHry/fYs+ppaeuyrBiz4h0V6xqteLPqmWnjsqwYs+bVgePMF9iz5/6Ww8qg2LPl5g nTxMcYo+0dDDPDOpiT4qqOk8GbaIPlxkBz3amIc+DIsZPYFShj4rOis9PuSEPilkPD1eT4M+ PvxMPWSVgT4/9lw9229/PpNGbD2KcXs+XuJ6PZIzdz4YYIQ9/rlyPn3rij0dCW4+bw+RPWsl aT6tyJY9gBNkPlIUnD042F4+Q/CgPXt4WT4NW6U9R/lTPrNTqT2lX04++9msPamwSD5F7q89 WfFCPqaRsj2iJj0+tcW0PWlVNz63jLY9Y4IxPl3ptz0Tsis++964PdjoJT5Qcbk9xSogPoCk uT2xexo+Q/+yvc4lEj4sAbO9bH8XPvKssr0/6Rw+if6xvftfIj4t8rC9AOAnPoOEr72AZS0+ nrKtvWvsMj78eau9l3A4Pq3YqL2W7T0+Qs2lvfZeQz7RVqK9E8BIPhN1nr1XDE4+Qyiavfc+ Uz5JcZW9blNYPpNRkL35RF0+KsuKvRMPYj6f4IS9Ra1mPhIqfb1JG2s+Lthvvd9Ubz6+02G9 IFZzPvolU70vG3c+r9hDvZmgej7K9jO9/OJ9PpuLI72ob4A+LqMSvWPJgT47SgG9bv2CPlMb 37ywCoQ+Nva6vCfwhD6MQJa8CK2FPkstYrymQIY+ZSoXvHmqhj7XZJe7GuqGPp240rFQ/4Y+ 2mSXOxnqhj5wKhc8eKqGPj4tYjypQIY+iUCWPAqthT4n9ro8KPCEPmMb3zyvCoQ+N0oBPW79 gj4uoxI9YsmBPqKLIz2ob4A+0vYzPfzifT612EM9mqB6PgEmUz03G3c+yNNhPRxWcz4t2G89 4VRvPiYqfT1KG2s+oeCEPUetZj4ry4o9EA9iPptRkD34RF0+UnGVPWtTWD5IKJo9/T5TPhp1 nj1TDE4+1FaiPRLASD48zaU9915DPqjYqD2b7T0++XmrPZZwOD6bsq09b+wyPoyErz1/ZS0+ J/KwPf/fJz6D/rE9/V8iPvassj1C6Rw+LwGzPWp/Fz6dwKy9DXMPPsWgrL0/jRQ+Cy+svZC1 GT7IZ6u94egePp5Hqr3OIyQ+gcuovcxiKT7U8Ka9FqIuPmC1pL293TM+bBeivbsROT6pFZ+9 3Dk+Plyvm73lUUM+UuSXvX5VSD7EtJO9WUBNPqEhj70ZDlI+OSyKvXG6Vj571oS9NUFbPolF fr0wnl8+HihyvWfNYz5hW2W99spnPhPnV70mk2s+rtNJvWwibz6AKju9eXVyPpn1K71AiXU+ nT8cvdlaeD7sEwy9rOd6Pmf89rxGLX0+hRXVvKopfz6RjLK8eW2APpt7j7zGH4E+PvpXvCKr gT4wWBC8CQ+CPo2PkLsYS4I+KOOrMR9fgj6Zj5A7H0uCPh1YEDwGD4I+HvpXPCKrgT6fe488 xx+BPo+Msjx5bYA+kxXVPKIpfz5n/PY8Qy19PuoTDD2g53o+oj8cPdpaeD6c9Ss9QYl1PoYq Oz2AdXI+stNJPWkibz4P51c9JpNrPmRbZT30ymc+GChyPWfNYz6ORX49Mp5fPn3WhD0yQVs+ PSyKPXa6Vj6mIY89GA5SPsu0kz1WQE0+TeSXPX9VSD5br5s94lFDPqsVnz3bOT4+ZheiPbkR OT5htaQ9vt0zPtbwpj0Voi4+gMuoPcpiKT6fR6o90CMkPstnqz3h6B4+Ei+sPZK1GT7FoKw9 QI0UPva+pr3Xxww+zYCmveSlET7S9KW9MpAWPqsXpb3Fgxs+VOajvXl9ID4PXqK9+XklPpR8 oL3DdSo+zz+evTRtLz5Pppu9hlw0PuuumL3UPzk+AVmVvS4TPj50pJG9mNJCPoeRjb0Dekc+ FiGJvXIFTD5rVIS96HBQPrBafr1puFQ+OlxzvTPYWD70sme9dcxcPiBlW72ckWA+6XlOvTMk ZD5h+UC99YBnPiXsMr27pGo+mVskvaiMbT65URW9ETZwPh/ZBb1znnI+tfnrvKbDdD6+kMu8 p6N2Pl6PqrzIPHg+wQ2JvICNeT5WSk68p5R6PobdCbxKUXs+ihGKu8TCez6D+aIxl+h7PqcR ijvBwns+cd0JPElRez5LSk48qJR6Pr0NiTyAjXk+YI+qPMk8eD7KkMs8r6N2PrD56zyow3Q+ I9kFPXSecj67URU9DTZwPpFbJD2rjG0+JuwyPbmkaj5m+UA98IBnPu55Tj01JGQ+HWVbPZ2R YD7ysmc9c8xcPkNccz0w2Fg+tVp+PWq4VD5rVIQ94HBQPhQhiT1zBUw+iZGNPQV6Rz5tpJE9 mNJCPgNZlT0yEz4+666YPdQ/OT5Tpps9glw0PtY/nj02bS8+k3ygPcN1Kj4WXqI99nklPlHm oz12fSA+pxelPcODGz7K9KU9MZAWPtCApj3ppRE+L/igvekkCj7enqC978kOPof7n719eRM+ LgufvccwGD4Ry5295OwcPsQ4nL2qqiE+KFKavdxmJj6DFZi9Eh4rPnWBlb3FzC8+CpWSvV1v ND62T4+9MQI5PmOxi72GgT0+aLqHvaDpQT6ga4O9yjZGPniMfb1GZUo+7ZdzvXFxTj7i/Wi9 u1dSPn7DXb2qFFY+oe5RveikWT4IhkW9KwVdPiaROL1rMmA+JRgrvc0pYz7HIx29h+hlPmC9 Dr0bbGg+0d3/vFCyaj5mheG8/bhsPiiHwrxNfm4+cPmivKYAcD4w84K8oz5xPs4XRbwoN3I+ vbYDvFHpcj6A54O7clRzPt1azLEveHM+jueDO29Ucz6rtgM8SelyPrsXRTwoN3I+LvOCPKg+ cT55+aI8qABwPieHwjxOfm4+aYXhPPy4bD7L3f88TLJqPlq9Dj0bbGg+uSMdPYLoZT4lGCs9 xiljPiSROD1mMmA+DIZFPScFXT6h7lE96KRZPn3DXT2xFFY+4v1oPcBXUj7tl3M9dnFOPnmM fT1GZUo+oWuDPcc2Rj5suoc9oOlBPl+xiz2EgT0+uE+PPS8COT4ElZI9W280Pm+BlT3CzC8+ eRWYPQ4eKz4xUpo92WYmPsM4nD2pqiE+EsudPeLsHD4sC589yjAYPof7nz17eRM+356gPe7J Dj42apu96IoHPpj4mr3T+Qs+lUCavbtxED53P5m9A/AUPr7yl73ncRk+S1iWvX30HT4obpS9 t3QiPtcykr1m7yY+F6WPvUhhKz4hxIy9BMcvPoSPib0lHTQ+MQeGvUhgOD6IK4K944w8PrX6 e72Rn0A+uvtyvdKURD5AXWm9RGlIPl0jX72bGUw+71JUvY6iTz5t8Ui9DAFTPkMFPb0QMlY+ S5UwvbYyWT45qSO9TwBcPkpJFr1UmF4+N34IvW/4YD6zovS8dh5jPsGY17x2CGU+z/K5vKy0 Zj7MxZu8oiFoPnNPerz8TWk+UFw8vLQ4aj5mv/u79OBqPvwbfLsnRms+UjBzsvxnaz79G3w7 KkZrPm6/+zv54Go+R1w8PLg4aj6HT3o8AE5pPtHFmzybIWg+0PK5PKy0Zj6zmNc8cQhlPrqi 9Dx0HmM+On4IPW/4YD5MSRY9V5hePjupIz1UAFw+RJUwPbYyWT5GBT09EDJWPm3xSD0RAVM+ 81JUPZWiTz5eI189mhlMPkhdaT1EaUg+tftyPdCURD63+ns9kp9APowrgj3ojDw+MAeGPUZg OD6Ej4k9KB00PirEjD0Axy8+FaWPPUlhKz7ZMpI9Zu8mPiZulD24dCI+RViWPX30HT7D8pc9 6XEZPnM/mT0D8BQ+m0CaPbhxED6Z+Jo90vkLPvwSlr1g+gQ+rouVvfE1CT5rwZS9HXkNPrax k71xwRE+ZVqSvVEMFj51uZC9BFcaPjXNjr2tnh4+TZSMvVTgIj6lDYq96hgnPpk4h71cRSs+ vxSEvW1iLz4mooC98WwzPlnCeb2qYTc+PqVxvWA9Oz5N72i92vw+PoqjX733nEI+0sVVvaIa Rj6sWku9zXJJPlNnQL2Yokw+r/E0vS+nTz5EACm99H1SPlOaHL1RJFU+gMcPvfOXVz4HkAK9 tdZZPjX56bx43ls+zizOvH6tXT7OzbG8G0JfPhPwlLzummA+Nk9vvLm2YT6xEjS8f5RiPjap 8LtzM2M+BQBxuw+TYz5FdvQx/LJjPgsAcTsOk2M+PKnwO3YzYz6kEjQ8fZRiPihPbzy6tmE+ CvCUPO2aYD7NzbE8G0JfPtUszjx8rV0+J/npPHbeWz4JkAI9rdZZPojHDz31l1c+TZocPVUk VT5OACk9831SPq3xND0xp08+VWdAPZaiTD6hWks9yXJJPtPFVT2iGkY+f6NfPfecQj5M72g9 2/w+Pj2lcT1cPTs+WMJ5PathNz4hooA98mwzPr8UhD1vYi8+mTiHPVtFKz6kDYo97BgnPkyU jD1S4CI+Mc2OPa2eHj5yuZA9BlcaPmBakj1TDBY+vbGTPXDBET5swZQ9HXkNPrKLlT3vNQk+ ePCQvcFzAj7dVZC9ln4GPpB7j73Hjwo+VF+OvQulDj4h/4y95bsSPj5Zi73N0RY+H2yJvRDk Gj6WNoe98+8ePri3hL2S8iI+7u6BvQ/pJj65t329cdAqPmr9dr2wpS4+ka9vvdhlMj7Uz2e9 4g02PmFgX73Zmjk+LGRWvc4JPT6/3ky91ldAPnnUQr0pgkM+NUo4vRmGRj6hRS29/GBJPsnM Ib1jEEw+d+YVveqRTj7LmQm9ZeNQPjjd+bzCAlM+EdrfvB7uVD5NO8W8yKNWPtkSqrw3Ilg+ F3OOvB1oWT4Q3mS8U3RaPrE0LLzkRVs+cCPmuyLcWz6wdGa7dzZcPt4PmrGOVFw+xHRmO3g2 XD5lI+Y7HdxbPsc0LDznRVs+Ed5kPFN0Wj4Pc448HGhZPtMSqjw5Ilg+SjvFPMajVj4L2t88 He5UPi7d+Ty+AlM+0ZkJPWXjUD5w5hU965FOPsnMIT1jEEw+n0UtPfxgST47Sjg9FYZGPmzU Qj0ugkM+yt5MPdhXQD4qZFY9yQk9PmRgXz3bmjk+189nPecNNj6Rr2892mUyPmP9dj23pS4+ vrd9PW3QKj7p7oE9EekmPru3hD2V8iI+mzaHPfHvHj4abIk9EeQaPjdZiz3L0RY+JP+MPeS7 Ej5OX449DKUOPo97jz3Jjwo+5VWQPZh+Bj6yAIy93u7/PftUi70D1AM+pWyKvdS1Bz6jRYm9 spoLPjTeh71YgA8+uzSGvVxkEz7gR4S9OUQXPpsWgr1jHRs+JUB/vSPtHj6Vx3m9z7AiPhzD c72eZSY++zJtvcQIKj4GGGa9fJctPsxzXr33DjE+WEhWvXBsND6XmE29Ja03PuBnRL1wzjo+ Sbo6vbbNPT6GlDC9bahAPrX7Jb0oXEM+wvUavYzmRT7eiA+9e0VIPt+7A73Wdko+EizvvLl4 TD4aPta8YUlOPtO9vLw7508+K7yivNFQUT5eSoi87YRSPvT0Wrx6glM+b70kvJhIVD60Jty7 oNZUPkNzXLsALFU+SbQoMoxIVT4tc1w7ASxVPuMm3DuZ1lQ+Zb0kPJlIVD7n9Fo8eoJTPmJK iDzrhFI+MLyiPNJQUT7Pvbw8OudPPgg+1jxgSU4+DizvPLp4TD7cuwM903ZKPtiIDz12RUg+ wPUaPY/mRT66+yU9I1xDPoeUMD1rqEA+U7o6PbfNPT7pZ0Q9dM46PpeYTT0jrTc+WEhWPWps ND7Dc1499A4xPgYYZj17ly0+/jJtPcQIKj4cw3M9m2UmPpbHeT3PsCI+JUB/PSXtHj6XFoI9 YR0bPuVHhD06RBc+uzSGPVxkEz4w3oc9WIAPPqVFiT2xmgs+pWyKPdC1Bz76VIs9AtQDPrpB h71xC/s95YaGvVo2AT5WkoW9NusEPj5ihL1Dogg+//SCvVZZDD4rSYG9Mg4QPi67fr18vhM+ kWJ6vb9nFz4ph3W9iwcbPi0ocL1Tmx4+LUVqvYIgIj6Z3mO9gJQlPk31XL2t9Cg+vYpVvXg+ LD4DoU29RW8vPs86Rb2NhDI+ZFs8vct7NT5/BjO9k1I4PqlAKb2PBjs+vQ4fvXWVPT47dhS9 Jf0/PgN9Cb2GO0I+8FL8vLVORD4EBeW85jRGPmAezbx57Ec+cK60vO5zST7HxJu878lKPtlx grxR7Us+xoxRvBndTD4apx28c5hNPvyr0ru/Hk4+HvRSu39vTj7TdGaxbopOPr3zUjt+b04+ J6zSO7oeTj4wpx08dZhNPrCMUTwZ3Uw+23GCPFLtSz7PxJs87MlKPmmutDzuc0k+Yx7NPHjs Rz75BOU86jRGPvJS/Dy0TkQ+An0JPYY7Qj43dhQ9Jv0/PsEOHz14lT0+qUApPZIGOz6ABjM9 lFI4PmFbPD3PezU+xjpFPY2EMj4AoU09RW8vPruKVT14Piw+TPVcPbD0KD6d3mM9fJQlPjdF aj2AICI+IShwPVGbHj4wh3U9jgcbPpNiej3BZxc+Mrt+PXq+Ez4wSYE9Ng4QPvz0gj1ZWQw+ O2KEPUaiCD5SkoU9N+sEPuSGhj1aNgE+srGCvac99j2L6YG9b0v9PXDqgL3yLwI+cmV/vZa7 BT7ygXy9lEYJPswneb3Tzgw+9lR1vSRSED6lB3G9Ns4TPsI+bL2+QBc+lvlmvWGnGj7xN2G9 sP8dPjL6Wr1BRyE+VUFUvad7JD60Dk29bponPmRkRb1AoSo+9kQ9vaaNLT6DszS9Wl0wPqGz K70bDjM+fEkiva6dNT7MeRi9/Ak4PqNJDr3/UDo+m74Dvc1wPD5CvfG8o2c+PoVg27zTM0A+ bHTEvMvTQT4hB628NEZDPqAnlbzPiUQ+B8p5vHedRT61nki8UoBGPhDtFryOMUc+jazJu5Gw Rz6R8Em79fxHPp1toDF8Fkg+zfBJO/b8Rz7BrMk7krBHPvzsFjyJMUc+q55IPE2ARj4Zynk8 e51FPqEnlTzKiUQ+IQetPDVGQz5mdMQ8y9NBPoFg2zzQM0A+UL3xPKZnPj6RvgM9zXA8PqJJ Dj39UDo+0HkYPfwJOD6JSSI9qZ01PqOzKz0XDjM+ibM0PVldMD77RD09po0tPmJkRT0/oSo+ sg5NPXaaJz5QQVQ9pHskPjL6Wj1DRyE+9TdhPa3/HT6S+WY9Y6caPsQ+bD3BQBc+owdxPTXO Ez7zVHU9I1IQPs4neT3Yzgw++YF8PZZGCT5tZX89lbsFPmnqgD3yLwI+hemBPW1L/T2MnXy9 4YXxPeH1er1pRPg9k+V4veoH/z2oaXa9ceYCPoZ/c72zRwY+0CRwvb6lCT7QV2y9i/4MPvYW aL3xTxA+RWFjvcOXEz4oNl69ydMWPqCVWL3PARo+AYBSvYUfHT5Q9ku9qyogPvz5RL3/ICM+ 5Yw9vUAAJj6TsTW9N8YoPuxqLb2/cCs+dLwkvbH9LT4Nqhu9EGswPhE4Er3UtjI+cWsIvSjf ND66kvy8P+I2PgWv57xpvjg+3DfSvCFyOj71Oby88/s7PpXCpbyaWj0+z9+OvOCMPj7+P2+8 xpE/PvYjQLx2aEA+5IkQvCoQQT6qIcG7YIhBPiFhQbuo0EE+qb0SMsPoQT5OYUE7q9BBPvwh wTtfiEE+9okQPCwQQT71I0A8eGhAPvA/bzzNkT8+x9+OPNyMPj6cwqU8mFo9Pvk5vDz2+zs+ 3zfSPCZyOj4Ur+c8bL44PsGS/Dw84jY+c2sIPSjfND4MOBI907YyPgiqGz0QazA+cbwkPbX9 LT7rai09u3ArPoqxNT03xig+5ow9PUAAJj4C+kQ9ASEjPlX2Sz2sKiA+B4BSPYcfHT6alVg9 zgEaPis2Xj3N0xY+SGFjPcGXEz4AF2g98E8QPtJXbD2K/gw+yiRwPcClCT55f3M9skcGPrBp dj1w5gI+j+V4Pe0H/z3r9Xo9ZET4PV0udL1q5Ow9WXJyvYBX8z22UnC9Rs75PbDMbb2SIgA+ A95qvUxcAz6ThGe9a5IGPsi+Y70Awwk+XotfvRPsDD5l6Vq9kQsQPo3YVb1tHxM+x1hQvYsl Fj6Takq90hsZPt4ORL0bABw+Jkc9vVLQHj40FTa9XIohPnF7Lr0mLCQ+o3wmvbGzJj4cHB69 /B4pPpNdFb0mbCs+LkUMvVmZLT6B1wK9y6QvPu0y8rzfjDE+7iDevP9PMz5FhMm8vOw0Psxo tLy2YTY+VtuevMStNz7U6Ii8yc84Pqc9ZbzPxjk+tRY4vAuSOj5neQq81TA7PpYFubueojs+ CUE5uwbnOz5HShyy6/07PtdAOTsK5zs+ggW5O52iOz5XeQo80zA7PqMWODwNkjo+nj1lPM/G OT7U6Ig8yc84PkXbnjzCrTc+2Gi0PLphNj4xhMk8vew0Ptkg3jwFUDM+9DLyPOGMMT6D1wI9 0KQvPitFDD1WmS0+kF0VPSRsKz4hHB49/B4pPqZ8Jj2wsyY+bnsuPSYsJD47FTY9WoohPixH PT1R0B4+4Q5EPRsAHD6Rako90BsZPsFYUD2JJRY+j9hVPW0fEz5h6Vo9jwsQPlyLXz0R7Aw+ yr5jPQPDCT6PhGc9a5IGPgDeaj1NXAM+tMxtPZIiAD6uUnA9Q875PV5ycj2FV/M9ahJsvVpZ 6D3PRGq924TuPUkYaL2msvQ9X4plvX7f+j0NmWK9CIQAPnBCX71UlAM+GYVbveOeBj7pX1e9 1aEJPjbSUr07mww+m9tNvSqJDz5FfEi9qWkSPrK0Qr25OhU+2oU8vWT6Fz4N8TW9saYaPjH4 Lr2wPR0+kp0nvWu9Hz684x+9ByQiPvzNF72lbyQ+s18PvYyeJj7lnAa99q4oPqgT+7xInyo+ b1bovPdtLD4JDNW8iBkuPlA/wbyioC8+hfusvAwCMT5QTJi8njwyPkI+g7xTTzM+77tbvFU5 ND7tcDC80vk0Pti2BLwtkDU+S1Gxu/H7NT6aiTG7vDw2PgU+ljFcUjY+v4kxO7w8Nj5QUbE7 8fs1Ps62BDwukDU+B3EwPM75ND71u1s8Uzk0Pi8+gzxXTzM+WUyYPKI8Mj5u+6w8DAIxPlc/ wTyioC8+EwzVPIYZLj5mVug8820sPqkT+zxMnyo+5JwGPfiuKD61Xw89ip4mPgXOFz2sbyQ+ uOMfPQgkIj6OnSc9a70fPjP4Lj2wPR0+B/E1PbCmGj7ahTw9ZPoXPri0Qj25OhU+P3xIPahp Ej6i2009KokPPjXSUj08mww+7l9XPdOhCT4VhVs9454GPmpCXz1UlAM+CZliPQSEAD5oimU9 hN/6PUkYaD2jsvQ9xERqPdeE7j1cRmS91uTjPahpYr04zOk9hjJgvcu07z2+nl29ZJv1PXKs Wr3gfPs9AVpXve2qAD4qplO9h5EDPvqPT71scAY+1RZLvdJFCT6EOka96Q8MPjb7QL3lzA4+ elk7veR6ET49VjW9BhgUPuDyLr2AohY+LDEovXUYGT5EEyG9JHgbPsWbGb27vx0+ns0RvZLt Hz40rAm98v8hPiY7Ab1J9SM+NP3wvBPMJT7g9d684IInPuxpzLxHGCk+PWO5vBKLKj597KW8 DdorPusQkrw0BC0+D7h7vIoILj6Ls1K8QeYuPhUtKbyhnC8+dXz+uxkrMD5bAKq7MpEwPqw0 KruTzjA+L0CrsQ7jMD6YNCo7j84wPjAAqjsukTA+dHz+OxgrMD4ILSk8oZwvPoazUjw95i4+ 5bd7PIwILj72EJI8MwQtPoPspTwQ2is+SWO5PA+LKj72acw8RhgpPuX13jzggic+MP3wPBXM JT4dOwE9TPUjPiysCT3x/yE+o80RPZDtHz7Kmxk9vb8dPj4TIT0geBs+LzEoPXUYGT7i8i49 fqIWPkFWNT0JGBQ+dVk7PeF6ET46+0A96MwOPoc6Rj3uDww+2hZLPdNFCT71j089aXAGPiam Uz2GkQM+C1pXPfGqAD51rFo93Xz7PbieXT1im/U9hTJgPci07z2oaWI9PszpPf3GXL3Yht89 f91avYot5T3CnVi9RNTqPeUFVr01ePA9KBRTvVMW9j0ix0+9iav7PbEdTL1KmgA+FhdIvQ9X Az7MskO9bwoGPqnwPr20sgg++NA5vSJOCz48VDS9AdsNPoB7Lr2bVxA+/kcovSzCEj6UuyG9 BhkVPizYGr1zWhc+VqATvdqEGT7kFgy9mpYbPvU+BL0rjh0+Qzj4vAxqHz5ZZOe80CghPrMK 1rwcySI+KDTEvK9JJD4S6rG8W6klPsI2n7wC5yY+dSSMvLQBKD4ffHG8hPgoPgMeSry1yik+ 0EUivJN3Kj4mFvS7mv4qPkIMo7tdXys+ET4ju4yZKz4AAAAA7awrPiM+IzuJmSs+KgyjO19f Kz4zFvQ7mf4qPtlFIjyWdyo+AB5KPLLKKT4WfHE8gPgoPlkkjDyvASg+uTafPAXnJj4X6rE8 WqklPiU0xDyrSSQ+pQrWPBvJIj5WZOc8zyghPko4+DwLah8+/j4EPSyOHT7qFgw9nJYbPleg Ez3bhBk+LtgaPXJaFz6RuyE9BBkVPgdIKD0owhI+hHsuPZZXED48VDQ9A9sNPvzQOT0kTgs+ rfA+PbSyCD7IskM9bwoGPiAXSD0MVwM+th1MPUOaAD4ex089gKv7PSgUUz1WFvY94wVWPTd4 8D3KnVg9RNTqPXrdWj2ALeU9Q5FVvXA/2z34nFO9eKjgPYNWUb2oEOY9KLxOvVB16z1ZzEu9 jdPwPcuFSL11KPY9n+dEvfVw+z0T8UC9AFUAPsahPL0w6AI+ufk3vX5wBT4X+TK9P+wHPp6g Lb3eWQo+NPEnvbe3DD4h7CG9MQQPPhWTG72wPRE+DegUvahiEz5x7Q29j3EVPtylBr3eaBc+ zCj+vC9HGT6aeO68EgsbPodC3rw0sxw+dY7NvFg+Hj7zZLy8TKsfPr/Oqrz/+CA+SNWYvFsm Ij6Ogoa8hDIjPrLBZ7yVHCQ+RPVBvOvjJD7dtRu83YclPkI06rvnByY+rXCcu6hjJj6anxy7 0ZomPmnQ17IzrSY+kp8cO9GaJj6icJw7qGMmPiE06jvmByY+9bUbPN+HJT499UE86eMkPsbB ZzyZHCQ+lYKGPHwyIz5R1Zg8XCYiPrPOqjz3+CA+8mS8PFKrHz57js08XD4ePopC3jw1sxw+ mXjuPA8LGz7EKP48KUcZPuKlBj3iaBc+dO0NPY9xFT4S6BQ9qmITPhqTGz2yPRE+H+whPTAE Dz4x8Sc9t7cMPqOgLT3cWQo+JPkyPT/sBz67+Tc9fXAFPsahPD0z6AI+GPFAPQBVAD6a50Q9 93D7Pc+FSD11KPY9W8xLPZLT8D0fvE49VXXrPXpWUT2tEOY9+JxTPXio4D0rok69Zw7XPfak TL3WPNw9cllKvZlp4T0Bvke9JpLmPVfRRL3Fs+s9Q5JBvbDL8D0DAD69GNf1PeYZOr0E0/o9 v981vYm8/z2IUTG9UEgCPo1vLL0npgQ+fDonvT32Bj46syG9FzcJPhrbG70pZws+vLMVvf+E DT79Pg+9H48PPip/CL0VhBE+zXYBvXpiEz58UfS8/SgVPlsw5bxL1hY+K5HVvCFpGD4/e8W8 WuAZPqf2tLzdOhs+4QukvJh3HD6Zw5K8oZUdPmAngbwYlB4+QYFevDhyHz4dMzq8Ui8gPtd4 FbzcyiA+4M7gu1NEIT5+KJa7W5shPttUFruxzyE+xrrnMCrhIT6EVBY7sc8hPnIoljtamyE+ js7gO1NEIT7qeBU838ogPkEzOjxULyA+ToFePDpyHz5cJ4E8FZQePpbDkjyelR0+5QukPJh3 HD6x9rQ83DobPkJ7xTxd4Bk+LJHVPB9pGD5iMOU8SdYWPoJR9Dz9KBU+zHYBPX1iEz4ofwg9 E4QRPgM/Dz0ejw8+vLMVPQKFDT4l2xs9LGcLPj2zIT0YNwk+ezonPT/2Bj6Nbyw9J6YEPoBR MT1RSAI+vN81PYq8/z30GTo9BNP6Pf//PT0W1/U9SJJBPbTL8D1R0UQ9xbPrPQi+Rz0mkuY9 aFlKPZlp4T35pEw91zzcPc/2R72j89I9afJFvVTq1z1Qo0O9lt7cPSAIQb0EzuE9pB8+vSG2 5j3h6Dq9NpTrPRRjN72zZfA9yI0zvcAn9T3PaC+9odf5PSz0Kr2Ocv49UDAmvdJ6AT7LHSG9 BK8DPqa9G7151AU+ChEWvcHpBz6eGRC9eO0JPjPZCb0+3gs+3VEDvcO6DT5NDPm8s4EPPnrx 6rzFMRE+QVncvMbJEj5ESs28kkgUPmPLvbwGrRU+NeStvCn2Fj6ynJ287SIYPkX9jLyGMhk+ fx14vB4kGj5atFW8+vYaPg/SMrx/qhs+y4kPvBs+HD4/39e7YLEcPlYvkLv6Ax0+UlgQu6A1 HT6D+SKwN0YdPixYEDuhNR0+Xy+QO/gDHT5D39c7XbEcPrmJDzwcPhw+FNIyPH2qGz5NtFU8 +/YaPoQdeDwdJBo+S/2MPIYyGT63nJ088CIYPjjkrTwj9hY+YMu9PAmtFT5KSs08kEgUPkpZ 3DzHyRI+dvHqPMQxET5dDPk8r4EPPuNRAz3Eug0+MdkJPUHeCz6mGRA9eu0JPgsRFj2/6Qc+ qL0bPXfUBT7MHSE9Ba8DPkwwJj3QegE+NfQqPYpy/j3JaC89pdf5PcmNMz3AJ/U9DmM3Pa9l 8D3i6Do9NZTrPZsfPj0ctuY9FghBPQbO4T1Xo0M9ld7cPWnyRT1R6tc9dYxBvQbvzj1ggj+9 k7DTPRIxPb0eb9g9S5c6vUUo3T3vsze9wtnhPTCGNL0CgeY9VQ0xvZIb6z0VSS29zabvPUg5 Kb0nIPQ9+t0kve6E+D2oNyC9hNL8PfFGG70ZgwA+wQwWvauOAj5YihC9oIoEPjHBCr24dQY+ JrMEvZlOCD5mxPy8BRQKPlGh77zOxAs+ZwLivMBfDT467dO8s+MOPulnxbyZTxA+S3m2vF+i ET5jKKe8HdsSPsJ8l7zi+BM+Vn6HvOH6FD6ham68W+AVPqZUTbyeqBY+kcwrvBJTFz6Y5Am8 Od8XPvNez7uwTBg+JYCKuxabGD5gpwq7O8oYPsUFKbL62Rg+cKcKOzvKGD4ygIo7GZsYPvhe zzutTBg+o+QJPDffFz6MzCs8EFMXPrNUTTyZqBY+k2puPFbgFT5Vfoc84voUPsl8lzzj+BM+ XiinPB/bEj5DebY8YaIRPuRnxTyWTxA+M+3TPLPjDj5fAuI8wF8NPlWh7zzPxAs+V8T8PAoU Cj4pswQ9lk4IPjvBCj2zdQY+WIoQPaKKBD68DBY9qY4CPulGGz0XgwA+pDcgPXzS/D0J3iQ9 8YT4PUw5KT0oIPQ9GEktPc+m7z1aDTE9jhvrPSOGND0AgeY99bM3PbrZ4T1Nlzo9SCjdPRox PT0Wb9g9WoI/PY6w0z1rYDu9RgDLPRFSOb1Aj889wv82vZsa1D1xaDS9P6DYPROLMb3RHd09 8mYuvQyR4T18+yq9hPflPXVIJ73WTuo9sU0jvYCU7j1vCx+9CsbyPRCCGr3+4PY9TrIVvdTi +j3+nBC9CMn+PW1DC72VSAE+DacFvWQcAz4Gk/+8s94EPqFZ87xhjgY+XKbmvEkqCD4oftm8 RrEJPlTmy7xPIgs+6eS9vF98DD4egK+8gL4NPqa+oLzO5w4+sqeRvHL3Dz64QoK8ouwQPvIu ZbyqxhE+T1xFvPCEEj7eHSW84SYTPneFBLwIrBM+GUjHu/0TFD7uF4W7el4UPiA9Bbs+ixQ+ H7KTMDWaFD79PAU7P4sUPrcXhTt5XhQ+J0jHO/4TFD5vhQQ8B6wTPt4dJTziJhM+QlxFPO+E Ej7lLmU8qsYRPrpCgjyi7BA+r6eRPHL3Dz6fvqA8zucOPhuArzyAvg0+0uS9PF58DD5Y5ss8 TyILPid+2TxEsQk+Q6bmPEQqCD6hWfM8YY4GPgKT/zyy3gQ+E6cFPWIcAz5sQws9lEgBPvyc ED0Jyf49TLIVPdLi+j0Mgho9/uD2PWgLHz0LxvI9rk0jPX6U7j1xSCc90k7qPXz7Kj2E9+U9 92YuPQiR4T0dizE90h3dPXBoND1BoNg9zP82PaAa1D0PUjk9PY/PPSRwNb0eJ8c90V4zvfGF yz2jDDG9qeDPPal4Lr1JNdQ9/KErvYqB2D0GiCi9V8PcPUYqJb1o+OA9hIghvXke5T3Coh29 NzPpPSd5Gb1GNO09NQwVvUof8T2OXBC9APL0PSZrC73oqfg9IDkGvdtE/D3mxwC9esD/PTYy 9rw/jQE+Y13qvGMoAz5tFd68jLAEPgZf0by/JAY+ZT/EvO+DBz4DvLa8M80IPvnaqLyi/wk+ gKKavGYaCz6IGYy8rhwMPq6NerzTBQ0+NWRcvBTVDT5ZxT287okOPjXBHrzaIw8+VtD+u2Si Dz7nlL+7MgUQPlDkf7v4SxA+3BQAu4R2ED4bdN+xvoQQPqoUADuBdhA+AeR/O/dLED7vlL87 MQUQPiPQ/jtlog8+JMEePNkjDz5KxT088YkOPjFkXDwU1Q0+wY16PNEFDT6LGYw8shwMPnei mjxjGgs++dqoPKP/CT7+u7Y8NM0IPlY/xDzxgwc+BF/RPMAkBj53Fd48kLAEPlld6jxiKAM+ RTL2PECNAT7rxwA9dcD/PSM5Bj3dRPw9LGsLPeyp+D2IXBA99vH0PTgMFT1LH/E9MnkZPT40 7T3Coh09NTPpPYSIIT18HuU9SyolPW744D0JiCg9W8PcPf2hKz2Qgdg9nHguPUg11D2jDDE9 ruDPPcleMz3uhcs9N7kvvVdjwz3+pS29RpTHPexUK726wMs9JcUova7mzz3S9SW9IgTUPXfm Ir33Ftg9r5YfvS8d3D1HBhy9gRTgPVY1GL3a+uM9DiQUverN5z3w0g+9novrPZNCC72mMe89 /3MGvd698j1GaAG9Ey72PYNB+LwkgPk9Fj7tvOix/D3zyeG8X8H/Pfro1bw9VgE+pp/JvK64 Aj4p87y8CAcEPnXor7xzQAU+VYWivBRkBj7Pz5S8HXEHPkPOhrzUZgg+lw5xvJFECT77A1S8 tQkKPsaKNryxtQo+/7EYvApICz4vEvW7WcALPjg/uLtHHgw+shZ2u5NhDD4FWPa6A4oMPqon nzF4lww+Ulj2OgCKDD7EFnY7kWEMPks/uDtIHgw+XxL1O1rACz4Qshg8DkgLPreKNjyytQo+ BgRUPLUJCj68DnE8lEQJPk3OhjzTZgg+48+UPBtxBz5hhaI8EWQGPnborzxzQAU+FfO8PAkH BD60n8k8qrgCPgLp1Tw+VgE+5MnhPF3B/z0EPu087bH8PYNB+DwfgPk9QmgBPRMu9j0CdAY9 3r3yPZJCCz2nMe8969IPPZuL6z0LJBQ97s3nPVs1GD3Y+uM9TAYcPYYU4D2qlh89Lh3cPXnm Ij38Ftg90PUlPR4E1D0dxSg9q+bPPfhUKz20wMs99aUtPUSUxz1KJwC+7T8KvBOhBL7Qiw28 dFkJvsfCELwlVQ6+xdoTvGWZE76Gxha8AiwZvj13GbxTEx++bNkbvGdWJb4S1h28Af0rvl9R H7zXDzO+oSggvIWYOr55MiC8vqFCvkg7H7yIN0u+wwMdvFFnVL4DPxm8G0BevnGNE7zC0mi+ d3kLvDoydL56cAC86jmAvpl547u714a+mfi8uwYAjr6xJIu7ycGVvshuFrvCLZ6+ImxKOW1W p74c0Fs75k+xvosg8TunL7y+KotLPMsLyL5AMJo81PnUvm5c3DxEDOO+nukXPThP8r5ieUw9 O2EBv8s/hz3KKAq/dIawPXpkE7+DvuM9yOQcv/dHET4bXya/+iY3PntsL797wGM+jpA3v1JX iz70Sz6/w1anPoM3Q7+DzcQ+gh5Gv+5g4j6QC0e/D6/+PgZBRr8ASQw/qyJEv5CkFz9AHEG/ OD8hP3iOPb8CGSk/ycU5v9VNLz/i+DW/rQc0P3NLMr/YdDc/fNIuv/nBOT9tmCu/LRc7P6ag KL8Clzs/7Oklv5ReOz9AcCO/+oU6P/MtIb8XITk/iRwfv1ZANz8eNR2/QPE0P8dwG78sPzI/ pMgZv8MzLz8PNhi/TdcrP6WyFr8oMSg/TDgVv/pHJD9OwRO/BSIgPztIEr87xRs/D8gQv3g3 Fz8tPA+/kX4SP3JMA75rmsu7/O8Hvp4AzrvF1Ay+oOXPu8T/Eb4GK9G7aHYXvguu0butPh2+ zULRuyNfI75sts+7C98pvnXLzLtuxjC+JDjIuyEeOL7UpMG7+O8/vkSmuLvVRki+KLysu9Au Ub4iS527ZrVavvWWibt36WS+PHZhu7vbb76TQCO7rZ57vgPFq7prI4S+oJgeOYL1ir6FJwA7 LlKSvi3kiDs1R5q+hnXiO5Pjor70Rig8UjesvhfuazxBU7a+PIqfPFtIwb4Zp9I84ybNvmnA CD26/Nm+aWMvPSTT577z2l49HKv2vtiIjD1MPAO/JB2wPSOOC7/vXts9DC4Uv8/DBz417hy/ vdYmPuiNJb9+Q0s+2Lotv3cOdT7ZFzW/Ed+RPpdJO7/hIas+IgdAv9iBxT7uKEO/AgPgPomw RL8wovk+O8VEv7i+CD9dqEO/63cTP1SmQb9bzRw/dgk/v1OvJD/kETy/xSUrPyLyOL9/RzA/ 9s41v/IyND8xwTK/tgg3P1DYL79t6Dg/qhwtvwnvOT+SkSq/GDY6P+E2KL+V0zk/EQomv0Xa OD8eByS/B1o3PwkpIr9QYDU/WWogv5D4Mj80xR6/rywwP6YzHb9CBS0/x68bv/uJKT+0Mxq/ 8sElP8m5GL+4syE/gjwXv7hlHT+5thW/ON4YP4kjFL+LIxQ/C0QGvtCzfruNDQu+UrF6u5Ua EL4t93S7QnAVvnQ2bbscFBu+NRJju0UMIb5XHVa7bl8nvgDVRbv2FC6+f6Mxu/w0Nb6o0Bi7 bMg8vi0S9bob2US+n5Gruu5xTb7+hiW62Z5WvgKoQTkjbWC+fMGYOmfrar6Xfxk7sil2vqXv dTvjHIG+lFayO3qXh74hq/Q7P4+OvoESIjykD5a+YrZRPPMknr50b4U8Mdymvv/ApzzHQrC+ FQHRPCdmur5IUAE9AlPFvsAuHz1AFNG+WiZDPV+x3b7Ncm49OCzrvuZBkT3rffm+V32wPYFJ BL8v0NU9gSMMv1UTAT7bLxS/hC8bPtpEHL9zlDk+zCskv1JsXD40oyu/Xc2BPjRkMr9CU5c+ Zis4v99Xrj4hwzy/mTzGPrcMQL9fRN4+AQVCv56r9T5Jw0K/w+AFP9NyQr+N/Q8/uElBvx7+ GD9fgD+/OMsgP9lKPb+VYCc/RNU6v6fHLD9hQji/UhIxP/2rNb/cVjQ/CCQzv9isNj8NtjC/ SCs4P65oLr9y5zg/zD4sv4n0OD+NOCq/ZmM4PzhUKL+6Qjc/no4mv0SfNT+l4yS/F4QzP55O I7/c+jA/WMohvysMLj9oUSC/z78qP0XeHr/rHCc/ZGsdv1kqIz9I8xu/su4eP45wGr+UcBo/ Nd4Yv7a2FT+gCwm+rmfAuib3Db74Fqa6EygTvr7lhrqWoxi+KxhEuk1vHr5NrNq5YpEkvmHR 7beaECu+6g7gOVj0Mb4Z4ns6r0Q5vka7zzqGCkG+5asXO55PSb75iU87oB5SvsNqiDtHg1u+ U5auO1uKZb6EPNs75UFwvoLABzwzuXu+p18mPGwAhL7PSko8Z5WKvox5dDwkpZG+9AmTPOM5 mb5qPrA8U16hvuWt0jxkHaq+dlX7POmBs75usRU9KJa9vvgdMj30Ysi++sJTPa/u075hlns9 qDvgvlZZlT1LRu2+2yqxPYIC+76Z7dE9b6wEv+FW+D3FEQy/74sSPsmVE79GZSw+rRMbv9nr ST7QXSK/7CtrPuM/Kb/M/Ic+NoMvvyDymz639DS/WhmxPrZrOb/29cY+oM88vyf23D4TGz+/ mYLyPp9bQL9JhwM/961Av7sSDT+nOEC/BrkVPw0mP78XYB0/tJ89v4z8Iz/fyju/wo4pP8rG Ob9YHy4/T6w3vx68MT8LjjW/h3U0Pzp5M7/VXDY/lXYxvwKDNz89iy+/7fc3P325Lb8dyjc/ bQEsv5AGNz+JYSq/0bg1PxPXKL8b6zM/U14nv5emMT/t8iW/bvMuPwSQJL8u2Ss/XjAjv+Ne KD+YziG/VYskPzBlIL8zZSA/re4ev0XzGz+1ZR2/gjwXPxGhC74HFoc6j6oQvvQ1tDrn+hW+ 5q7nOkeXG75RNRE7XYUhvla4MjtLyye+8PpYO9JvLr6jWII7Pno1vphVmzuU8jy+9+y3O4fh RL4Drdg7mFBNvl07/jsnSla+n6wUPHrZX75DdS080Apqvvn8STxf63S+UOFqPLxEgL7ZbYg8 M3qGvndjnjw9Ho2+t9K3PGo5lL5VVNU8p9Sbvv6b9zwH+aO+4b4PPXGvrL5z+SY9WgC2visP Qj0o87++sKlhPVyNyr7sRYM9pdHVvsLJmD1xvuG+PNyxPWNM7r51BM89Vmz7vlvQ8D2kggS/ 7+YLPi15C7+4PyI+s4ASv2amOz5ZeRm/hzdYPjM9IL+L7Xc+QKImv1RLjT6ffSy/u+afPsun Mb8mfLM+EQE2vwSoxz5hdTm/gvfbPmn+O7/h8u8+mqM9v0WUAT8aeD6/IZsKP0qXPr+q5xI/ DCE+v19fGj8YNj2/FvMgPzj1O79JnSY/pXk6v9hfKz8v2ji/90EvP/YoN78WTjI/uXM1v1eQ ND9pxDO/ehU2P4whMr8O6jY/+Y4wv+0ZNz9PDi+/ErA2P1ufLb+AtjU/iUAsv0s2ND8L7yq/ qDcyP0qnKb8Xwi8/6WQov5ncLD8EIye/3I0pP1fcJb9Z3CU/Uoskv5vOIT9VKiO/Z2sdP7mz Ib/HuRg/rgIOvmPCazv7JRO+YPWFOyyRGL7S/Jc7a0kevq85rDtSVCS+1PjCO/y3Kr5ikdw7 CHsxvgpo+TuppDi+aPgMPK48QL5CWR88i0tIvowkNDxl2lC+YLRLPDPzWb5ccmY8oqBjvhRs gjxI7m2+A7qTPGjoeL4cdqc8GU6CvjEBvjzLi4i+gczXPIo0j76jW/U83E+WvlykCz1Z5Z2+ YiMfPYP8pb6ikjU9aJyuvnlqTz1Vy7e+0DRtPSuOwb56x4c9u+fLvkKVmz3Y19a+DGayPSla 4r72pMw942TuvgHD6j1j5/q+ZpkGPkzkA7/1MBo+/3IKv1RXMD5eCRG/Si5JPhaMF7+JwmQ+ rtsdvzOCgT4f1iO/meCRPl5ZKb+bT6M+OEYuvwiPtT6FgzK/CE7IPpIANr9zMNs+0bY4v/vV 7T7nqTq/X+H/PnrmO7/bfwg/HoA8v092ED+1jjy/eboXP9UrPL9jOx4/sHA7v9jvIz9udDq/ FNUoP25LOb837Sw/iwY4v9A9MD9Zsza/i84yPxtcNb9eqDQ/QAg0v37UNT+ZvDK/Klw2P917 Mb8jSDY/8UYwv6qgNT8mHS+/WW00P478Lb81tTI/K+Isv9B+MD8Wyiu/TtAtP7GvKr+3ryo/ 2I0pvwgjJz/fXii/YzAjP+8cJ79K3h4/88Elv7YzGj8ZLxC+btbLOwloFb5Dw+A7gOkavnH/ 9zuRuCC+oeoIPMfaJr5+TBc8GFYtvuBVJzz8MDS+6D05PHhyO755RE08BSJDvnKyYzzRR0u+ ENx8PJvsU77IkIw8yBldvmN5nDxk2Wa+PWiuPCc2cb6tp8I8cTt8vpyN2TyX+oO+PH3zPOc3 ir6fdAg9EdyQviIrGT2C7Ze+Oy4sPZ5yn75w1UE9ZXGnvgiFWj1H76++FK92PabwuL4Waos9 VXjCvjfCnT0Fh8y+g6+yPV8a174wiMo9Lizivoen5T1Nse2+qTUCPqKY+b5/lxM+FOUCvwQj Jz4TEwm/4Pk8PptCD7/FMFU+TlwVvyXKbz77RRu/eViGPujjIL8s2pU+qRomv7pCpj5I0Sq/ J1y3PmzzLr/448g+FXMyvw+P2j7KSTW/nQ7sPtd4N79OFf0+dwg5v0iuBj+vBjq/6VMOP16F Or+RYxU/hpg6v6/LGz+EVDq/74AhP+DMOb9YfSY/ThM5v02/Kj8sNzi/h0guP0JFN7/7HDE/ x0c2vyZCMz9xRjW/Ub40P7ZGNL8MmDU/D0wzv+jVNT8hWDK/KH41PwFrMb/XljQ/boMwv4Ql Mz/tni+/iC8xPwa6Lr8Hui4/S9AtvxbKKz+Z3Cy/7WQoPyrZK78GkCQ/yr8qv2pRID/8iSm/ yK8bP1glEr59oBE8w28XvqOFHjzxAh2+074sPNrjIr61dDw85hcpvgTWTTzlpC++0hZhPB6R Nr5Dc3Y8POM9vpsXhzyFokW+aUyUPKLWTb5aBKM864dWvq1yszwkv1++KdHFPKuFab7RYto8 V+VzvhF08Tx06H6+CK4FPeVMhb63PxQ9G4KLvkaoJD1vGZK+CCk3PVIYmb6NDEw98YOgvhSn Yz0LYai+2ld+PZKzsL7pRI49VH65vrhZnz1+wsK+lquyPRR/zL7/gMg9QrDWvtUk4T2tTuG+ SOT8PZNO7L4eBg4+Jp/3vq1yHz70lAG/PNcyPiRpB79BS0g+5joNv03aXz5R9hK/SYB5PoWF GL/akoo+wNEdv11OmT6zxCK/OtCoPhlKJ7+m6rg+S1Erv2NmyT5uzi6/UgXaPl+7Mb8Mhuo+ 5xc0v+qn+j5a6TW/KRcFP6s5N7/ycQw/VBY4vw9OEz/cjji/LJoZP8KzOL/OSR8/QZU4v/FU JD+hQji/PrcoP4bJN79sbyw/zTU3v3Z+Lz8ukTa/5uYxP1zjNb9OrDM/JTI1v9HSND9sgTS/ tF41P2jTM79mVDU/zSgzvxW4ND/SgDK/zI0zP3PZMb902TE/hS8xv/GeLz/KfjC/L+IsPxfC L79Spyk/afMuv/PyJT8sDC6/WcohPz8FLb+mMx0/1OQTvuzePTycPBm+6S9NPADdHr7p/108 38okvgR7cDxxCyu+TmmCPFGkMb5mn408eZs4vrH/mTxa9z++SK6nPMy+R77W07Y8GPlPvuSe xzz6rVi+LUTaPJzlYb6p/+48m6hrvsEKAz3q/3W+jekPPWd6gL4xSB49YEiGvp9YLj2nboy+ K1NAPfXxkr6sd1Q9zNaZvuANaz1TIaG+FTOCPRrVqL4bbZA91vSwvkVmoD0Mgrm+8VSyPZl8 wr5Kc8Y9TeLLvnj/3D1TrtW+1Tn2PafY376vMQk+g1Xqvl/dGD7ZFPW+izwqPvsAAL+sZj0+ s4EFv6BrUj6M/Qq/oVBpPpFjEL/EBoE+dqEVvxJFjj5epBq/NE6cPgJaH7/+A6s+uLEjv2s/ uj65nSe/CtLJPvETK7/vh9k+rw4uv0kq6T7WjDC/YYL4PriRMr/1rQM/cCQ0v+XDCj8ZTzW/ lG4RP9kdNr9UnRc/+Z02v0FDHT/53Da/91YiP9rnNr9U0iY/r8o2v8SxKj8wkDa/0fMtP3lB Nr+ZmDA/FOY1v0uhMj/JgzW/yA80P8YeNb9Q5jQ/prk0v0MnNT+QVTS/GNU0PyTyM78u8jM/ w40zv9OAMj9/JTO/cIMwPzK1Mr+U/C0/pzcyvw/vKj+SpjG/WF4nP9r6ML+eTiM/rCwwvy/F Hj9AbRW+6nVqPFjOGr4eLHw8l3cgvurEhzytbSa+OF+SPJi1LL7//p08wFQzvurBqjzPUDq+ OMm4POGvQb6KOsg8X3hJvkFA2TwcsVG+HwrsPElhWr4YZwA9YpBjvsTkCz1FRm2+XKAYPfuK d76kwCY9XDOBvk1xNj3w8Ia+aeNHPUgCjb4PTls9XGuTvqvucD3XL5q+4YSEPfNSob6W9ZE9 RteovifzoD1uvrC+8aqxPe0Iub7wTcQ9pbXBvhEQ2T2Jwcq+jCfwPSQn1L7G5QQ+Qt7dvh4Z Ez5e2+e+S8ciPngP8r6qBjQ+vGf8voroRj7OZgO/JXdbPoCTCL9ts3E+gasNv27JhD5nnxK/ 1H6RPoZfF7/Z5p4+tNwbv//mrD4wCSC/3127PnDZI78YJMo+5EQnv8kN2T5NRiq/qeznPh/c LL/dkfY+SggvvyBoAj/UzzC//z4JP2w6Mr/1ug8/mVEzvzrMFT8RIDS/4mUbP/iwNL/bfSA/ fg81v7QMJT8qRjW/Qg0pP5deNb8hfCw/PWE1v29XLz9HVTW/T54xP25ANb+rUDM/BSc1v8hu ND/rCzW/OPk0P5XwNL+Y8DQ/E9U0v5FVND8PuDS/zCgzP9CWNL8FazE/XG00vykdLz9INjS/ i0AsPxrrM78b1yg/FYQzv67jJD+O+DK/WGogP7K+Fr4Lm4s8LyUcvmqjlTwK0yG+xZKgPL7M J77Fgaw8FxcuvquLuTwqtzS+2M/HPFqyO742cNc8YA5DvqWT6DxB0Uq+v2X7PEcBU76NCwg9 DKVbvjJvEz1yw2S+Y/wfPX1jbr6j1S09ZIx4viMhPT2wooG+8QlOPdFKh77Vv2A9C0KNvtd3 dT2ii5O+fTaGPYAqmr7575I9DiGhvtMLoT0Lcai+gbCwPUMbsL6GB8I9Wh+4vtA81T1/e8C+ T37qPREsyb6e/QA+UCvSvj7xDT4Ocdu+oTAcPlXy5L5k0Cs+SKHuvgXiPD7xbPi+9HFPPq4g Ab9ohmM+AAQGv2odeT4O1Aq/pRWIPt2DD7+oTJQ+RQYUv3oioT6uThi/9X+uPpZRHL9DSLw+ VAUgv8dZyj6GYiO/MI/YPodkJr/2wOY+fwkpv9LG9D53Uiu/vTwBPw1DLb/z2Qc/E+EuvyEq Dj8RNDC/fx4UP7NEMb9wqhk/Thwyv5/DHj9gxDK/zGEjPx1GM7+Yfic/KKozvzIVKz9M+DO/ KyIuP0A3NL/rojA/tmw0v5+VMj8CnTS/z/gzP0DLNL9HyzQ/Nfk0v/ALNT9BJzW/r7k0P19U Nb9w0zM/KX41vyNYMj+noDW/80YwP322Nb9kny0/zbg1v45hKj9DnzW/oY4mP0tgNb8OKSI/ eNkXvv/4oTyYQR2+hietPP/vIr7ATrk88+govmuIxjwCMS++7/DUPPPMNb4UqOQ818E8vjXR 9TwGFUS+7EkEPQ7MS771jQ49u+xTvlrNGT0gfVy+ayMmPVeDZb7brjM9uwVvvnCRQj2lCnm+ +vBSPS7Mgb4h92Q9gVqHvlTSeD0xM42+s1qHPeJYk74KbJM9082ZvpK7oD28k6C+VWqvPaSr p76bm789rBWvvvR00T3f0La+xB3lPd3avr59vvo9sC/Hvv0/CT6Cyc++DUUWPmig2L4+gSQ+ DarhvjoFND7B2eq+cd5EPlQg9L7ZFVc+Q2z9vrKuaj77VAO/H6V/PiTiB7+C9oo+llIMv4S4 lj5LmxC/IgmjPqixFL/2068+E4wYvxQAvT5YIhy/nHDKPi1uH7+RBdg+YmsivwKd5T4eGCW/ FRTzPtF0J78/JAA/EYQpv6aMBj9XSiu/8rMMP6TNLL9njBI/DxUuv+wJGD9wKC+/KiIdP+wP ML9wzCE/k9Mwv50BJj8gezG/27spP8gNMr9s9iw/7JEyv2itLz8NDTO/ct0xP5GDM7+VgzM/ w/gzvwmdND/DbjS/Bic1P0vmNL/KHjU/tF41v26BND/h1TW/E0wzPyBINr/jezE/ELA2v1YO Lz+MBje/cAEsP7lCN784VCg/Blo3vx4HJD9Cvhi+Dz+4PGUkHr70isQ8d88jvubf0TyEwym+ e1jgPNQEML7mEfA85pc2vhmWAD1vgT2+1OUJPWPGRL4RDBQ94GtMvvAeHz0od1S+CzcrPbnt XL6kbzg9G9Vlvr3mRj3mMm++1b1WPZ0Meb6WGWg91rOBvlgiez2hJIe+SgKIPRLbjL5MeJM9 ONmSvo4NoD3AIJm+Yd6tPc6yn74/Cb092Y+mvmOuzT1yt62+zu/fPS8otb6B8PM9Wt+8vgDq BD7S2MS+2N4QPssOzb6y5x0+sHnVviYULD71D96+sHE7Pg/G5r6QCkw+bo7vvh7lXT6sWfi+ bQJxPmWLAL/CroI+3NkEvy11jT7SDgm/nsqYPvMgDb8roaQ+WQcRv/DmsD7juRS/Roa9Pqcx GL88Zso+O2kbv01r1z7uXB6/FHjkPvEKIb9hbvE+WHMjvxQw/j4EmCW/708FP3d8J78XUQs/ gSUpv88OET8MmSq/nn0WP7bdK79Ykxs/ifosvzxHID+m9i2/qpEkPxHZLr8QbCg/eKgvv9HQ Kz/fajC/3rouP7ElMb+0JTE/at0xvxINMz+flTK/tmw0P6dQM79vQDU/ww80v8yDNT/F0jS/ KjI1PwmYNb+4RjQ/Jlw2v5m8Mj/oGTe/AY8wPxnKN7+AuS0/Y2M4v5U4Kj9B2ji/EgomP+tt Gb6EWM48ps4evpC32zy5ciS+zi7qPPRdKr7x2Pk8YJQwvtZpBT0nGje+8p8OPabzPb7SoBg9 ZiVFvqWAIz0btEy+VVUvPYmkVL5oNzw9k/tcvqtBSj0svmW+x5FZPTXxbr4OSGo9f5l4vgiI fD3KXYG+WjyIPeethr4iIpM9/T6MvisMnz2kEpK+OhOsPQkqmL6bUbo904WevknjyT38JaW+ peXaPbMJrL5Cd+09Ly+zvpvbAD6Jk7q+WOILPpEywr4V3xc+rQbKvi/gJD6yCNK+ofIyPs4v 2r4wIUI+j3HivtVzUj7oweq+tu5jPlAT876NkXY+Elf7vlorhT7GvgG/Q5mPPmC7Bb96iZo+ b5kJv5DvpT5kUQ2/zbuxPmPcEL9Q270+jDQUv3Q4yj42VRe/ZbvWPiQ7Gr+xSuM+quQcv//L 7z6mUR+/yCT8Pn6DIb+OHQQ/+HwjvwL7CT8HQiW/HJ8PP6nXJr8T/xQ/i0MovyURGj/Niym/ mMweP9i2Kr+fKSM/D8srvzchJz+nziy/Hq0qP3zHLb+Dxy0/2Louv+ZqMD9irS+/85EyP+qi ML9INzQ/UJ4xv09VNT9GoTK/GOY1P0qsM79l4zU/T740v3FGNT9+1DW/Qwg0PwrqNr+NITI/ 6fc3vz+LLz+F9Di/zD4sP5XTOb/oNig/n+kZvg0y5DysQR++GZnyPE/bJL6/EgE9G7oqvjx5 CT3C4TC+EI8SPSVWN76bZBw9UBs+vh0MJz1ZNUW+bZkyPYyoTL51Ij89LXlUvki/TD2eq1y+ NIpbPTBEZb4GoGs9JUduvhogfT2VuHe+YBaIPS/OgL59dZI9//qFvmrBnT03ZIu+wQ+qPQUL kb51d7c9LPCWvuEQxj3tE52+pvXVPd11o76EQOc93RSqvsYM+j3s7rC+BjsHPgMBuL7YSxI+ +0a/vgNGHj5zu8a+tTUrPrxXzr6dJTk+xRPWvoQeSD4T5t2+aiZYPvvD5b4CQGk+mqHtvvtp ez4VcvW+OE+HPgEo/b4uaZE+2VoCv6P6mz7MBga/gPimPneRCb/tVLI+A/UMv2z/vT5xLBC/ NOXJPrszE7+W8dU+GAgWv1QO4j7+pxi/eCTuPi0TG7+sHPo+t0odv+rvAj/lUB+/xasIPwYp Ib89Nw4/Vdciv0eIEz/FYCS/rpUYP8bKJb/pVh0/IxsnvyvEIT/BVyi/R9YlP4eGKb+Qhik/ Ga0qv63OLD/G0Cu/eqgvP2j2LL/NDTI/KCIuv0r4Mz9oVy+/RmE1P5KYML+AQTY/5uYxvzGR Nj8jQjO/yUc2P1WoNL8eXDU/eRU2v2vEMz/7gje/l3YxP3LnOL+2aC4/FjY6v5qRKj+oMhq+ tbn5PAV/H74SjgQ9BwslvuPXDD332Sq+AcgVPUnvML5kbR89k043vpDYKT13+z2+exs1Pbf5 RL72SUE9KE1Mvlt5Tj2m+VO+ZsFcPfoCXL6nO2w992xkvhwEfT1EO22+fpyHPU5xdr5yfZE9 JgmAvpY2nD2CEIW+3dqnPd1Pir5bfrQ9B8iPvnk2wj1meZW+uxnRPeRjm76AP+E90Iahvuy/ 8j3R4Ke+v9kCPrlvrr5eGQ0+eDC1vsIqGD4JH7y+ShkkPko2w75J7zA+BHDKvr61Pj7WxNG+ kXNNPkIs2b5kLV0+vZzgvsbkbT7WC+i+0Zd/Pmhu775CIIk+xrj2vlfqkj4v3/2+pCKdPgxr Ar9Tv6c+SskFvyi0sj5VBQm/wvK9PuYaDL+5ask+lAYPvwEK1T7sxRG/T73gPoxXFL93cOw+ NbsWv+4O+D698Ri/FcIBPwf9Gr8HXgc/598cv53RDD8Pnh6/nhMSP9k7IL9QGxc/Lr4hv5jg Gz9UKiO/1FsgP8+FJL/ThSQ/RNYlv8pXKD80ISe/E8srPw1sKL8X2S4/2rspvyZ7MT8xFSu/ KKozPxx8LL+aXjU/yvMtvzOQNj90fi+/0DU3P/McMb9JRTc/iM4yv1yzNj9VkDS/v3M1P89c Nr88eTM/QCs4vxG2MD8I7zm/qxwtP4pKGr4ybwc9Z4gfvpyXDz3LAyW+sl0YPcm/Kr4mzyE9 iL8wvuj6Kz1JBje+afE2PWGXPb5QxEI9NHZEvhiHTz0hpku+205dPZkqU76aMmw98AZbvgRL fD1qPmO+k9mGPSbUa773Q5A9Bct0vkB0mj2JJX6+I3ulPfbyg75marE95QaJvt1Uvj0RT46+ Qk7MPZbLk75Va9s9F3yZvnDB6z2vX5++Tmb9Pc10pb7rNwg+OLmrvuF5Ej7eKbK+hoMdPuPC uL6hXik+bH+/vgwUNj60Wca+JKtDPgRLzb6VKVI+t0vUvuGSYT5VU9u+s+dxPqhY4r7ekoE+ 5VHpvqSjij77NPC+YiGUPr739r5eBZ4+R5D9vtFGqD6a+gG/ANuyPgAPBb9Etb0+qwEIv1bH yD6rzwq/dQHUPt92Db/HUt8+FvYPv6Kp6j4PTRK/2vP1Pnl8FL+rjwA/74UWvwANBj/naxi/ L2kLP6YxGr/BmxA/Cdsbv6icFT+PbB2/MWQaPxbrHr8a6x4/zFsgv1gqIz8mxCG/KxsnP50p I7/etio/o5Ekv6X2LT+ZASa/lNMwP4t+J78eRjM/Og0pvy9GNT+9sSq/sco2P2pvLL+NyTc/ fEguvzI3OD/HPTC/jwY4Pw1OMr/4KDc/gHU0vw2ONT/UrDa/DCQzP2boOL9R2C8/8DIavp3I ET2xXx++PmEaPcXHJL7MmyM99m0qvgOGLT0oVTC+rS44PVqANr7cpUM9efI8vin9Tz2YrkO+ ekddPbe3Sr5xmWs90xBSvlAJez3PvFm+cteFPXm+Yb4c0o49ZhhqvlmCmD3pzHK+DPeiPRXe e77oP649u6aCvpVtuj0Wjoe+k5HHPVWljL4fvtU9WOyRvkcG5T2EYpe+ZX31Pc8Gnb6OmwM+ hdeivpEjDT5k0qi+SGAXPmj0rr7nWiI+2Tm1vtkbLj4znru+v6o6Phscwr6xDUg+bq3IvkdJ Vj5SS8++DmBlPjTu1b41UnU+743cvqQOgz74IeO+192LPnuh6b5iEpU+twPwvjCmnj4LQPa+ c5GoPnBO/L6+yrI+yBMBv/xGvT6Q4gO/sfnHPgaRBr8X1dI+Uh0Jv3rK3T5phgu/V8roPhDM Db+/xPM+0+4Pv5Sp/j4j8BG/ZbQEPyvSE79R+Qk/y5cVv94bDz+IRBe/ohQUP3vcGL+C3Bg/ LWQav5NsHT+S4Bu/Mb4hP+dWHb/MyiU/lswev9GLKT82RyC/i/osP2rMIb/vDzA/xGEjv2LE Mj+yDCW/hQ81P0zSJr/g5zY/OLcov6dCOD9Lvyq/URM5PzHtLL9vSzk/7kEvvzLaOD8cvDG/ U6w3P9lWNL8GrDU/rgg3vzXBMj+p7Rm+HOIbPesGH76o4yQ9LlkkvsSKLj0D5ym+8eQ4PQOz L768AEQ93r81vhLuTz08EDy+BL5cPdamQr4Tg2o9RoZJviRReT0ksVC+4p6EPe4pWL77L409 //Jfvh1olj1xDmi+kFSgPSV+cL4tA6s9qUN5vsuCtj0IMIG+9+LCPQLqhb7vM9A9wM+KvpCG 3j3u4I++H+ztPcgclb5mdv49G4KavoYbCD4nD6C+xp8RPqTBpb580Bs+pparvq+1Jj6eirG+ tVYyPlGZt774uT4+zL29vrPkSz6A8sO+idpZPjQxyr5enWg+JXPQvvsseD4bsda+bUOEPpDj 3L7i0ow+0gLjvuTAlT4yB+m+/wefPj7p7r5Woag+/qH0vo+Esj4fK/q++6e8Ph9//76mAMc+ 00wCv5CC0T6+uwS/3CDcPmULB7/ozeY+kDsJv8l78T7DTAu/Lxz8PjdADb9yUAM/1RcPv+N9 CD831hC/g48NP5J+Er+TfhI/nhQUv4pEFz+jnBW/DtsbP00bF7/dOyA/qpUYv8lgJD8hERq/ i0MoP1STG7+53Ss/JyIdv3koLz+cwx6/UBwyP9V9IL/8sDQ/8VYiv/3cNj/sVCS/SZU4P1J9 Jr/kzDk/DdUov3Z0Oj/PXyu/rnk6P1cfLr/Qxjk/TRIxv2dCOD/mMjS/9s41P5h8Gb5jtSU9 MoAevn4YLz1luiO+/yM5PY0tKb4k5UM9+tsuvl1qTz0ayDS+D8NbPUr0Or4AAGk93GJBvgcz dz0pFki+vDeDPV8QT77sZIs9mVNWvjQslD3H4V2+JZmdPaS8Zb5UuKc9muVtvueWsj3GXXa+ s0K+Pdklf74xyso9BR+EvnM82D360oi+6KjmPU6ujb6DH/Y9HLCSviNYAz4S15e+kTUMPmoh nb7prxU+3YyivpHOHz6dFqi+xJgqPj67rb7EFDY+03azvhhIQj7JRLm+JjdPPgIgv77d5Fw+ 7ALFvp5Saz5x58q+8X96PiXH0L4iNYU+X5vWvmSGjT5SXdy+KDCWPksG4r6KLZ8+zo/nvnl4 qD6w8+y+lQmyPoYs8r5r2Ls+ezX3vmHbxT6/Cvy+/AfQPsFUAL/yUto+EogCv2ew5D4enwS/ BRTvPk+aBr9fcfk+vnoIv9jdAT8aQgq/RfMGP7jyC7+88gs/fo8NvzvWED/cGw+/zpcVP7+b EL+qMRo/lxMSvxGeHj9FiBO/V9ciPwz/FL+v1yY/lH0WvxGZKj/oCRi/FBUuP22qGb+5RDE/ 22Ubvw8gND82Qx2/AZ42P8pJH7/Gszg/6IAhv4xUOj/T7yO/sXA7Pz+dJr869Ts/u44pv+LK Oz+hxyy/SdU6P3hHML8r8jg/teEYvuo8Lz20zR2+Dvo4PdztIr61YUM9SUQovuWATj0T0y2+ vmVaPVecM74/H2c9L6I5vp29dD2r5j++BqmBPbxrRr6id4k9QzNNvm3UkT0FP1S++cmaPYmQ W75XY6Q9KCljvmisrj30CWu+aLG5PaIzc75cf8U9gqZ7vrsj0j09MYK+YKzfPWmzhr6UJ+49 HFmLvsqj/T1dIZC+wxcHPsoKlb6Z7A8+kxOavmJXGT56OZ++yV4jPsh5pL4HCS4+SdGpvqhb OT5APK++TVtFPnm2tL68C1I+Uju6vlZvXz6mxb++C4dtPgZQxb5MUnw+ttTKvkPnhT6+TdC+ rvuNPie11b4dY5Y+/gTbvkEZnz6JN+C+sxioPm1H5b74WrE+0i/qvqfYuj6A7O6+U4nEPh56 877iY84+Hdb3vmhe2D4L//u+gG7iPnb0/75ziew+j9sBvyuk9j5rpAO/zFkAP0lWBb9KVgU/ PPMGvx1CCj/cfQi/2xcPP0z5Cb8x0hM/K2kLv+xrGD+a0Qy/698cPzk3Dr8JKSE/FJ8PvwpC JT/MDhG/hiUpP2SMEr+mzSw/eh4UvxM0MD8yzBW/n1EzP06dF7/dHTY/IZoZv+SOOD+nyxu/ iJg6P1s7Hr/YKzw/D/Mgvxw2PT+D/CO/up89P45gJ7/gSj0/uiUrv+wRPD8aHxi+5nM4Pbzx HL5wg0I9DfYhvgA/TT31LSe+XLNYPUSbLL4R7mQ93T8yvsP9cT2XHTi+HPJ/PS82Pr7sbYc9 T4tEvkxmjz2KHku+rOuXPUjxUb73B6E9wARZvrnFqj35WWC+JjC1PaLxZ76oUsA9IcxvvmY5 zD1z6Xe+2PDYPZckgL7WheY9KnWEvmkF9T2z5Yi+Yj4CPhx1jb6OfAo+/CGSvqNDEz6A6pa+ 7pkcPnLMm75RhSY+OsWgvkULMT7F0aW+mjA8PqDuqr5i+Uc+3hewvqxoVD46SbW+eoBhPhJ+ ur5yQW8+arG/vteqfT4i3sS+H12GPt7+yb7ONY4+VQ7Pvo1clj4uB9S+g82ePmDk2L7ag6c+ IaHdvut5sD4kOeK+Lqm5Pq+o5r5ICsM+s+zqvjiVzD7jAu++aEHWPuLp8r65BeA+NaH2vrPY 6T5sKfq+tbDzPv+D/b4EhP0+x1kAv26kAz/R3QG/wHoIP2xQA785QA0/YbQEvyjwET/8DAa/ 64UWPwVeB78N/Ro/v6sIv+hQHz/++gm/+HwjPxRRC793fCc/7rMMv1xKKz8dKg6/GuEuP/C6 D79sOjI/im4Rvx5PNT8GThO/VBY4P4djFb9jhTo/cLoXv7mOPD9bXxq/FSE+PwxgHb8QJj8/ K8sgv2OAPz9MryS/egk/P9Y2F77+VUE9lu4bvm2wSz2E1SC+s7dWPU/tJb44eGI9mDcrvkD/ bj3/tTC+3Vp8PRNqNr4UTYU9VVU8vpjmjD0heUK+XAKVPcXWSL6AqZ09Xm9Pvlnlpj3UQ1a+ 5b+wPdRUXb6QQ7s9z6Jkvi57xj3WLWy+7XHSPaj1c75mM989iPl7vmzL7D0pHIK+70X7PSdY hr55VwU+mq+Kvi+JDT4JIY++6j0WPqqqk75Gex8+WUqYvnRGKT6L/Zy+TaQzPmPBob4LmT4+ lpKmvhooSj6Ibau+GlRWPkROsL6tHmM+hTC1vkGIcD7WD7q++Y9+Pnznvr7TmYY+urLDvsE3 jj61bMi+JR+WPrQQzb6RTJ4+JprRvsa7pj7KBNa+v2evPrhM2r7DSrg+kW7evmNewT6JZ+K+ mpvKPoc15r7e+tM+JNfpvjV03T7aS+2+cf/mPvyT8L7/k/A+tLDzvnYp+j4jpPa+lNsBP0xx +b5SmgY/Jxz8vsZMCz+Kqf6+1+4PP6WPAL98fBQ/EcIBv8PxGD/m7wK/vUodP4kdBL+DgyE/ 6U8FvweYJT+djAa/EYQpP+vZB78QQy0/9T4Jv9zPMD/cwwq/biQ0P+hxDL+wOTc/5lMOv64G Oj9DdhC/JIA8P6XnEr9Nlz4//rgVv6g4QD8R/hi/uklBP1PNHL9ZpkE/FisWvs/fST2Vxhq+ f31UPciOH75YyF89IoUkvk7Maz0Tqym+PZZ4PfoBL77VGYM9Los0vpdZij3wRzq+9RGSPVs5 QL4HS5o9dmBGvmYNoz0Zvky+8mGsPedSU74FUrY9SR9avmXnwD1hI2G+LyzMPQdfaL7OKtg9 ttFvvuTt5D2Fene+WIDyPRJYf76QdgA+RbSDvoofCD7A1Ie+iUAQPgIMjL7B3hg+RliQvir/ IT5st5S+e6YrPgwnmb7n2DU+ZaSdvgWaQD5lLKK+8uxLPqa7pr7S01c+g06rvulPZD4W4a++ jmFxPjZvtL7IB38+pfS4vk6ghj4Ibb2+RgSOPv3Twb5wrZU+QSXGvrOYnT6qXMq+VsKlPlx2 zr7pJa4+xm7Svl++tj7MQta+Eoa/PtPv2b7Vdsg+z3PdvhaK0T5nzeC+4LjaPun74770++M+ ZP/mvuJL7T6v2Om+OqH2PmmJ7L6A9P8+AhTvviGfBD+7e/G+kzsJP7XE874PzA0/zfP1vhRN Ej/kDvi+PbsWP6Ec+r4uExs/wiT8vqtRHz8HMP6+WnMjPzgkAL/TdCc/ujwBv3dSKz8baAK/ TAgvP/GtA7+7kTI/JRcFv13pNT8+rga/eAg5P9F/CL975js/F5sKvxp4Pj+yEg2//a1AP4j9 D7/ackI/33cTv2SoQz/3/RS+MQ5SPRF8Gb7L51w9YiQevituaD0t+CK+Aq10Pan4J75Z2IA9 CyctvhLDhz1qhDK+sh2PPcYROL5h75Y9C9A9vu4/nz3wv0O+SBeoPSDiSb4CfrE97zZQvsN8 uz2Tvla+xhzGPep4Xb5bZ9E9lmVkvitm3T3ig2u+JiPqPazScr4xqPc9b1B6vqn/Aj6V/YC+ MJkKPj3ohL6YpRI+ruaIvpApGz4h94y+iikkPo8Xkb6cqS0+o0WVvpetNz69fpm+mzhCPvK/ nb48TU0+IAaivl7tWD7XTaa+9BllPn2Tqr4v03E+RNOuviQYfz44CbO+bXOGPmgxt74bno0+ z0e7vvMJlT5+SL++NLScPq8vw76OmaQ+y/nGvg22rD6Ho8q+QgW1PvYpzr4xgr0+pIrRvl4n xj6Kw9S+G+/OPjfT175A09c+17javmjN4D4udN2+I9fpPrAF4L7l6fI+eW7ivgz/+z5asOS+ F4gCP+LN5r5oCwc/TMrovmyGCz+Sqeq+F/YPP29w7L6OVxQ/byTuvgCoGD/zy+++s+QcP1du 8b7yCiE/CxTzviMYJT/MxvS+fgkpP8uR9r4h3Cw/TYL4vtiMMD/dp/q+5xc0P0YV/b7VeDc/ UeH/vu2pOj87lAG/n6M9Pz6HA7+iW0A/s+AFv0/DQj+ovgi/QcVEP6KxE77g3lk9XREYvv3s ZD3YmBy+LqdwPSdJIb6QGH09UyMmvoImhT1fKCu+hyiMPSlZML70mJM9grY1vrR+mz0TQTu+ B+GjPWn5QL6Rx6w95N9Gvkk6tj2x9Ey+VEHAPcM3U7455co9x6hZvsgu1j0wR2C+yibiPQwS Z75w1u49HghuvtdG/D2/J3W+ikAFPtxufL4Vxww+d+2Bvmm7FD6DtIW+yCEdPs+Kib4h/iU+ XG6NvilULz7wXJG+GSc5PgdUlb60eUM+5FCZvjJOTj6HUJ2+K6ZZPsNPob5cgmU+OkulvtTi cT5nP6m+oMZ+PqIorb7yFYY+PwOxvuYHjT6Ny7S+KzeUPu19uL5coZs+0Ra8vnNDoz7nkr++ 8BmrPiXvwr7cILM+rSjGvt1Tuz4ePcm+Eq7DPm0qzL52Ksw+He/OvpHD1D4WitG+0XPdPtL6 076PNeY+Y0HWvuYC7z5aXti+INb3PuhS2r7DVAA/0SDcvsK7BD9xyt2+Ux0JP75S377gdg0/ SL3gvu7FET9LDuK+GwgWP6FK474lOxo/CnjkvvBcHj/0nOW+YmsiP+jA5r6DZCY/mOznvk5G Kj85Kum+rg4uP/+F6r5iuzE/gg7svtBJNT/j1e2+1bY4P8/y775p/js/gYLyvhkbPz+Jq/W+ BQVCPxei+b6PsEQ/QEgSvuVPYT3JiBa+eItsPafuGr7AcXg9wHofvseGgj3zLSS+JzWJPQsJ Kb7mSZA9wAwuvlLLlz2qOTO+BsCfPUKQOL7hLqg95RA+vggfsT25u0O+15e6PbiQSb4wocQ9 oo9Pvs9Czz0EuFW+5oTaPRYJXL6qb+Y9wYFivnEL8z2qIGm+SDAAPgjkb76sOwc+usl2vvmr Dj46z32+IIUWPr54gr7tyh4+kRaGvtuAJz4jv4m+NKowPklwjb7NSTo+nSeRvhliRD6C4pS+ 4vROPiuemL6LA1o+k1ecvpOOZT6TC6C++ZVxPuK2o77HGH4+GFanvpWKhT7I5aq+RUSMPoZi rr6wN5M+4sixvpFimj6bFbW+O8KhPoJFuL6OU6k+pVW7vvsSsT5XQ76+mvy4PiUMwb4pDME+ EK7DviE9yT5eJ8a+qorRPtN2yL7V79k+kpvKvo5n4j43lcy+sOzqPtdjzr4hevM+9AfQvsQK /D6FgtG+00wCPw7V0r4GkQY/bAHUvq3PCj/6CdW+mAYPP4Px1b69MxM/W7vWvjRVFz8/a9e+ OmkbP4cF2L4vbh8/I4/YvoZiIz+4Ddm+40QnP9yH2b7vEys/OgXavmvOLj8Aj9q+E3MyP2gw 276UADY/bffbvmN1OT8P9ty+nc88P0pE3r63DEA/4wLgvvQoQz/rwxC+FmBoPZ7kFL4DwnM9 QigZvhHNfz2Xjx2+vUWGPVYbIr4VBI09F8wmvjInlD1goiu+E7WbPaueML7ns6M9PcE1viwq rD08Cju+qB61Pad5QL5EmL49Sw9GvjeeyD3Dyku+zDfTPWCrUb6QbN49P7BXvgpE6j0v2F2+ 5MX2PachZL7j/AE+2IpqvpXzCD6JEXG+wEoQPiizd77sBRg+vmx+vngoID53nYK+irUoPvUM hr71rzE+xIKJvkMaOz6W/Iy+f/ZEPup3kL4+Rk8+GvKTvpAKWj5KaJe+30NlPobXmr798XA+ rzyevugTfT6blKG+AtSEPg7cpL7oVYs+yg+ovvsNkj6gLKu+N/qYPmovrr4pGKA+JxWxvgJl pz732rO+jt2uPkN+tr5EfrY+lvy4vmBDvj7TU7u+ryjGPiWCvb77Kc4+DIa/vslC1j5hXsG+ mm7ePkQKw76yqOY+T4nEvoTs7j5a28W+fzX3PpsAx74tf/8+pvnHvpLiAz9Ox8i+rgEIP61q yb7pGgw/L+XJvnAsED9pOMq+jDQUPy9myr6sMRg/k3DKvlgiHD+3Wcq+UwUgPwQkyr532SM/ /NHJvr2dJz9RZsm+S1ErP+rjyL5p8y4/803IvoSDMj/sp8e+EgE2P931xr61azk/gjzGviLD PD+9gcW+HAdAP7wmD75ZDm89FycTvgiQej0QSBe+XVyDPT+KG74hyYk9Mu4fvneTkD1kdCS+ z8CXPS0dKb64Vp891+gtviJbpz2A1zK+JNSvPSfpN77+x7g9oB09vkY9wj2UdEK+nzrMPWnt R77LxtY9XIdNvr7o4T1jQVO+hKftPScaWb79Cfo9IxBfvo2LAz5VIWW+4moKPotLa75RphE+ LYxxvv9AGT5K4He+9j0hPotEfr7znyk+oVqCvoppMj4wl4W+zJw7Pr/ViL6LO0U+6BOMvhlH Tz4jT4++ScBZPrmEkr5pp2Q+2rGVviL8bz6b05i+br17Pvfmm77k9IM+4+ievmA/ij5L1qG+ pryQPiKspL7Uapc+bGenvrdHnj5ABaq+rVClPtOCrL7Xgqw+jd2uvv3asz72ErG+rVW7Ptog s74k78I+OgW1voijyj5cvra+x27SPsBKuL64TNo+KKm5viQ54j6d2Lq+1S/qPmPYu76KLPI+ 76e8vh8r+j7xRr2+zBMBPzm1vb7+DgU/tfK9vlYFCT9n/72+B/UMP0Lbvb5o3BA/OYa9vuS5 FD8OAL2+EYwYPzhIvL6QURw/0F27vi0JID9dP7q+uLEjP5bquL4VSic/F1y3vkjRKj/2jrW+ OEYuPxp8s77LpzE/SRmxvrX0ND+/V66+Yys4P8khq76YSTs/uHINvmtadT1lUhG+qHqAPWVQ Fb5lmoY9NW0ZviIRjT07qR2+suOTPcsEIr4/F5s9IIAmvhmxoj1QGyu+zLaqPWLWL74LLrM9 KrE0vr0cvD1Tqzm+6IjFPWHEPr7HeM89oftDvqHy2T0xUEm+2vzkPd3ATr7NnfA9SkxUvtzb /D3B8Fm+rt4EPlasX75ApAs+tXxlvpfBEj5KX2u+lzkaPjRRcb7lDiI+HU93vupDKj55VX2+ 39oyPiywgb6s1Ts+t7WEvsQ1RT4UuYe+MfxOPtm3ir6lKVk+b6+Nvjy+Yz4mnZC+krluPjd+ k76NGno+x0+Wvtbvgj7sDpm+TQOJPri4m75FRo8+PUqevv22lT6ewKC+YFOcPgEZo74GGaM+ rFClvkMFqj4BZae+KBWxPoZTqb6GRbg+6hmrvvCSvz4Ltqy+zfnGPuUlrr5hds4+umevvsUE 1j7kebC+J6HdPvJasb5xR+U+kAmyvrnz7D6JhLK+AKL0PrXKsr5qTvw+89qyvp36AT8etLK+ SskFP+JUsr55kQk/wruxvmVRDT/g5rC+WQcRP+zTr76osRQ/5n+uvqpOGD/w5qy+sdwbP+8D q74AWh8/JNCovrPEIj+pQqa+pxomP4pPo75dWSk/q+afvpt9LD8J8pu+M4MvPypTl740ZDI/ 996RvtgXNT/oqQu+QUR7PadoD74SeYM9hkMTvvKgiT3dOhe+KR6QPfZOG75f9ZY9/H8fvmYr nj0MziO+ScWlPSE5KL4xyK09EsEsvoU5tj2YZTG+th6/PT4mNr5lfcg9ZgI7vlZb0j1E+T++ Ur7cPc4JRb4zrOc9zTJKvskq8z3Ack+++T//PeTHVL6y+AU+SzBavlCiDD6OqV++i58TPiUx Zb7c8ho+K8Rqvq6eIj5kX3C+J6UqPlX/db4bCDM+JaB7vi3JOz7anoC+jOlEPs5pg74vak4+ my6GvnZLWD7E6oi+UY1iPsCbi75PL20+4T6OvlwweD5r0ZC+cMeBPphQk75WpIc+lLmVvoOt jT6QCZi+TeGTPrw9mr7BPZo+WlOcvqDAoD6yR56+bmenPicYoL5rL64+M8KhvqAVtT5uQ6O+ 1ha8PomZpL6zL8M+UcKlvqtcyj7Bu6a+K5rRPtKDp75i5Ng+qRiovog34D5weKi+0Y/nPk6h qL5F6e4+apGovhBA9j7MRqi+SZD9Pkm/p74LawI/d/imvtAGBj+H76W+b5kJPxqhpL72IA0/ FwmjvkybED9yIqG+RQYUP8nmnr6HXxc/KE6cvl6kGj9OTpm+vdEdPxvalb7i4yA/iOCRvh/W Iz9CS42+PqImP7b8h77ePyk/SM2Bvi+jKz9DDnW+0LotPzvOCb4TZoA98msNvpNDhj2kIxG+ c3CMPYz1FL7g8JI91+EYvlrJmT2S6By+Tv6gPbgJIb6UlKg9JEUlvuuQsD2Smim+afi4PZwJ Lr4b0ME9rJEyvkIdyz0MMje+I+XUPdjpO74VLd8977dAvnX66T0Bm0W+nFL1PXyRSr5inQA+ mJlPvhHcBj5PsVS+1WcNPk3WWb4ZQxQ++QVfvhZwGz59PWS+3vAiPrJ5ab5gxyo+JLduvgz1 Mj4d8nO+aXs7PqUmeb5WW0Q+d1B+vpCVTT6JtYG+YypXPuA4hL6IGWE+za+GvnRiaz66F4m+ BQR2Pgpui75UfoA+FLCNvhwlhj4g24++AvWLPnLskb547JE+SuGTvpIJmD75tpW+QEqePtJq l74krKQ+NfqYvqQsqz6MYpq+48ixPlihm77qfbg+MbScvoFIvz6vmJ2+QSXGPoxMnr63EM0+ es2evjMH1D47GZ++/wTbPoMtn75RBuI++Aefvi8H6T4npp6+uAPwPlUFnr7B9/Y+nSKdvi7f /T6X+pu+11oCP2+Jmr5iuwU/j8qYvs8OCT96uJa+lVIMP5pMlL7egw8/yX6RvmWfEj8CRY6+ dKEVP8iSir6EhRg/bliGvvxFGz8kgoG+r9sdP2ztd74uPSA/xCtrvs5dIj8tbFy+zCskP1ZD S77ljSU/lOEHvnn5gj1DXgu+o9qIPdzyDr6DCY89gZ8Svh2KlT0+ZBa+jGCcPQhBGr4xkaM9 vTUevlkgqz0bQiK+oRKzPcJlJr6obLs9MKAqvjEzxD2/8C6+CGvNPZdWM74bGdc9vNA3vjpC 4T0EXjy+XOvrPQP9QL5JGfc9IqxFvmhoAT6PaUq+UIsHPjQzT76P9w0+xAZUvkOvFD6r4Vi+ bLQbPhvBXb7cCCM+8qFivh6uKj7YgGe+oKUyPjdabL5u8Do+LipxvmKPQz6h7HW+6oJMPjWd er4Xy1U+Yzd/vq5nXz4024G+6FdpPrAKhL6SmnM+mSeGviEufj5iL4i+NIiEPmQfir5lH4o+ /vSLviHbjz6ArY2+l7mVPkNGj765uJs+obyQvkvWoT71DZK+yw+oPqg3k76DYq4+KTeUvpLL tD7tCZW+z0e7Pmqtlb4F1ME+IB+Wvq9syD6LXJa+XA7PPhZjlr4ntdU+HzCWvk9d3D7dwJW+ 1wLjPlsSlb5+oek+WyGUvv808D5O6pK+xLj2PiZpkb4EKP0+O5mPvsm+AT8hdY2+3dkEP3f2 ir4h4gc/mxWIvg7UCj9gyYS+f6sNP7YGgb6SYxA/M4B5vlT2Ej8Kym++TVwVP2rCZL4VjBc/ ZDdYvlZ5GT+z60m+qxMbP06UOb7XRBw/l9Ymvi3uHD/E5QW+y1yFPYdBCb7wPos9OLMMvgNt kT3cOhC+0eqXPWrYE75QvJ49u4sXvmjlpT2TVBu+T2qtPZcyH748T7U9UyUjvnKYvT0pLCe+ a0rGPVtGK76Qac89B3Mvvlb62D0TsTO+PQHjPUP/N760gu09JFw8vhWD+D0SxkC+ZAMCPjc7 Rb7pCAg+c7lJvilUDj5+Pk6+8OYUPsfHUr4Pwxs+hlJXvvTpIj6021u+Gl0qPgZgYL6aHTI+ /9tkvk0sOj7WS2m+2YlCPpurbb55Nks+E/dxviIyVD7aKXa+Z3xdPmQ/er5vFGc+9DJ+vvr4 cD7T/4C+YSh7PkDQgr5D0II+MYiEvmYviD4VJYa+GLCNPlKkh76aUJM+SAOJvvAOmT5aP4q+ 5uiePuFVi74S3KQ+QkSMvsrlqj7fB42+QwOxPhSejb5rMbc+QQSOvghtvT67N46+uLLDPsw1 jr7o/sk+pvuNvsFN0D5eho2+XJvWPtzSjL6T49w+0d2Lvv4h4z6do4q+6lHpPj4gib5rbu8+ L0+HvhJy9T5PK4W+CVf7Prmugr5kiwA/CqV/vv5UAz9WHXm+/AMGP1Wzcb57kwg/iFBpvor9 Cj862l++6DoNP6gwVb6WQg8/Ki5Jvl4JET9Kpju+r4ASPyZlLL7ElRM/YS8bvtcvFD+pwwe+ Bi4UP5DcA760kIc9mhcHvjpxjT2oZgq+5ZuTPavJDb4vFJo9gEARvs7doD3oyhS+iPynPZNo GL4udK89EBkcvqNItz3R2x++BH6/PSiwI75RGMg9RpUnvp8b0T0qiiu++IvaPbyNL76FbeQ9 pp4zvk7E7j1xuze+PZT5PWziO76VcAI+uxFAvmlXCD4+R0S+XoAOPrWASL4O7RQ+jrtMvgKf Gz4U9VC+ipciPkIqVb7L1yk+71dZvrRgMT6qel2+5jI5PsqOYb7XTkE+g5Blvpa0ST67e2m+ 7WNSPjZMbb5VXFs+kf1wvs2cZD41i3S+HCRuPmvwd75w8Hc+Wyh7vtb/gD4ZLn6+nSeGPlJ+ gL4Mbos+bMeBvm3RkD7P74K+yk+WPt30g7765ps+/dOEvp2UoT6QioW+HVanPuwVhr6lKK0+ aHOGvjgJsz5JoIa+pPS4Ps6Zhr56574+Gl2GvinexD4954W+tdTKPhk1hb4qx9A+aEOEvhix 1j6dDoO+943cPtiSgb6iWOI+wJd/vuAL6D7raXu+j6HtPniRdr5RE/M+VgJxvqxZ+D6drmq+ Omz9PlmGY76vIAE/EXdbvstmAz+Ia1K+tIEFPyhLSL4iaQc/wvk8vg8TCT88VzC++3IKP6Y/ Ir4veQs/2IsSvsARDD83EwG+gCMMP7Fe270bjgs/p8cBvvmViT1E4gS+h3KPPQwPCL4xl5U9 5E0LvnIHnD2Jng6+mMaiPbQAEr4w2Kk993MVvtc/sT3Q9xi+JQG5PaKLHL7NH8E9py4gvo6f yT0B4CO+KYTSPameJ75Z0ds9bGkrvsGK5T3wPi++H7TvPbcdM77tUPo9BwQ3vlSyAj787zq+ RXkIPojfPr7dfg4+W9BCvnzEFD71v0a+cEsbPqSrSr7bFCI+gpBOvqUhKT5ra1K+iXIwPgw5 Vr4JCDg+3vVZvkziPz4gnl2+YwFIPuwtYb7OZFA+KqFkvvMLWT6P82e+t/VhPrkga763IGs+ FiRuvjSLdD70+HC++DJ+Po6ac76wCoQ+AAR2vr0XiT5aMHi+5T6OPoEaer44fpM+ab17vp7T mD7jE32+szyePrkYfr7itqM+lsZ+vmQ/qT4ZGH++R9OuPsYHf745b7Q+8o9+vtMPuj7Mqn2+ bLG/Pj5SfL4HUMU+3X96vnXnyj7wLHi+KnPQPihSdb447tU+nedxvlNT2z675G2+u5zgPu4/ ab76w+U+p+5jvuXB6j4L5V2+Yo7vPsUVV75SIPQ+4HFPvu5s+D536Ea+tGf8PpZmPb76AAA/ JdcyvvGUAT/pIie+EOUCP9gwGr5I5AM/1+YLvqCCBD+uVvi9a6wEPwjQ1b2BSQQ/8BywvUY8 Az9GUf+9gm2LPTCjAr7BQ5E9Ka4Fvi5glz1ayQi+88WdPXb0C74veKQ9HS8PvjR6qz3SeBK+ Q8+yPQPRFb7Pero9/TYZvjGAwj3zqRy+2eLKPfQoIL4xptM97LIjvqLN3D2fRie+e1zmPavi Kr4NVvA9h4Uuvna9+j17LTK+58oCPqPYNb76cAg+64Q5vkpSDj4OMD2+CXAUPpbXQL5Vyxo+ 3HhEvhRlIT4LEUi+ED4oPgydS761Vi8+rxlPvnOvNj6Ag1K+Q0g+Pt/WVb7uIEY+BhBZvvY4 Tj75Kly+nY9WPp8jX76hI18+tPVhvpnzZz7MnGS+kP1wPmUUZ75nP3o+3ldpvjfbgT5vYmu+ 0a+GPkovbb7Em4s+grluviidkD4X/G++4bGVPvfxcL6G15o+7pVxvpILoD7J4nG+O0ulPiXT cb5/k6o+g2Fxvhfhrz42iHC+hTC1PmpBb74Ofro+AYdtvqXFvz6OUmu+8ALFPkydaL4uMco+ /F9lvlRLzz7RkmG+u0vUPlQtXb5ELNk+WSZYvhDm3T7Ec1K+jHHiPoAKTL4RxuY+W95EvrjZ 6j7y4Ty+RKHuPpgGNL51D/I+dDwqvs4U9T6Vch++JZ/3PmaXE76gmPk+VZkGvmLn+j4v0PC9 UWz7Pmrt0b1+Avs+MH2wvd99+T6jiIy9C6v2Pi0C+71KGI09/1sAviXmkj2tRQO+J/iYPdQ9 Br4rUZ89F0QJvjr0pT0HWAy+UuSsPRl5D76LJLQ9rKYSvvy3uz3+3xW+waHDPTMkGb755Ms9 UXIcvsiE1D02yR++QoTdPaInI75Y5uY9LYwmvv+t8D1B9Sm+Dt76PS9hLb6YvAI+D84wvvNA CD7ROTS+Qf0NPjeiN76C8hM+1AQ7vqMhGj4UXz6+YIsgPiauQb5CMCc+He9EvqcQLj7EHki+ wCw1PtY5S75ahDw+zTxOvjQXRD77I1G+juRLPo3rU76R61M+mY9WvvoqXD7sC1m+KqFkPk5c W747TG0+YHxdvt8pdj6kZ1++bjd/Pn8ZYb7gOIQ+S41ivsbqiD40vmO+c6+NPmSnZL68hJI+ 10Nlvkxolz6PjmW+llecPlWCZb7HT6E+7hllvtpNpj7gT2S+iE6rPqceY75CTrA+dYBhvj1J tT5Eb1++UTu6Ps/kXL4FIL8+edpZvoLywz43SVa+bq3IPo0pUr4BS80+g3NNvtPE0T51Hki+ whPWPichQr7HL9o+nXE7vvMP3j4nBTS+CKrhPmHQK75V8uQ+Oscivljb5z5K3Ri+gVXqPgwG Dr6OTuw+kTUCvkax7T7Xwuq94GTuPkYEz71bTO4+tyqxvUJG7T69QZG9KSzrPrTaXr0a0+c+ 7KT2vWyXjj18HPy96lqUPTHXAL5rYJo996wDvrGqoD0mjwa+djynPT19Cb6IGK49qHYMvsNB tT20eg++/bq8PZSIEr4Ih8Q9ZJ8VvsCozD0dvhi+ACPVPZfjG75++N09jQ4fvu4r5z2OPSK+ 6L/wPQtvJb7ztvo9SaEovqyJAj5o0iu+n+sHPl8AL75agg0+9CgyvqROEz7LSTW+QVEZPldg OL7Dih8+5Wk7vob7JT6FYz6+yKMsPjZKQb5wgzM+uhpEvlqaOj6q0Ua++OdBPoFrSb6Ea0k+ kORLvvwjUT72OE6+AhBZPs1kUL7sLWE+62NSvsB7aT4hMlS+FPdxPhPLVb46nXo+WCpXvo+1 gT5pS1i+nS6GPqApWb7at4o+R8BZviFPjz6HClq+HPKTPn4DWr4snpg+H6ZZvolQnT5S7Vi+ IAaiPsTTV76nu6Y+FVRWvottqz6maFS+3xewPq4LUr56trQ+GjdPvsVEuT6j5Eu+0r29PqIN SL4ZHMI+GKtDvrBZxj6rtT6+A3DKPpIlOb69V84+lfIyvqkI0j4aFCy+r3nVPi2BJL5hoNg+ kTAcvgFx2z4MGRO+N97dPp0xCb6g2N8+I+T8vapO4T5up+W9LCziPtakzL0iWuI+GNyxvXS+ 4T4rWZW9ozvgPoZybr1Rsd0+KGMvva/82T5LPPK9FOyPPbR2971Xo5U9asj8vXyamz1UGAG+ GNShPT/XA76oUqg9aqAGvtMYrz0wcwm+Gim2PdlODL4uhr09jTIPvqMyxT1cHRK+CzHNPTwO Fb7lg9U9/AMYvrQt3j1Q/Rq+1TDnPcj4Hb6sj/A90/Qgvj5M+j277yO+UDQCPp/nJr5dcwc+ ftopvgvkDD4txiy+EIcSPlSoL771XBg+fX4yvilmHj75RTW+6aIkPgX8N742Eys+np06vu62 MT6uJz2+uI04PuyWP77wlj8+8edBvqbRRj4rF0S+zTxOPukgRr7h1lU+WwFIviGeXT6OtEm+ g5BlPnU2S76gq20+44JMvqXsdT6SlU2+f1B+PihqTr7PaYM+KvxOvhi5hz4UR0++6BOMPjZG T77qd5A+3fROvoTilD4sTk6+4lCZPjdNTb7zv50+6uxLvmMsoj4QKEq+l5KmPlz5R76e7qo+ P1tFvj88rz4USEK+03azPu65Pr5Lmbc+sKo6vi2euz78Eza+aH+/Pj/vML5INsM+ojUrvna7 xj4m4CS+rgbKPqXnHb7LDs0+/UQWvoTJzz4v8Q2+RyvSPrblBL4lJ9Q+vDn2vVCu1T61JOG9 PrDWPg6Iyr1jGtc+9GWyvdjX1j6hyZi9oNHVPhuWe72j7tM+DiZDvTUU0T46wAi92ibNPvLK 7b13F5E9ZMnyvcjAlj1K3Pe94KecPcAC/b0Nz6I95B0BvrU4qT0VwwO+LuevPUxwBr7c3LY9 viQJvgocvj2T3wu+LqfFPdCfDr6cgM09ZGQRvo+q1T0bLBS+LyfePan1Fr6u+OY9mr8ZvgMh 8D1ciBy+BaL5PUROH768vgE+bg8ivnbaBj7pySS+0yQMPop7J75dnhE+ESIqvoJHFz4Ouyy+ gCAdPvFDL751KSM+/Lkxvj5iKT5VGjS+k8ovPvZhNr73YTY+uo04vrInPT5Tmjq+vxpEPlmE PL7ROUs+OUg+voGDUj5O4j++3/VZPtFOQb7SjmE+1YlCvt5LaT5dj0O+LipxPlJbRL6gJnk+ i+lEvtmegD66NUW+uLWEPoI7Rb7B1Yg+ePZEvpb8jD4NYkS+oCeRPqt5Q74IVJU+lDhCvsJ+ mT7+mUC+aKSdPgOZPr5kwaE+lTA8vsHRpT6UWzm+R9GpPr4UNr48u60+rFYyvp2KsT7XGy6+ 2zm1PpteKb7awrg+PRkkvggfvD76RR6+/0a/PgjfF76RMsI+y94QvtHYxD7oPwm+tS/HPpL9 AL4ULMk+eSfwvYXByj5f/9y9SeLLPumAyL0Qf8w+aq+yvQiHzD4llZu9t+fLPtRFg71ajco+ xsJTve9iyD5+Lh+9+VLFPtGm0rxVSME+W1Ppvc8akj0iF+69srSXPans8r0mip0999L3vVid oz36yPy9b/CpPbfmAL6hhbA9c28Dvhhftz3n/QW+6n6+PS+RCL5W58U9SygLvliazT0lwg2+ /JnVPYtdEL5C6N09K/kSvumG5j2YkxW+tXfvPT4rGL5NvPg9b74avhMrAT5eSx2+MyMGPhTQ H74ORws+fkoivhqXED5iuCS+ixMWPmUXJ76LvBs+BWUpvguSIT6fniu+zZMnPnDBLb5zwS0+ kMovvlUaND7ytjG+o506PmuDM743SkE+tyw1vsseSD5srza+tBlPPgQIOL4JOVY+4TI5vqd6 XT5KLDq+AtxkPmrwOr42Wmw+XXs7viPycz4jyTu+KqB7PqXVO74wsIE+wZw7vjOXhT4/Gju+ xYKJPsxJOr5KcI0+DSc5vu5ckT6TrTe+o0WVPtfYNb4MJ5k+SaQzvo39nD49CzG+PMWgPvwI Lr7IeaQ+vZgqvpkWqD6ltSa+p5arPtxaIr5q9K4+gIMdvt0psj64Khi+ejC1PtNLEr7+ALg+ S+ILvoKTuj736QS+V9+8PmG++r3V2r4+PH7qvXp7wD4CENm9mrXBPjFzxr2UfMI+f6uyvX3C wj4lwp29VXjCPmnHh70pjsE+g6lhvSbzvz7BHTK9H5a9Ph9QAb0fZro+8ImfvD9Ttj7l1+S9 h/eSPVti6b12gJg9BfztvdxCnj3fo/K9lUCkPblY973Ie6o9RRn8vUX2sD0FcgC+K7K3PbTb Ar5Nsb49xUgFvqr1xT02uAe+DoHNPe8oCr5HVdU9upkMvhR03T1ICQ+++t7lPSp2Eb6Il+49 1N4TvgKf9z2fQRa+WnsAPsOcGL69TwU+Uu4avhNNCj5KNB2+sXMPPnlsH76lwxQ+nZQhvv48 Gj5EqiO+fd8fPuKqJb7oqiU+zpMnvqSeKz44Yim+/rkxPjETK74H/Dc+vKMsvodjPj6oEC6+ Iu9EPrNWL74TnUs+inIwvmtrUj6uYDG+7FdZPpQdMr4JYGA+mKUyvtiAZz4H9TK+JbduPhUI M75V/3U+4Noyvn1VfT59aTK+olqCPvOvMb7zDIY+MKowviW/iT4iVC++Xm6NPpypLb6NF5E+ dKYrvm+3lD5sRim+WkqYPkiFJr5zzJs+wF4jvnw5nz6Ozh++2YyiPnTQG76lwaU+QGAXvmHS qD7aeRK+N7mrPlQZDb6zb64+ADsHvuzusD6P2wC+Ki+zPmbw870qKLU+rB3lvdjQtj6yPNW9 Vx+4Pt1NxL3oCLk+0FSyvQqCuT6lWZ+9Tn65Pvxpi72f8Lg+oDRtvU7Ltz4TD0K9XQC2Pkux Fb3hgbM+uADRvMJCsD5w7Wu8UDesPr1a4L3urpM9Vq3kvaclmT23DOm9ldOePdJ37b2quqQ9 bO3xvZ/cqj0nbPa9PDuxPYXy+r1S2Lc91X7/vZO1vj2fBwK+0dTFPeBQBL6QN809DZoGvnLf 1D3z4Qi+583cPUQnC75RBOU9lmgNvgiE7T1jpA++/k32PQjZEb47Y/89xgQUvj1iBD6/JRa+ ITkJPvk5GL53Ng4+VD8avjZaEz6fMxy+V6QYPn8UHr5/FB4+fN8fvkmqIz4HkiG+B2UpPm4p I77wQy8+4qIkvv1FNT6B+yW+52k7Pj8wJ74qrkE+CD4ovg0RSD6lISm+f5BOPsvXKb5IKlU+ FV0qvrrbWz4ariq+8KFiPk7HKr66eWk+H6UqvmNfcD7kQyq+GU93Pu+fKb6ORH4+hbUovnad gj7XgCe+lBaGPiD+Jb7Oiok+fikkviP3jD4o/yG+RFiQPjl7H76vqpM+5Jkcvnvqlj5YVxm+ kxOaPtmvFb5rIZ0+wZ8RvicPoD6IIw2+g9eiPuA3CL7KdKU+ttkCvs/gpz65DPq92xSqPjN3 7b2rCaw+uu/fvXa3rT7pdNG9qRWvPnIHwr0+G7A+5KqxvW6+sD45ZqC91PSwPtZEjr2Qs7A+ 3a52vUfvrz5Mak+9YZyuPkf5Jr1rr6w+NFX7vFodqj62wKe8KdymPpZGKLyT46I++N3bvW9C lD0s+t+9xKWZPeQg5L0kPp89DVHovVANpT1Ziey94hSrPWXI8L1+VrE9qgz1vbnTtz1uVPm9 M46+Pdid/b1Jh8U9bvMAvo/AzD2lFgO+UzvUPVs3Bb7V+Ns9QFQHvkn64z32awm+q0DsPft8 C77izPQ9s4UNvrSf/T1ohA++v1wDPkp3Eb5eDQg+alwTvrbhDD7AMRW+uNkRPiP1Fr4k9RY+ VqQYvqMzHD72PBq+nZQhPoi8G75lFyc+fiAdvha7LD4oZh6+f34yPryKH75bYDg+XYsgvhZf Pj4TZSG+2HhEPtcUIr6lq0o+h5civhn1UD7z6SK+jFJXPtMII74cwV0+2/AivoI9ZD6tniK+ KMRqPtkOIr45UXE+7z0hvkfgdz5yKCC+umx+PuPKHr68eII+wSEdvoW0hT6IKRu+ruaIPrne GL4DDIw+4z0Wvgohjz6bQxO+9yGSPpDsD77GCpU+jTUMvhDXlz59Gwi+GoKaPoebA77NBp0+ Mmb9vatfnz7Vv/K90IahPnRA573YdaM+muXavfglpT5Yrs292Y+mPoybv72gq6c+dbCwvQdx qD4W86C9QNeoPv5skL0U1ag+x1d+vQhhqD71hFq9YnGnPnmSNb19/KU+wr4Pvf74oz6prdK8 TV6hPjpvhbzyJJ4+wHTiuzFHmj6DY9e9abOUPdBK2706Apo9iTrfvQOEnz2OMeO9TzqlPYYu 572GJqs9DTDrvS5KsT2FNO+9rKa3PUg6871nPb49bD/3va8PxT3nQfu9xh7MPYc//73Ra9M9 9ZoBvu332j1AkQO+BMTiPUSBBb700Oo9imkHvlsf8z2CSAm+y6/7PXscC75IQQI+uOMMvt3L Bj5UnA6+nncLPlxEEL5eRBA+tdkRvsUxFT46WhO+Vj8aPqDDFL56bB8+ihMWvmK4JD6ARxe+ FCIqPvJcGL5OqC8+O1EZvs5JNT6fIRq+0gQ7PlLLGr6U10A+bEsbvvu/Rj4Bnxu+kLtMPgTD G77Jx1I+abQbvqvhWD4UcBu+/wVfPtnyGr4rMWU+jjkavklfaz76QBm+LYxxPuYFGL4ms3c+ GoUWvjbPfT5iuxS+eO2BPpKlEr5A6IQ+hEAQvsDUhz4niQ2+ma+KPoR8Cr4ddY0+vRcHvl4h kD4fWAO+G7CSPlt2/r3GHJU+VX31vYVilz5Xweu9GXyZPmo/4b3gY5s+l/XVveoTnT4z48m9 zoWePigJvb3Msp8+QWqvvbSToD7BC6G9DCGhPov1kb3wUqE+BTOCvU4hoT7spmO98IOgPknV Qb2acp8+NCMfvVPlnT7Im/e8pNSbPkI+sLzjOZk++LVRvKMPlj6R44i7KVKSPiPt0r1FA5U9 G6HWva48mj2IW9q97qafPTsb3r1sQ6U93d7hvXETqz0EpeW9UhixPRNs6b1TU7c9UDLtvaPF vT3d9fC9f3DEPbS09L3ZVMs9pGz4vc1z0j1VG/y9K87ZPT2+/72+ZOE9VqkBviY46T3fagO+ 30jxPTMiBb5Ml/k9tc0GvrURAT6pawi+pHYFPkP6Cb5D+gk+nXcLvlicDj614Qy+alwTPnU2 Dr75ORg+qnMPvk40HT4WlxC+gEoiPl2eEb6Peyc+CocSvjLGLD6eThO+9CgyPn/yE747ojc+ BXAUvhAwPT53xBS+VtBCPgvtFL6ugEg+7uYUvog+Tj4/rxS+vAZUPhdDFL5H1lk+g58Tvoip Xz6RwRK+t3xlPkumEb6KS2s+vEoQvosRcT7yqw6+tcl2PgvHDL7ebnw+KZkKvpf9gD6HHwi+ QbSDPnNXBb4lWIY+XD4CvrXliD64o/29GVmLPoEf9r1Qro0+Feztve7gjz46BuW9VeyRPktr 272Vy5M+qBnRvWF5lT7HEMa9LPCWPoNRur0HKpg+Td6tvbwgmT6Gu6C90M2ZPt7vkr1+Kpo+ 1oSEvdovmj7MDWu9xtaZPnEMTL1OGJk+GS4svYDtlz5BpAu92U+WPhtU1bxmOZQ+3AmTvCWl kT7vESK8PY+OPgYmALt/9Yo+iHzOvX0zlT28/tG9oVaaPZGF1b2NqJ89zw/ZvXMqpT0hnNy9 jN2qPQsp4L32wrA9/rTjvdLbtj06Pue9Oim9PeDC6r0hrMM98kDuvW1lyj1EtvG9+FXRPYgg 9b10ftg9N334vX3f3z28yfu9gHnnPUQD/73bTO89aBMBvqhZ9z2gmAK+5Z//PZ8PBL6gDwQ+ pHYFvqtrCD7cywa+ueMMPlsNCL5MdxE+IDkJvr4lFj4UTQq+VO4aPg5HC74T0B8+0SQMvufJ JD4H5Ay+f9opPlOCDb5lAC8+O/0Nvsw5ND5CUg6+6oQ5PtZ+Dr6K3z4+WIAOvj5HRD4jVA6+ cLlJPoz3Db42M08+1mcNvlCxVD5Nogy+STBaPjikC75ZrF8+32oKvlghZT6R8wi+1opqPqc7 B74H5G8+hEAFvrwndT6f/wK+clB6Pop2AL4QWH8+6EX7vSkcgj5ZBfW9LHWEPoEn7r1ls4Y+ 4ajmvffSiD57ht69v8+KPhi+1b1TpYw+Ok7MvRFPjj5oNsK9B8iPPmN3t70DC5E+KxOsvaAS kj57DaC9NtmSPvprk73fWJM+bDaGvZ+Lkz6M7nC9V2uTPpd3VL318ZI+/yg3vWwZkj4RKxm9 DdyQPohb9byCNI8+qdK3vDsejT75eHS8YpWKPt2p9Lt6l4c+ApQeuWgjhD4uE8q9ekWVPTZl zb2eUZo9MbrQvXSKnz3ZENS9GfGkPddn172lhqo9s73avRNMsD3ZEN69UEK2PYpf4b1Uarw9 +afkvfLEwj0W6Oe98VLJPc0d6735FNA910buvY0L1z27YPG9IjfePfZo9L0QmOU9wFz3vYAu 7T02Ofq9R/r0PVH7/L1Y+/w925//vaaYAj62EQG+ts0GPkNBAr6AHAs+vlwDvmaEDz47YgS+ wwQUPr1PBb7DnBg+LSMGvmBLHT502ga+bw8iPllzB76h5yY+n+sHvmfSKz7uQAi+Cc4wPvJw CL6o2DU+QnkIvvzvOj5lVwi+uxFAPukICL4wO0U+TYsHvpNpSj4O3Aa+mJlPPq34Bb7mx1Q+ qN4EvsDwWT6LiwO+JRBfPt38Ab6qIWQ+QjAAvqogaT7QRvy9HQhuPiGo972o0nI+UIDyvYJ6 dz5fy+y9gvl7PsSF5r2XJIA+UqzfvT8xgj5aPNi9BR+EPuAz0L0C6oU+f5HHvROOhz7LVL69 4waJPkt+tL3gT4o+sg+qvTRkiz4eDJ+9/T6MPkh4k70O24w+olqHvS0zjT7Fd3W9BkKNPvlN W71FAo0+DFNAvaVujD4sqCS9HIKLPpd0CL3mN4o+SszXvMmLiD5dY568MXqGPjVKSrxpAIQ+ Ilayu90cgT4/x6s6p557Poqyxb2dOpU9AtbIvR0vmj3X+su9VU6fPcUfz70ymaQ9bkPSvaIQ qj1jZNW9lrWvPQWB2L3YiLU9pZfbvS2Luz1spt69Ur3BPWSr4b3mH8g9eaTkvWKzzj1pj+e9 LXjVPdlp6r2bbtw9RTHtvdOW4z0P4++9xPDqPVt88r1gfPI9P/r0vT45+j2mWfe9bBMBPkOX +b05IgU+yq/7vYZICT6mn/29soUNPjZj/70I2RE+VXsAvqNBFj4OKwG+c74aPry+Ab5CTh8+ UjQCvr/vIz6oiQK+SqEoPpW8Ar4uYS0+5MoCvn8tMj5OsgK+CQQ3PpBwAr5s4js+XwMCvhvG QD5paAG+HqxFPl+dAL55kUo+7z//vcFyTz7U2/y9S0xUPu8J+r0lGlk+28X2vSzYXT5kC/O9 wYFiPmzW7r0REmc+FiPqvd2Daz7Z7eS9s9FvPlwz372o9XM+y/DYvXTpdz6rI9K9f6Z7PiXK yr3UJX8+6OLCvQwwgT6Kbbq9uKaCPlxqsb308oM+zdqnvX4QhT5kwZ29AvuFPhAik73orYY+ QAKIvaIkhz5F0ni9fVqHPrO/YL3OSoc+VeNHvevwhj6NWC69XEiGPqk/FL3fTIU+Gn3zvJb6 gz43Ab68GE6CPrNtiLy6RIA+L18mvCa5ez7F7nW7qSl2PvpBIzut228+3lvBvVcUlT1gUsS9 qfCZPcpIx7219Z491T3KvVMkpD0tMM29UH2pPVQe0L11Aa89uwbTvXmxtD2y59W98Y26PWm/ 2L2Jl8A984vbvaTOxj1KS969uDPNPTT74L38xtM9b5njvaGI2j1/I+a9n3jhPduW6L3Zlug9 x/DqvR3j7z1vLu29v1z3PdNM771DA/894kjxveNqAz5cH/O9j2kHPuPM9L39fAs+9032vWKk Dz4Gn/e91d4TPkm8+L0/Kxg+AKL5vWCIHD41TPq91/QgPu22+r0NbyU+DN76vTv1KT5tvfq9 kIUuPuJQ+r20HTM+K5T5vXa7Nz4Pg/i9KFw8PkUZ970B/UA+lVL1vf2aRT7JKvO9zTJKPsCd 8L3iwE4+cqftvV9BUz4BROq9PbBXPqFv5r0YCVw+xibivTNHYD4oZt29l2VkPrsq2L0KX2g+ 43HSvd0tbD5UOcy9JMxvPk5/xb2jM3M+oUK+vcVddj6/gra9oEN5PuM/rr0Y3ns+H3ulvYEl fj6ONpy9JAmAPnB1kr0vzoA+TjyIvcZdgT5JInu91LOBPhT3ZL0szIE+2wlOvayigT43cTa9 XzOBPiVIHr1leoA++q0FvXzofj5tjdm8aDt8Phd2p7xl6Hg+8eBqvF3rdD4mwAe82UFwPrZ+ Gbtk62o+eHdhO3rpZD5bEL29CdSUPYLbv722l5k9OqXCvTiCnj09bMW9MpSjPTIvyL11zqg9 qezKvZAxrj0No829Gr6zPbtQ0L20dLk96PPSvblVvz22itW9hWHFPSAT2L1dmMs9BIvavXT6 0T0m8Ny9xIfYPS9A3702QN89mXjhvYMj5j3OluO9UjHtPQuY5b32aPQ9e3nnvcHJ+z0lOOm9 VakBPvLQ6r1GgQU+q0DsvfVrCT7/g+29l2gNPoKX7r0vdhE+tHfvvZmTFT73IPC9mL8ZPp+P 8L3I+B0+5r/wvY09Ij76rfC9J4wmPgNW8L2r4io+FLTvves+Lz5FxO69rJ4zPqqC7b1C/zc+ VuvrvQNePD5v+um9+rdAPiis573WCUU+zPzkvS1QST656OG9ZIdNPoVs3r1lq1E+3YTavQC4 VT61Lta9zKhZPk1n0b3qeF0+IyzMvV0jYT4ie8a906JkPpVSwL2g8Wc+W7G5ve8Jaz7ZlrK9 kOVtPh4Dq70kfnA+B/eivejMcj45dJq9A8t0Pmd9kb1NcXY+VBaIvZO4dz72h3y9eZl4Pn0Z aL2dDHk+4fBSvZ4KeT4NIT29YIx4PobAJr3zinc+dekPveD/dT7Nc/G8VeVzPoOnwrwkNnE+ 8rmTvD7ubT7F/Em8zApqPgI827tcimU+YcCYuidtYD69l4k7XLVaPg/RuL0Ve5Q9eHK7vcgl mT0wEb69Z/WdPfqrwL2C6qI9hUHDvboFqD1X0MW9r0etPexWyL3BsLI9qNPKvWVBuD3CRM29 7/m9PWyoz72o2sM9qvzRvajjyT1sP9S9+xTQPY1u1r2NbtY9wIfYvSrw3D2WiNq9c5njPZdu 3L3eaeo9ITfevb9g8T1039+9OH34Pb9k4b1Evv89CsTivUKRAz5E+uO9QlQHPlAE5b1CJws+ 997lvUoJDz7ghua9KvkSPqD45r2n9RY+1DDnvU/9Gj7pK+e9jQ4fPk/m5r2kJyM+dVzmvaFG Jz68iuW9cmkrPoNt5L28jS8+LwHjvROxMz45QuG9vdA3Pg8t373Z6Ts+TL7cvT/5Pz6Y8tm9 pftDPsTG1r1s7Uc+wzfTvb/KSz7JQs+9n49PPjLlyr3EN1M+uBzGvY6+Vj5c58C9QB9aPoRD u73QVF0+EDC1vQBaYD5erK69KCljPky4p72ivGU+gVSgvWsOaD5Ogpi9ZBhqPuxDkL0n1Gs+ bJyHvUM7bT4CIH29H0duPu1Har0s8W4+wr1WveQybz5akUK9vgVvPonVLb14Y24+QqAYvUJG bT6uCgO9m6hrPpNi2rynhWk+GmiuvF3ZZj7qa4K8qaBjPgl1Lbx92V8+zZWuuz+DWz7KlEG5 1p5WPqlLnTvLLlE+9Z60vdQKlD0uGLe9OpyYPZqNub24UJ09+v27vb8ooj0AaL697SSnPTvK wL2cRaw9KyPDvTOLsT01ccW9Cva2Paayx71Whrw9s+XJvUE8wj10CMy9xxfIPesYzr3sGM49 +xTQvW4/1D1w+tG9BovaPfnG070x++A9KnjVvWeP5z2FC9e930buPW1+2L2AIPU9KM7ZvVIb /D3t99q995oBPtT4271eNwU+4c3cvfLhCD4PdN29upkMPjLo3b2LXRA+KifevRwsFD6sLd69 /gMYPnf43b2a4xs+OITdvTTJHz6ezdy97rIjPkzR272rnic+8ovavSyKKz5L+ti9BXMvPhEZ 172YVjM+G+XUvQ4yNz5RW9K9aAI7Pr54z71hxD4+lDrMvZJ0Qj4rnsi9SQ9GPiShxL2tkEk+ SEHAvbH0TD69fLu97jZQPvlRtr3hUlM+3L+wvc5DVj63xaq9vQRZPlVjpL2FkFs+GZmdvczh XT4ZaJa9A/NfPgnSjr1svmE+idmGvWo+Yz4SBH29+WxkPvCfa700RGU+p5FZvS2+ZT6v5ka9 HNVlPsWuM71Rg2U+XfwfvXXDZD615Au9ZpBjPoD/7rye5WE+ItHFvCO/Xz5TeZy8whldPiVy Zrww81k+bawUvCNKVj6eaoi7nx5SPmaJJTrmcU0+fLysO9RGSD7qerC9mISTPYTNsr2E/Jc9 UBu1vaiVnD0LY7e9i1ChPWyjub2PLaY9DNu7vQUtqz1rCL69SU+wPQMqwL16lLU9ID7Cvd78 uj0NQ8S9VojAPek2xr3sNsY9yhfIvXUIzD2m48m9s/zRPV2Yy70gE9g9sjPNvVJL3j1ds869 eaTkPfAU0L3SHes981XRvU228T3Jc9K9qmz4PdJr072IP/89SzvUvaUWAz5p39S9D5oGPkhV 1b30KAo++5nVvSTCDT6DqtW9ZGQRPt2D1b1ADhU+/CLVvR2+GD7FhNS9VXIcPi+m073zKCA+ IYTSvQXgIz6WG9G9SJUnPoZpz71aRis+BGvNvcLwLj42Hcu9s5EyPmJ9yL1BJjY+3ojFvVKr OT5APcK9oR09Pj6Yvr2qeUA+15e6vbS7Qz49Ora9699GPvZ9sb0f4kk+5mGsvRm+TD5Q5aa9 Y29PPusHob1G8VE+7cmavQA/VD4kLJS9nFNWPu4vjb3sKVg+bNeFvcu8WT77Sny98AZbPqE7 bL31Alw+GopbvZmrXD6mQUq9k/tcPpFvOL207Vw+byMmvRh9XD4fbxO9DaVbPgxnAL1FYVo+ HETavPmtWD6OcrO85odWPr2QjLyW7FM+LrRLvGHaUD4WO/67lVBNPl+JT7ucT0k+jJOrOhfZ RD7jprg78O8/Pq5lrL2p6ZI9O5OuvfJHlz0Gu7C9s8WbPdvbsr1jY6A9bPS0vUUhpT1iA7e9 qP+pPUQHub25/q49kP66vYYetD2o57y9T1+5PdfAvr3awL49T4jAvQ5DxD0+PMK9seXJPaPa w71nqM89gGHFvbiK1T2jzsa9+IvbPeQfyL1hq+E97lLJvRjo5z1oZcq9+kDuPdpUy720tPQ9 xh7MvehB+z2KwMy9bfMAPow3zb3gUAQ+D4HNvTq4Bz5Tms29SCgLPpeAzb3Rnw4+ATHNvVsd Ej7AqMy9Z58VPvPky70xJBk+2uLKvfipHD6Ln8m9qy4gPk0YyL0osCM+Y0rGvScsJz4qM8S9 MaAqPhHQwb2bCS4+rR6/vZdlMT6wHLy9K7E0PvvHuL0p6Tc+pR61vT4KOz74HrG94RA+Po7H rL1r+UA+SBeovey/Qz5eDaO9emBGPnWpnb3P1kg+nOuXvYkeSz5n1JG9PzNNPuhki71aEE8+ 2p6EvRyxUD4wCXu9zRBSPn0ybL2RKlM+WMFcvZ75Uz44v0y9MnlUPmY3PL2LpFQ+BDcrvSp3 VD5GzRm9uuxTPn4LCL0/AVM+EQrsvByxUT6/nse8EflPPjwEo7yi1k0+qNt8vM5HSz5pJDS8 g0tIPs6s2Lt94UQ+naoXu4UKQT79EfU6acg8PgelwTsdHjg+9l+ovU07kj33aaq91n+WPWFt rL064po9AGmuvbdinz2TW7C9lwGkPcZDsr0Cv6g9KiC0vSSbrT1B77W9/5WyPYavt72Er7c9 Rl+5vaDnvD3S/Lq9Hz7CPVWGvL2ossc97/m9vcJEzT2vVb+97PPSPYWXwL1pv9g9U73BvWmm 3j3vxMK9/KfkPRqsw73gwuo9e3DEveL18D2uD8W9dD/3PUWHxb3knf09xtTFvZ8HAj6m9cW9 x0gFPk7nxb0wkQg+LqfFvZbfCz6eMsW9jTIPPgSHxL2WiBI+uqHDvf/fFT4vgMK9/jYZPsUf wb2lixw+BX6/vdHbHz5vmL29UyUjPqJsu73BZSY+Xfi4vZSaKT5+Oba9DsEsPgAus71m1i8+ G9SvvYDXMj4uKqy9QcE1PtUuqL1DkDg+/uCjvRNBOz7hP5+9B9A9PgdLmr1cOUA+WwKVvSF5 Qj5DZo+9TYtEPpl3ib25a0Y+tTeDvSkWSD4dUXm9RIZJPmmZa72xt0o+zU5dvSimSz5LeU69 LE1MPm0iP72HqEw+UlUvvR60TD7mHh+92GtMPuSNDr0JzEs+p2X7vDzRSj4dQNm8WXhJPrvT trzSvkc+VkyUvH2iRT5ksmO8ASJDPg5ZH7yrPEA+oOy3u4/yPD4Lus+6q0Q5PnPRGDv3NDU+ nDjIO2zGMD5baqS9w3qRPU9Spr2MpZU97DKovY3smT0BC6q98U+ePVPZq737z6I9mpytvbBs pz1zU6+9NSasPWj8sL1t/LA9+pWyvUTvtT2OHrS9kf66PXuUtb0PKsA9Bva2vTxxxT1jQbi9 qtPKPat0ub2/UNA98Y26vbLn1T0ui7u9p5fbPVBqvL2NX+E9NCm9vTs+5z2jxb29TTLtPWU9 vr1NOvM9KI6+vXRU+T2Utb691X7/PUyxvr202wI+7H6+ven9BT4DHL69xCQJPiuGvb3YTgw+ 97q8vbZ6Dz70t7u9r6YSPsd6ur0H0RU+HgG5vdL3GD6nSLe9ERkcPi9Ptb2ZMh8+lxKzvRtC Ij7nkLC9JEUlPizIrb0hOSg+wbaqvVQbKz4dW6e90+gtPuGzo72znjA+AMCfva45Mz6rfpu9 g7Y1Plzvlr3BETg+7xGSveZHOj6N5oy9UFU8PuZth70qNj4+BKmBvaLmPz7+Mne93GJBPgeD ar3UpkI+Z0ddvZiuQz4Lh0+9MHZEPt9JQb2z+UQ+YZkyvVs1RT6YgCO9ZyVFPvkLFL1cxkQ+ 4EkEvQAVRD6Pk+i8YA5DPmk6yLzfr0E+H66nvFr3Pz6TF4e8OOM9PlVETbxwcjs+U/gMvKmk OD4XVZu7Nno1Puzhe7pV9DE+pKMxO/MULj6cy8w7CN8pPl6FoL0uqZA9u0yivUm6lD0WDKS9 9OWYPUHCpb16LJ09EW6nvdiNoT02Dqm9MAqmPWWhqr1koao9LSasvW9Trz0gm629MiC0PbP+ rr1IB7k9Q0+wvXAIvj0ui7G9MiPDPbuwsr3qVsg9Gr6zvQ2jzT1xsbS9ugbTPdSItb0Igdg9 SUK2veAQ3j3Q27a9/rTjPVFTt70WbOk9qKa3vYY07z2507e9qwz1PUfYt72D8vo9JLK3vQRy AD4RX7e9cm8DPsrctr1OcAY+Fym2vS9zCT6+QbW9pnYMPoQktL0deQ8+Qc+yvdF4Ej7PP7G9 9XMVPih0r72UaBg+RWqtvZFUGz5WIKu9uTUePoqUqL27CSE+RsWlvQzOIz4VsaK9H4AmPrJW n70sHSk+CbWbvWCiKz5Py5e9vAwuPu+Yk70qWTA+pR2PvWyEMj6LWYq9Los0PhJNhb0QajY+ G/J/vZYdOD6IvXS9NaI5Puz/aL1I9Do+7b1cvT8QPD4b/U+9c/I8Pj3EQr1ilz0+chs1vXn7 PT4NDCe9TBs+PtKgGL2j8z0+yeUJvXSBPT4g0fW818E8Phpw17xZsjs+G8m4vM1QOj6l/5m8 fZs4PiNzdrwckTY+kT05vPowND6kZ/m7CXsxPlRYgrvQby4+ewvguZUQKz4O1UU7a18nPuy2 zzsiXyM+cLGcvcjHjz2qWZ69Qb+TPUH5n73Mz5c9HI+hvZL5mz0IGqO9mTygPdCYpL3RmKQ9 KAqmvTkOqT2ybKe9l5ytPQK/qL3GQ7I9oP+pvWIDtz0GLau9Ctu7PZJFrL1AysA9qEetvVTQ xT2IMa69puzKPW8Br71UHtA9kbWvvV9k1T0JTLC9tr3aPe/CsL0PKeA9TxixvQCl5T0qSrG9 CzDrPXlWsb1myPA9NDuxvSts9j1G9rC9QRn8PZ2FsL265gA+IuevvRnDAz7KGK+9aqAGPocY rr1AfQk+T+SsvQZYDD4pequ9HS8PPjLYqb22ABI+g/ynvenKFD5g5aW9vYsXPieRo70JQRo+ SP6gvZXoHD5hK569+38fPjoXm73JBCI+xMCXvWF0JD4tJ5S9FMwmPt1JkL0OCSk+gyiMvVwo Kz4Sw4e9CyctPtIZg735AS8+01p8vfq1MD6//XG93T8yPjofZ71bnDM+CMNbvRnIND4B7k+9 3r81PtOlQ71XgDY+UvE2vUcGNz6K2Cm9kk43PpFkHL0lVjc+6J8OvSIaNz4RlgC935c2Pv6n 5LzwzDU+sM/HvCe3ND7Zwaq8v1QzPkufjbxMpDE+tBZhvOikLz66VSe8E1YtPhiR3Lv8tyo+ bfpYu0nLJz7hCe43YJEkPg8dVjtCDCE+E0PRO68+HT757pi9o9eOPW15mr2ktZI9u/qbvUCr lj3LcZ29jLiaPXvdnr2B3Z49lDygvRMaoz3YjaG9DW6nPfXPor1P2as9kgGkvZFbsD1CIaW9 bPS0PYstpr1to7k95iSnvQBovj2+Bai9h0HDPW7OqL05L8g9T32pvTEwzT2hEKq9ckPSPaKG qr3UZ9c9g92qvR2c3D1uE6u9397hPYQmq72LLuc93xSrvVmJ7D2X3Kq9bO3xPb57qr26WPc9 bPCpvfvI/D2xOKm96B0BPqNSqL091wM+bzynvSmPBj419KW9FEQJPil4pL139As+lcaivYee Dj7L3aC9f0ARPki8nr1r2BM+j2CcvUBkFj5PyZm91+EYPlf1lr32Ths+rOOTvTupHT5yk5C9 NO4fPg4Ejb1WGyI+IDWJvfItJD58JoW9UyMmPlTYgL2o+Cc+K5Z4vRCrKT40/269nDcrPv/t ZL1Dmyw+umVavRLTLT5Xak+9/NsuPq8ARL0Dsy8+nC44vShVMD7j+iu9iL8wPlttH71J7zA+ Ao8SvcHhMD7GaQW9XZQwPtIR8LzSBDA+5fDUvPowLz6bi7m8FxcuPvL+nbydtSw+MGmCvG8L Kz7e1U285BcpPndMF7zG2iY+o/jCu01UJD4EuDK7X4UhPnmu2jlKbx4+mxJjOxkUGz79rdE7 aXYXPj8+lb3c2Y09TayWvYWekT3AEJi9cHmVPYZqmb2Iapk9hbiavc9xnT2Q+Zu9Ho+hPXYs nb1CwqU98k+evQULqj2zYp+9BWmuPV9joL3V27I9i1ChvRFjtz2/KKK9+v27PXzqor38q8A9 NZSjvUJsxT1RJKS92T3KPSyZpL3KH889HfGkveAQ1D1vKqW9zg/ZPWlDpb07G949STqlvZMx 4z1LDaW9CFHoPae6pL3Xd+09lkCkveKj8j1QnaO9+tL3PQ/Por3CAv09FdShvVUYAT6rqqC9 +awDPilRn73UPQY+6sWdvVnJCD5nB5y9400LPisUmr2uyQ0+0eqXvd46ED4YipW9gp8SPt3w kr2O9RQ+Ih6Qvdk6Fz4cEY29Nm0ZPh3Jib1Bihs+vkWGvZePHT7FhoK9wXofPooYfb0nSSE+ Aa10vS34Ij5GzGu9IIUkPi54Yr1O7SU+TrNYve8tJz7rgE69RkQoPhTlQ72KLSk+3uQ4vf/m KT70hS29820qPhvPIb3Lvyo+9ccVvfPZKj4seQm9FLoqPtvY+bz1XSo+aFjgvIXDKT5NiMa8 9ugoPq6BrLy8zCc+Hl+SvKptJj7AenC83sokPpZ0PLzW4yI+keoIvI+4ID6ZOay7a0kePsM0 EbtDlxs+qBlEOpWjGD7ANm07QnAVPk0r0TvD/xE+hJ+RvXPPjD2E8pK9CHuQPXw7lL1+O5Q9 bHmVvccQmD05q5a9u/qbPc7Pl71A+Z89+eWYvRgMpD2G7Jm97TKoPTXimr1nbaw9tMWbvRC7 sD2plZy9Vhu1PbBQnb2ajbk9XvWdvSkRvj0zgp69P6XCPbT1nr3MSMc9T06fvdb6yz1xip+9 MrrQPYyon72ThdU98qafvYlb2j0FhJ+9jDrfPR8+n73fIOQ9ntOevb4M6T3PQp69CPztPRyK nb2s7PI936ecvUfc9z17mpu9cMj8PWlgmr0v1wA+HviYva1FAz4xYJe9Ka4FPjGXlb0PDwg+ 3JuTvaZmCj7+bJG9ObMMPn8Jj73d8g4+aHCMvaEjET7toIm9gUMTPmeahr1iUBU+W1yDvQ5I Fz4IzX+9PSgZPrNxeL2n7ho+GqdwvdmYHD4jbmi9YCQePkzIX73Ijh8+qrdWvYHVID71Pk29 DPYhPq9hQ73b7SI+9SM5vWO6Iz67ii69LVkkPsGbI73CxyQ+n10YvcoDJT7d1wy9AAslPq4S Ab1P2yQ+ty7qvLZyJD7V39G8dM8jPrNOubz57yI+uZKgvArTIT7bxIe8mHcgPpn/Xbz93B4+ ob4svO4CHT6S//e7fukaPmb8l7snkRg+1a7nuuT6FT7C5YY6EigTPhn4dDuVGhA+weXPO8LU DD79Eo69cbmLPTBMj70zTI89BnuQvYXykj2EnpG9UKyWPZy1kr1weZo9PL+Tva5Znj1DupS9 ukyiPYullb1UUqY91n+Wvfhpqj3qR5e9PJOuPX78l72GzbI9PZyYvTAYtz3GJZm9dnK7PbuX mb2H2789p/CZvVxSxD0bL5q9CtbIPZhRmr0+Zc09n1aavcH+0T2vPJq9HKHWPTcCmr3LSts9 uKWZvSr63z2jJZm9U63kPXWAmL1bYuk9q7SXvScX7j3EwJa9Y8nyPVCjlb2sdvc96FqUvYAc /D0n5pK9AFwAPsFDkb0xowI+fHKPvUTiBD43cY29mxcHPuY+i72HQQk+ndqIvUFeCz6OQ4a9 8msNPhB5g72qaA8+qXqAvWRSET78j3q9HCcTPvjBc72f5BQ+ZYtsvcmIFj717GS9XREYPsLn XL0RfBk+en1UvZTGGj5ssEu9lu4bPmiDQr268Rw+A/o4vbPNHT5yGC+9L4AePpvjJL3pBh8+ L2EavbJfHz6Vlw+9ZogfPgWOBL0Dfx8+A5nyvK5BHz6Et9u8qM4ePs+KxLxiJB4+ZyetvJhB HT5Oo5W8LiUcPvgrfLxazho+ui9NvJk8GT6NhR68xW8XPiPD4LsKaBU+JvWFu/glEz6uNLS6 jaoQPkQYpjoo9w0+DrJ6O4sNCz7BAM47+e8HPg== ##END= odin-1.8.5/aclocal.m40000644000175000017500000115365211734622575011270 00000000000000# generated automatically by aclocal 1.11.1 -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],, [m4_warning([this file was generated for autoconf 2.67. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically `autoreconf'.])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ]) # serial 56 LT_INIT # LT_PREREQ(VERSION) # ------------------ # Complain and exit if this libtool version is less that VERSION. m4_defun([LT_PREREQ], [m4_if(m4_version_compare(m4_defn([LT_PACKAGE_VERSION]), [$1]), -1, [m4_default([$3], [m4_fatal([Libtool version $1 or higher is required], 63)])], [$2])]) # _LT_CHECK_BUILDDIR # ------------------ # Complain if the absolute build directory name contains unusual characters m4_defun([_LT_CHECK_BUILDDIR], [case `pwd` in *\ * | *\ *) AC_MSG_WARN([Libtool does not cope well with whitespace in `pwd`]) ;; esac ]) # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl AC_BEFORE([$0], [LTDL_INIT])dnl m4_require([_LT_CHECK_BUILDDIR])dnl dnl Autoconf doesn't catch unexpanded LT_ macros by default: m4_pattern_forbid([^_?LT_[A-Z_]+$])dnl m4_pattern_allow([^(_LT_EOF|LT_DLGLOBAL|LT_DLLAZY_OR_NOW|LT_MULTI_MODULE)$])dnl dnl aclocal doesn't pull ltoptions.m4, ltsugar.m4, or ltversion.m4 dnl unless we require an AC_DEFUNed macro: AC_REQUIRE([LTOPTIONS_VERSION])dnl AC_REQUIRE([LTSUGAR_VERSION])dnl AC_REQUIRE([LTVERSION_VERSION])dnl AC_REQUIRE([LTOBSOLETE_VERSION])dnl m4_require([_LT_PROG_LTMAIN])dnl dnl Parse OPTIONS _LT_SET_OPTIONS([$0], [$1]) # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' AC_SUBST(LIBTOOL)dnl _LT_SETUP # Only expand once: m4_define([LT_INIT]) ])# LT_INIT # Old names: AU_ALIAS([AC_PROG_LIBTOOL], [LT_INIT]) AU_ALIAS([AM_PROG_LIBTOOL], [LT_INIT]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PROG_LIBTOOL], []) dnl AC_DEFUN([AM_PROG_LIBTOOL], []) # _LT_CC_BASENAME(CC) # ------------------- # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. m4_defun([_LT_CC_BASENAME], [for cc_temp in $1""; do case $cc_temp in compile | *[[\\/]]compile | ccache | *[[\\/]]ccache ) ;; distcc | *[[\\/]]distcc | purify | *[[\\/]]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` ]) # _LT_FILEUTILS_DEFAULTS # ---------------------- # It is okay to use these file commands and assume they have been set # sensibly after `m4_require([_LT_FILEUTILS_DEFAULTS])'. m4_defun([_LT_FILEUTILS_DEFAULTS], [: ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} ])# _LT_FILEUTILS_DEFAULTS # _LT_SETUP # --------- m4_defun([_LT_SETUP], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl _LT_DECL([], [host_alias], [0], [The host system])dnl _LT_DECL([], [host], [0])dnl _LT_DECL([], [host_os], [0])dnl dnl _LT_DECL([], [build_alias], [0], [The build system])dnl _LT_DECL([], [build], [0])dnl _LT_DECL([], [build_os], [0])dnl dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl dnl AC_REQUIRE([AC_PROG_LN_S])dnl test -z "$LN_S" && LN_S="ln -s" _LT_DECL([], [LN_S], [1], [Whether we need soft or hard links])dnl dnl AC_REQUIRE([LT_CMD_MAX_LEN])dnl _LT_DECL([objext], [ac_objext], [0], [Object file suffix (normally "o")])dnl _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_CMD_RELOAD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl _LT_CONFIG_LIBTOOL_INIT([ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi ]) if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi _LT_CHECK_OBJDIR m4_require([_LT_TAG_COMPILER])dnl _LT_PROG_ECHO_BACKSLASH case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\([["`$\\]]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\([["`\\]]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o _LT_CC_BASENAME([$compiler]) # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then _LT_PATH_MAGIC fi ;; esac # Use C for the default configuration in the libtool script LT_SUPPORTED_TAG([CC]) _LT_LANG_C_CONFIG _LT_LANG_DEFAULT_CONFIG _LT_CONFIG_COMMANDS ])# _LT_SETUP # _LT_PROG_LTMAIN # --------------- # Note that this code is called both from `configure', and `config.status' # now that we use AC_CONFIG_COMMANDS to generate libtool. Notably, # `config.status' has no value for ac_aux_dir unless we are using Automake, # so we pass a copy along to make sure it has a sensible value anyway. m4_defun([_LT_PROG_LTMAIN], [m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([ltmain.sh])])dnl _LT_CONFIG_LIBTOOL_INIT([ac_aux_dir='$ac_aux_dir']) ltmain="$ac_aux_dir/ltmain.sh" ])# _LT_PROG_LTMAIN # So that we can recreate a full libtool script including additional # tags, we accumulate the chunks of code to send to AC_CONFIG_COMMANDS # in macros and then make a single call at the end using the `libtool' # label. # _LT_CONFIG_LIBTOOL_INIT([INIT-COMMANDS]) # ---------------------------------------- # Register INIT-COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL_INIT], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_INIT], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_INIT]) # _LT_CONFIG_LIBTOOL([COMMANDS]) # ------------------------------ # Register COMMANDS to be passed to AC_CONFIG_COMMANDS later. m4_define([_LT_CONFIG_LIBTOOL], [m4_ifval([$1], [m4_append([_LT_OUTPUT_LIBTOOL_COMMANDS], [$1 ])])]) # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS]) # _LT_CONFIG_SAVE_COMMANDS([COMMANDS], [INIT_COMMANDS]) # ----------------------------------------------------- m4_defun([_LT_CONFIG_SAVE_COMMANDS], [_LT_CONFIG_LIBTOOL([$1]) _LT_CONFIG_LIBTOOL_INIT([$2]) ]) # _LT_FORMAT_COMMENT([COMMENT]) # ----------------------------- # Add leading comment marks to the start of each line, and a trailing # full-stop to the whole comment if one is not present already. m4_define([_LT_FORMAT_COMMENT], [m4_ifval([$1], [ m4_bpatsubst([m4_bpatsubst([$1], [^ *], [# ])], [['`$\]], [\\\&])]m4_bmatch([$1], [[!?.]$], [], [.]) )]) # _LT_DECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION], [IS-TAGGED?]) # ------------------------------------------------------------------- # CONFIGNAME is the name given to the value in the libtool script. # VARNAME is the (base) name used in the configure script. # VALUE may be 0, 1 or 2 for a computed quote escaped value based on # VARNAME. Any other value will be used directly. m4_define([_LT_DECL], [lt_if_append_uniq([lt_decl_varnames], [$2], [, ], [lt_dict_add_subkey([lt_decl_dict], [$2], [libtool_name], [m4_ifval([$1], [$1], [$2])]) lt_dict_add_subkey([lt_decl_dict], [$2], [value], [$3]) m4_ifval([$4], [lt_dict_add_subkey([lt_decl_dict], [$2], [description], [$4])]) lt_dict_add_subkey([lt_decl_dict], [$2], [tagged?], [m4_ifval([$5], [yes], [no])])]) ]) # _LT_TAGDECL([CONFIGNAME], VARNAME, VALUE, [DESCRIPTION]) # -------------------------------------------------------- m4_define([_LT_TAGDECL], [_LT_DECL([$1], [$2], [$3], [$4], [yes])]) # lt_decl_tag_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_tag_varnames], [_lt_decl_filter([tagged?], [yes], $@)]) # _lt_decl_filter(SUBKEY, VALUE, [SEPARATOR], [VARNAME1..]) # --------------------------------------------------------- m4_define([_lt_decl_filter], [m4_case([$#], [0], [m4_fatal([$0: too few arguments: $#])], [1], [m4_fatal([$0: too few arguments: $#: $1])], [2], [lt_dict_filter([lt_decl_dict], [$1], [$2], [], lt_decl_varnames)], [3], [lt_dict_filter([lt_decl_dict], [$1], [$2], [$3], lt_decl_varnames)], [lt_dict_filter([lt_decl_dict], $@)])[]dnl ]) # lt_decl_quote_varnames([SEPARATOR], [VARNAME1...]) # -------------------------------------------------- m4_define([lt_decl_quote_varnames], [_lt_decl_filter([value], [1], $@)]) # lt_decl_dquote_varnames([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_dquote_varnames], [_lt_decl_filter([value], [2], $@)]) # lt_decl_varnames_tagged([SEPARATOR], [VARNAME1...]) # --------------------------------------------------- m4_define([lt_decl_varnames_tagged], [m4_assert([$# <= 2])dnl _$0(m4_quote(m4_default([$1], [[, ]])), m4_ifval([$2], [[$2]], [m4_dquote(lt_decl_tag_varnames)]), m4_split(m4_normalize(m4_quote(_LT_TAGS)), [ ]))]) m4_define([_lt_decl_varnames_tagged], [m4_ifval([$3], [lt_combine([$1], [$2], [_], $3)])]) # lt_decl_all_varnames([SEPARATOR], [VARNAME1...]) # ------------------------------------------------ m4_define([lt_decl_all_varnames], [_$0(m4_quote(m4_default([$1], [[, ]])), m4_if([$2], [], m4_quote(lt_decl_varnames), m4_quote(m4_shift($@))))[]dnl ]) m4_define([_lt_decl_all_varnames], [lt_join($@, lt_decl_varnames_tagged([$1], lt_decl_tag_varnames([[, ]], m4_shift($@))))dnl ]) # _LT_CONFIG_STATUS_DECLARE([VARNAME]) # ------------------------------------ # Quote a variable value, and forward it to `config.status' so that its # declaration there will have the same value as in `configure'. VARNAME # must have a single quote delimited value for this to work. m4_define([_LT_CONFIG_STATUS_DECLARE], [$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`']) # _LT_CONFIG_STATUS_DECLARATIONS # ------------------------------ # We delimit libtool config variables with single quotes, so when # we write them to config.status, we have to be sure to quote all # embedded single quotes properly. In configure, this macro expands # each variable declared with _LT_DECL (and _LT_TAGDECL) into: # # ='`$ECHO "X$" | $Xsed -e "$delay_single_quote_subst"`' m4_defun([_LT_CONFIG_STATUS_DECLARATIONS], [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames), [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAGS # ---------------- # Output comment and list of tags supported by the script m4_defun([_LT_LIBTOOL_TAGS], [_LT_FORMAT_COMMENT([The names of the tagged configurations supported by this script])dnl available_tags="_LT_TAGS"dnl ]) # _LT_LIBTOOL_DECLARE(VARNAME, [TAG]) # ----------------------------------- # Extract the dictionary values for VARNAME (optionally with TAG) and # expand to a commented shell variable setting: # # # Some comment about what VAR is for. # visible_name=$lt_internal_name m4_define([_LT_LIBTOOL_DECLARE], [_LT_FORMAT_COMMENT(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [description])))[]dnl m4_pushdef([_libtool_name], m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [libtool_name])))[]dnl m4_case(m4_quote(lt_dict_fetch([lt_decl_dict], [$1], [value])), [0], [_libtool_name=[$]$1], [1], [_libtool_name=$lt_[]$1], [2], [_libtool_name=$lt_[]$1], [_libtool_name=lt_dict_fetch([lt_decl_dict], [$1], [value])])[]dnl m4_ifval([$2], [_$2])[]m4_popdef([_libtool_name])[]dnl ]) # _LT_LIBTOOL_CONFIG_VARS # ----------------------- # Produce commented declarations of non-tagged libtool config variables # suitable for insertion in the LIBTOOL CONFIG section of the `libtool' # script. Tagged libtool config variables (even for the LIBTOOL CONFIG # section) are produced by _LT_LIBTOOL_TAG_VARS. m4_defun([_LT_LIBTOOL_CONFIG_VARS], [m4_foreach([_lt_var], m4_quote(_lt_decl_filter([tagged?], [no], [], lt_decl_varnames)), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var)])])]) # _LT_LIBTOOL_TAG_VARS(TAG) # ------------------------- m4_define([_LT_LIBTOOL_TAG_VARS], [m4_foreach([_lt_var], m4_quote(lt_decl_tag_varnames), [m4_n([_LT_LIBTOOL_DECLARE(_lt_var, [$1])])])]) # _LT_TAGVAR(VARNAME, [TAGNAME]) # ------------------------------ m4_define([_LT_TAGVAR], [m4_ifval([$2], [$1_$2], [$1])]) # _LT_CONFIG_COMMANDS # ------------------- # Send accumulated output to $CONFIG_STATUS. Thanks to the lists of # variables for single and double quote escaping we saved from calls # to _LT_DECL, we can put quote escaped variables declarations # into `config.status', and then the shell code to quote escape them in # for loops in `config.status'. Finally, any additional code accumulated # from calls to _LT_CONFIG_LIBTOOL_INIT is expanded. m4_defun([_LT_CONFIG_COMMANDS], [AC_PROVIDE_IFELSE([LT_OUTPUT], dnl If the libtool generation code has been placed in $CONFIG_LT, dnl instead of duplicating it all over again into config.status, dnl then we will have config.status run $CONFIG_LT later, so it dnl needs to know what name is stored there: [AC_CONFIG_COMMANDS([libtool], [$SHELL $CONFIG_LT || AS_EXIT(1)], [CONFIG_LT='$CONFIG_LT'])], dnl If the libtool generation code is destined for config.status, dnl expand the accumulated commands and init code now: [AC_CONFIG_COMMANDS([libtool], [_LT_OUTPUT_LIBTOOL_COMMANDS], [_LT_OUTPUT_LIBTOOL_COMMANDS_INIT])]) ])#_LT_CONFIG_COMMANDS # Initialize. m4_define([_LT_OUTPUT_LIBTOOL_COMMANDS_INIT], [ # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' _LT_CONFIG_STATUS_DECLARATIONS LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_quote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in lt_decl_all_varnames([[ \ ]], lt_decl_dquote_varnames); do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[[\\\\\\\`\\"\\\$]]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\[$]0 --fallback-echo"')dnl " lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\` ;; esac _LT_OUTPUT_LIBTOOL_INIT ]) # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before # AC_OUTPUT is called), incase it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} AC_MSG_NOTICE([creating $CONFIG_LT]) cat >"$CONFIG_LT" <<_LTEOF #! $SHELL # Generated by $as_me. # Run this file to recreate a libtool stub with the current configuration. lt_cl_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AS_SHELL_SANITIZE _AS_PREPARE exec AS_MESSAGE_FD>&1 exec AS_MESSAGE_LOG_FD>>config.log { echo AS_BOX([Running $as_me.]) } >&AS_MESSAGE_LOG_FD lt_cl_help="\ \`$as_me' creates a local libtool stub from the current configuration, for use in further configure time tests before the real libtool is generated. Usage: $[0] [[OPTIONS]] -h, --help print this help, then exit -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files Report bugs to ." lt_cl_version="\ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. Copyright (C) 2008 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation gives unlimited permision to copy, distribute and modify it." while test $[#] != 0 do case $[1] in --version | --v* | -V ) echo "$lt_cl_version"; exit 0 ;; --help | --h* | -h ) echo "$lt_cl_help"; exit 0 ;; --debug | --d* | -d ) debug=: ;; --quiet | --q* | --silent | --s* | -q ) lt_cl_silent=: ;; -*) AC_MSG_ERROR([unrecognized option: $[1] Try \`$[0] --help' for more information.]) ;; *) AC_MSG_ERROR([unrecognized argument: $[1] Try \`$[0] --help' for more information.]) ;; esac shift done if $lt_cl_silent; then exec AS_MESSAGE_FD>/dev/null fi _LTEOF cat >>"$CONFIG_LT" <<_LTEOF _LT_OUTPUT_LIBTOOL_COMMANDS_INIT _LTEOF cat >>"$CONFIG_LT" <<\_LTEOF AC_MSG_NOTICE([creating $ofile]) _LT_OUTPUT_LIBTOOL_COMMANDS AS_EXIT(0) _LTEOF chmod +x "$CONFIG_LT" # configure is writing to config.log, but config.lt does its own redirection, # appending to config.log, which fails on DOS, as config.log is still kept # open by configure. Here we exec the FD to /dev/null, effectively closing # config.log, so it can be properly (re)opened and appended to by config.lt. if test "$no_create" != yes; then lt_cl_success=: test "$silent" = yes && lt_config_lt_args="$lt_config_lt_args --quiet" exec AS_MESSAGE_LOG_FD>/dev/null $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false exec AS_MESSAGE_LOG_FD>>config.log $lt_cl_success || AS_EXIT(1) fi ])# LT_OUTPUT # _LT_CONFIG(TAG) # --------------- # If TAG is the built-in tag, create an initial libtool script with a # default configuration from the untagged config vars. Otherwise add code # to config.status for appending the configuration named by TAG from the # matching tagged config vars. m4_defun([_LT_CONFIG], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_CONFIG_SAVE_COMMANDS([ m4_define([_LT_TAG], m4_if([$1], [], [C], [$1]))dnl m4_if(_LT_TAG, [C], [ # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # _LT_COPYING _LT_LIBTOOL_TAGS # ### BEGIN LIBTOOL CONFIG _LT_LIBTOOL_CONFIG_VARS _LT_LIBTOOL_TAG_VARS # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac _LT_PROG_LTMAIN # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) _LT_PROG_XSI_SHELLFNS sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" ], [cat <<_LT_EOF >> "$ofile" dnl Unfortunately we have to use $1 here, since _LT_TAG is not expanded dnl in a comment (ie after a #). # ### BEGIN LIBTOOL TAG CONFIG: $1 _LT_LIBTOOL_TAG_VARS(_LT_TAG) # ### END LIBTOOL TAG CONFIG: $1 _LT_EOF ])dnl /m4_if ], [m4_if([$1], [], [ PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile'], []) ])dnl /_LT_CONFIG_SAVE_COMMANDS ])# _LT_CONFIG # LT_SUPPORTED_TAG(TAG) # --------------------- # Trace this macro to discover what tags are supported by the libtool # --tag option, using: # autoconf --trace 'LT_SUPPORTED_TAG:$1' AC_DEFUN([LT_SUPPORTED_TAG], []) # C support is built-in for now m4_define([_LT_LANG_C_enabled], []) m4_define([_LT_TAGS], []) # LT_LANG(LANG) # ------------- # Enable libtool support for the given language if not already enabled. AC_DEFUN([LT_LANG], [AC_BEFORE([$0], [LT_OUTPUT])dnl m4_case([$1], [C], [_LT_LANG(C)], [C++], [_LT_LANG(CXX)], [Java], [_LT_LANG(GCJ)], [Fortran 77], [_LT_LANG(F77)], [Fortran], [_LT_LANG(FC)], [Windows Resource], [_LT_LANG(RC)], [m4_ifdef([_LT_LANG_]$1[_CONFIG], [_LT_LANG($1)], [m4_fatal([$0: unsupported language: "$1"])])])dnl ])# LT_LANG # _LT_LANG(LANGNAME) # ------------------ m4_defun([_LT_LANG], [m4_ifdef([_LT_LANG_]$1[_enabled], [], [LT_SUPPORTED_TAG([$1])dnl m4_append([_LT_TAGS], [$1 ])dnl m4_define([_LT_LANG_]$1[_enabled], [])dnl _LT_LANG_$1_CONFIG($1)])dnl ])# _LT_LANG # _LT_LANG_DEFAULT_CONFIG # ----------------------- m4_defun([_LT_LANG_DEFAULT_CONFIG], [AC_PROVIDE_IFELSE([AC_PROG_CXX], [LT_LANG(CXX)], [m4_define([AC_PROG_CXX], defn([AC_PROG_CXX])[LT_LANG(CXX)])]) AC_PROVIDE_IFELSE([AC_PROG_F77], [LT_LANG(F77)], [m4_define([AC_PROG_F77], defn([AC_PROG_F77])[LT_LANG(F77)])]) AC_PROVIDE_IFELSE([AC_PROG_FC], [LT_LANG(FC)], [m4_define([AC_PROG_FC], defn([AC_PROG_FC])[LT_LANG(FC)])]) dnl The call to [A][M_PROG_GCJ] is quoted like that to stop aclocal dnl pulling things in needlessly. AC_PROVIDE_IFELSE([AC_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([A][M_PROG_GCJ], [LT_LANG(GCJ)], [AC_PROVIDE_IFELSE([LT_PROG_GCJ], [LT_LANG(GCJ)], [m4_ifdef([AC_PROG_GCJ], [m4_define([AC_PROG_GCJ], defn([AC_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([A][M_PROG_GCJ], [m4_define([A][M_PROG_GCJ], defn([A][M_PROG_GCJ])[LT_LANG(GCJ)])]) m4_ifdef([LT_PROG_GCJ], [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])]) AC_PROVIDE_IFELSE([LT_PROG_RC], [LT_LANG(RC)], [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])]) ])# _LT_LANG_DEFAULT_CONFIG # Obsolete macros: AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)]) AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)]) AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)]) AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_CXX], []) dnl AC_DEFUN([AC_LIBTOOL_F77], []) dnl AC_DEFUN([AC_LIBTOOL_FC], []) dnl AC_DEFUN([AC_LIBTOOL_GCJ], []) # _LT_TAG_COMPILER # ---------------- m4_defun([_LT_TAG_COMPILER], [AC_REQUIRE([AC_PROG_CC])dnl _LT_DECL([LTCC], [CC], [1], [A C compiler])dnl _LT_DECL([LTCFLAGS], [CFLAGS], [1], [LTCC compiler flags])dnl _LT_TAGDECL([CC], [compiler], [1], [A language specific compiler])dnl _LT_TAGDECL([with_gcc], [GCC], [0], [Is the compiler the GNU compiler?])dnl # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_TAG_COMPILER # _LT_COMPILER_BOILERPLATE # ------------------------ # Check for compiler boilerplate output or warnings with # the simple compiler test code. m4_defun([_LT_COMPILER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ])# _LT_COMPILER_BOILERPLATE # _LT_LINKER_BOILERPLATE # ---------------------- # Check for linker boilerplate output or warnings with # the simple link test code. m4_defun([_LT_LINKER_BOILERPLATE], [m4_require([_LT_DECL_SED])dnl ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ])# _LT_LINKER_BOILERPLATE # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ case $host_os in rhapsody* | darwin*) AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) AC_CHECK_TOOL([LIPO], [lipo], [:]) AC_CHECK_TOOL([OTOOL], [otool], [:]) AC_CHECK_TOOL([OTOOL64], [otool64], [:]) _LT_DECL([], [DSYMUTIL], [1], [Tool to manipulate archived DWARF debug symbol files on Mac OS X]) _LT_DECL([], [NMEDIT], [1], [Tool to change global to local symbols on Mac OS X]) _LT_DECL([], [LIPO], [1], [Tool to manipulate fat objects and archives on Mac OS X]) _LT_DECL([], [OTOOL], [1], [ldd/readelf like tool for Mach-O binaries on Mac OS X]) _LT_DECL([], [OTOOL64], [1], [ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4]) AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], [lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&AS_MESSAGE_LOG_FD fi rm -rf libconftest.dylib* rm -f conftest.* fi]) AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [lt_cv_ld_exported_symbols_list=yes], [lt_cv_ld_exported_symbols_list=no]) LDFLAGS="$save_LDFLAGS" ]) case $host_os in rhapsody* | darwin1.[[012]]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[[012]]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ]) # _LT_DARWIN_LINKER_FEATURES # -------------------------- # Checks for linker and compiler features on darwin m4_defun([_LT_DARWIN_LINKER_FEATURES], [ m4_require([_LT_REQUIRED_DARWIN_CHECKS]) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(whole_archive_flag_spec, $1)='' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" m4_if([$1], [CXX], [ if test "$lt_cv_apple_cc_single_mod" != "yes"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi ],[]) else _LT_TAGVAR(ld_shlibs, $1)=no fi ]) # _LT_SYS_MODULE_PATH_AIX # ----------------------- # Links a minimal program and checks the executable # for the system default hardcoded library path. In most cases, # this is /usr/lib:/lib, but when the MPI compilers are used # the location of the communication and MPI libs are included too. # If we don't find anything, use the default library path according # to the aix ld manual. m4_defun([_LT_SYS_MODULE_PATH_AIX], [m4_require([_LT_DECL_SED])dnl AC_LINK_IFELSE(AC_LANG_PROGRAM,[ lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_SYS_MODULE_PATH_AIX # _LT_SHELL_INIT(ARG) # ------------------- m4_define([_LT_SHELL_INIT], [ifdef([AC_DIVERSION_NOTICE], [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)], [AC_DIVERT_PUSH(NOTICE)]) $1 AC_DIVERT_POP ])# _LT_SHELL_INIT # _LT_PROG_ECHO_BACKSLASH # ----------------------- # Add some code to the start of the generated configure script which # will find an echo command which doesn't interpret backslashes. m4_defun([_LT_PROG_ECHO_BACKSLASH], [_LT_SHELL_INIT([ # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','` ;; esac ECHO=${lt_ECHO-echo} if test "X[$]1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X[$]1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "[$]0" --no-reexec ${1+"[$]@"} fi if test "X[$]1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF [$]* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL [$]0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL [$]0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "[$]0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo" fi AC_SUBST(lt_ECHO) ]) _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts]) _LT_DECL([], [ECHO], [1], [An echo program that does not interpret backslashes]) ])# _LT_PROG_ECHO_BACKSLASH # _LT_ENABLE_LOCK # --------------- m4_defun([_LT_ENABLE_LOCK], [AC_ARG_ENABLE([libtool-lock], [AS_HELP_STRING([--disable-libtool-lock], [avoid locking (might break parallel builds)])]) test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '[#]line __oline__ "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, [AC_LANG_PUSH(C) AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no]) AC_LANG_POP]) if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" ])# _LT_ENABLE_LOCK # _LT_CMD_OLD_ARCHIVE # ------------------- m4_defun([_LT_CMD_OLD_ARCHIVE], [AC_CHECK_TOOL(AR, ar, false) test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1]) AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) AC_CHECK_TOOL(RANLIB, ranlib, :) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi _LT_DECL([], [old_postinstall_cmds], [2]) _LT_DECL([], [old_postuninstall_cmds], [2]) _LT_TAGDECL([], [old_archive_cmds], [2], [Commands used to build an old-style archive]) ])# _LT_CMD_OLD_ARCHIVE # _LT_COMPILER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [OUTPUT-FILE], [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------------------- # Check whether the given compiler option works AC_DEFUN([_LT_COMPILER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no m4_if([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi $RM conftest* ]) if test x"[$]$2" = xyes; then m4_if([$5], , :, [$5]) else m4_if([$6], , :, [$6]) fi ])# _LT_COMPILER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_COMPILER_OPTION], [_LT_COMPILER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], []) # _LT_LINKER_OPTION(MESSAGE, VARIABLE-NAME, FLAGS, # [ACTION-SUCCESS], [ACTION-FAILURE]) # ---------------------------------------------------- # Check whether the given linker option works AC_DEFUN([_LT_LINKER_OPTION], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_SED])dnl AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi else $2=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" ]) if test x"[$]$2" = xyes; then m4_if([$4], , :, [$4]) else m4_if([$5], , :, [$5]) fi ])# _LT_LINKER_OPTION # Old name: AU_ALIAS([AC_LIBTOOL_LINKER_OPTION], [_LT_LINKER_OPTION]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], []) # LT_CMD_MAX_LEN #--------------- AC_DEFUN([LT_CMD_MAX_LEN], [AC_REQUIRE([AC_CANONICAL_HOST])dnl # find the maximum length of command line arguments AC_MSG_CHECKING([the maximum length of command line arguments]) AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac ]) if test -n $lt_cv_sys_max_cmd_len ; then AC_MSG_RESULT($lt_cv_sys_max_cmd_len) else AC_MSG_RESULT(none) fi max_cmd_len=$lt_cv_sys_max_cmd_len _LT_DECL([], [max_cmd_len], [0], [What is the maximum length of a command?]) ])# LT_CMD_MAX_LEN # Old name: AU_ALIAS([AC_LIBTOOL_SYS_MAX_CMD_LEN], [LT_CMD_MAX_LEN]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_SYS_MAX_CMD_LEN], []) # _LT_HEADER_DLFCN # ---------------- m4_defun([_LT_HEADER_DLFCN], [AC_CHECK_HEADERS([dlfcn.h], [], [], [AC_INCLUDES_DEFAULT])dnl ])# _LT_HEADER_DLFCN # _LT_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) # ---------------------------------------------------------------- m4_defun([_LT_TRY_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "$cross_compiling" = yes; then : [$4] else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF [#line __oline__ "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; }] _LT_EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed $3 fi fi rm -fr conftest* ])# _LT_TRY_DLOPEN_SELF # LT_SYS_DLOPEN_SELF # ------------------ AC_DEFUN([LT_SYS_DLOPEN_SELF], [m4_require([_LT_HEADER_DLFCN])dnl if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"],[ lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ]) ;; *) AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"], [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) ]) ]) ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" AC_CACHE_CHECK([whether a program can dlopen itself], lt_cv_dlopen_self, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self=yes, lt_cv_dlopen_self=yes, lt_cv_dlopen_self=no, lt_cv_dlopen_self=cross) ]) if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_TRY_DLOPEN_SELF( lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=yes, lt_cv_dlopen_self_static=no, lt_cv_dlopen_self_static=cross) ]) fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi _LT_DECL([dlopen_support], [enable_dlopen], [0], [Whether dlopen is supported]) _LT_DECL([dlopen_self], [enable_dlopen_self], [0], [Whether dlopen of programs is supported]) _LT_DECL([dlopen_self_static], [enable_dlopen_self_static], [0], [Whether dlopen of statically linked programs is supported]) ])# LT_SYS_DLOPEN_SELF # Old name: AU_ALIAS([AC_LIBTOOL_DLOPEN_SELF], [LT_SYS_DLOPEN_SELF]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], []) # _LT_COMPILER_C_O([TAGNAME]) # --------------------------- # Check to see if options -c and -o are simultaneously supported by compiler. # This macro does not hard code the compiler like AC_PROG_CC_C_O. m4_defun([_LT_COMPILER_C_O], [m4_require([_LT_DECL_SED])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&AS_MESSAGE_LOG_FD echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi chmod u+w . 2>&AS_MESSAGE_LOG_FD $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* ]) _LT_TAGDECL([compiler_c_o], [lt_cv_prog_compiler_c_o], [1], [Does compiler simultaneously support -c and -o options?]) ])# _LT_COMPILER_C_O # _LT_COMPILER_FILE_LOCKS([TAGNAME]) # ---------------------------------- # Check to see if we can do hard links to lock some files if needed m4_defun([_LT_COMPILER_FILE_LOCKS], [m4_require([_LT_ENABLE_LOCK])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl _LT_COMPILER_C_O([$1]) hard_links="nottested" if test "$_LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user AC_MSG_CHECKING([if we can lock with hard links]) hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no AC_MSG_RESULT([$hard_links]) if test "$hard_links" = no; then AC_MSG_WARN([`$CC' does not support `-c -o', so `make -j' may be unsafe]) need_locks=warn fi else need_locks=no fi _LT_DECL([], [need_locks], [1], [Must we lock files when doing compilation?]) ])# _LT_COMPILER_FILE_LOCKS # _LT_CHECK_OBJDIR # ---------------- m4_defun([_LT_CHECK_OBJDIR], [AC_CACHE_CHECK([for objdir], [lt_cv_objdir], [rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null]) objdir=$lt_cv_objdir _LT_DECL([], [objdir], [0], [The name of the directory that contains temporary libtool files])dnl m4_pattern_allow([LT_OBJDIR])dnl AC_DEFINE_UNQUOTED(LT_OBJDIR, "$lt_cv_objdir/", [Define to the sub-directory in which libtool stores uninstalled libraries.]) ])# _LT_CHECK_OBJDIR # _LT_LINKER_HARDCODE_LIBPATH([TAGNAME]) # -------------------------------------- # Check hardcoding attributes. m4_defun([_LT_LINKER_HARDCODE_LIBPATH], [AC_MSG_CHECKING([how to hardcode library paths into programs]) _LT_TAGVAR(hardcode_action, $1)= if test -n "$_LT_TAGVAR(hardcode_libdir_flag_spec, $1)" || test -n "$_LT_TAGVAR(runpath_var, $1)" || test "X$_LT_TAGVAR(hardcode_automatic, $1)" = "Xyes" ; then # We can hardcode non-existent directories. if test "$_LT_TAGVAR(hardcode_direct, $1)" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, $1)" != no && test "$_LT_TAGVAR(hardcode_minus_L, $1)" != no; then # Linking always hardcodes the temporary library directory. _LT_TAGVAR(hardcode_action, $1)=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. _LT_TAGVAR(hardcode_action, $1)=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. _LT_TAGVAR(hardcode_action, $1)=unsupported fi AC_MSG_RESULT([$_LT_TAGVAR(hardcode_action, $1)]) if test "$_LT_TAGVAR(hardcode_action, $1)" = relink || test "$_LT_TAGVAR(inherit_rpath, $1)" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi _LT_TAGDECL([], [hardcode_action], [0], [How to hardcode a shared library path into an executable]) ])# _LT_LINKER_HARDCODE_LIBPATH # _LT_CMD_STRIPLIB # ---------------- m4_defun([_LT_CMD_STRIPLIB], [m4_require([_LT_DECL_EGREP]) striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" AC_MSG_RESULT([yes]) else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ;; *) AC_MSG_RESULT([no]) ;; esac fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) ])# _LT_CMD_STRIPLIB # _LT_SYS_DYNAMIC_LINKER([TAG]) # ----------------------------- # PORTME Fill in your ld.so characteristics m4_defun([_LT_SYS_DYNAMIC_LINKER], [AC_REQUIRE([AC_CANONICAL_HOST])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_OBJDUMP])dnl m4_require([_LT_DECL_SED])dnl AC_MSG_CHECKING([dynamic linker characteristics]) m4_if([$1], [], [ if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[[lt_foo]]++; } if (lt_freq[[lt_foo]] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi]) library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[[01]] | aix4.[[01]].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[[45]]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[[123]]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[[01]]* | freebsdelf3.[[01]]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[[3-9]]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \ LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\"" AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null], [shlibpath_overrides_runpath=yes])]) LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[[89]] | openbsd2.[[89]].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi _LT_DECL([], [variables_saved_for_relink], [1], [Variables whose values should be saved in libtool wrapper scripts and restored at link time]) _LT_DECL([], [need_lib_prefix], [0], [Do we need the "lib" prefix for modules?]) _LT_DECL([], [need_version], [0], [Do we need a version for libraries?]) _LT_DECL([], [version_type], [0], [Library versioning type]) _LT_DECL([], [runpath_var], [0], [Shared library runtime path variable]) _LT_DECL([], [shlibpath_var], [0],[Shared library path variable]) _LT_DECL([], [shlibpath_overrides_runpath], [0], [Is shlibpath searched before the hard-coded library search path?]) _LT_DECL([], [libname_spec], [1], [Format of library name prefix]) _LT_DECL([], [library_names_spec], [1], [[List of archive names. First name is the real one, the rest are links. The last name is the one that the linker finds with -lNAME]]) _LT_DECL([], [soname_spec], [1], [[The coded name of the library, if different from the real name]]) _LT_DECL([], [postinstall_cmds], [2], [Command to use after installation of a shared archive]) _LT_DECL([], [postuninstall_cmds], [2], [Command to use after uninstallation of a shared archive]) _LT_DECL([], [finish_cmds], [2], [Commands used to finish a libtool library installation in a directory]) _LT_DECL([], [finish_eval], [1], [[As "finish_cmds", except a single script fragment to be evaled but not shown]]) _LT_DECL([], [hardcode_into_libs], [0], [Whether we should hardcode library paths into libraries]) _LT_DECL([], [sys_lib_search_path_spec], [2], [Compile-time system search path for libraries]) _LT_DECL([], [sys_lib_dlsearch_path_spec], [2], [Run-time system search path for libraries]) ])# _LT_SYS_DYNAMIC_LINKER # _LT_PATH_TOOL_PREFIX(TOOL) # -------------------------- # find a file program which can recognize shared library AC_DEFUN([_LT_PATH_TOOL_PREFIX], [m4_require([_LT_DECL_EGREP])dnl AC_MSG_CHECKING([for $1]) AC_CACHE_VAL(lt_cv_path_MAGIC_CMD, [case $MAGIC_CMD in [[\\/*] | ?:[\\/]*]) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR dnl $ac_dummy forces splitting on constant user-supplied paths. dnl POSIX.2 word splitting is done only on the output of word expansions, dnl not every word. This closes a longstanding sh security hole. ac_dummy="m4_if([$2], , $PATH, [$2])" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$1; then lt_cv_path_MAGIC_CMD="$ac_dir/$1" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac]) MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then AC_MSG_RESULT($MAGIC_CMD) else AC_MSG_RESULT(no) fi _LT_DECL([], [MAGIC_CMD], [0], [Used to examine libraries when file_magic_cmd begins with "file"])dnl ])# _LT_PATH_TOOL_PREFIX # Old name: AU_ALIAS([AC_PATH_TOOL_PREFIX], [_LT_PATH_TOOL_PREFIX]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_PATH_TOOL_PREFIX], []) # _LT_PATH_MAGIC # -------------- # find a file program which can recognize a shared library m4_defun([_LT_PATH_MAGIC], [_LT_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then _LT_PATH_TOOL_PREFIX(file, /usr/bin$PATH_SEPARATOR$PATH) else MAGIC_CMD=: fi fi ])# _LT_PATH_MAGIC # LT_PATH_LD # ---------- # find the pathname to the GNU or non-GNU linker AC_DEFUN([LT_PATH_LD], [AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_CANONICAL_BUILD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl AC_ARG_WITH([gnu-ld], [AS_HELP_STRING([--with-gnu-ld], [assume the C compiler uses GNU ld @<:@default=no@:>@])], [test "$withval" = no || with_gnu_ld=yes], [with_gnu_ld=no])dnl ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [[\\/]]* | ?:[[\\/]]*) re_direlt='/[[^/]][[^/]]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then AC_MSG_CHECKING([for GNU ld]) else AC_MSG_CHECKING([for non-GNU ld]) fi AC_CACHE_VAL(lt_cv_path_LD, [if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'] lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[[3-9]]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [[0-9]][[0-9]]*-bit [[LM]]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac ]) file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown _LT_DECL([], [deplibs_check_method], [1], [Method to check whether dependent libraries are shared objects]) _LT_DECL([], [file_magic_cmd], [1], [Command to use when deplibs_check_method == "file_magic"]) ])# _LT_CHECK_MAGIC_METHOD # LT_PATH_NM # ---------- # find the pathname to a BSD- or MS-compatible name lister AC_DEFUN([LT_PATH_NM], [AC_REQUIRE([AC_PROG_CC])dnl AC_CACHE_CHECK([for BSD- or MS-compatible name lister (nm)], lt_cv_path_NM, [if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi]) if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :) AC_SUBST([DUMPBIN]) if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm AC_SUBST([NM]) _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface], [lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&AS_MESSAGE_LOG_FD (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD) cat conftest.out >&AS_MESSAGE_LOG_FD if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest*]) ])# LT_PATH_NM # Old names: AU_ALIAS([AM_PROG_NM], [LT_PATH_NM]) AU_ALIAS([AC_PROG_NM], [LT_PATH_NM]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_PROG_NM], []) dnl AC_DEFUN([AC_PROG_NM], []) # LT_LIB_M # -------- # check for math library AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in *-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") AC_CHECK_LIB(m, cos, LIBM="$LIBM -lm") ;; *) AC_CHECK_LIB(m, cos, LIBM="-lm") ;; esac AC_SUBST([LIBM]) ])# LT_LIB_M # Old name: AU_ALIAS([AC_CHECK_LIBM], [LT_LIB_M]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_CHECK_LIBM], []) # _LT_COMPILER_NO_RTTI([TAGNAME]) # ------------------------------- m4_defun([_LT_COMPILER_NO_RTTI], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions], lt_cv_prog_compiler_rtti_exceptions, [-fno-rtti -fno-exceptions], [], [_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)="$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1) -fno-rtti -fno-exceptions"]) fi _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1], [Compiler flag to turn off builtin functions]) ])# _LT_COMPILER_NO_RTTI # _LT_CMD_GLOBAL_SYMBOLS # ---------------------- m4_defun([_LT_CMD_GLOBAL_SYMBOLS], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([LT_PATH_NM])dnl AC_REQUIRE([LT_PATH_LD])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_TAG_COMPILER])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. AC_MSG_CHECKING([command to parse $NM output from $compiler object]) AC_CACHE_VAL([lt_cv_sys_global_symbol_pipe], [ # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[[BCDEGRST]]' # Regexp to match symbols that can be accessed directly from C. sympat='\([[_A-Za-z]][[_A-Za-z0-9]]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[[BCDT]]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[[ABCDEGRST]]' fi ;; irix* | nonstopux*) symcode='[[BCDEGRST]]' ;; osf*) symcode='[[BCDEGQRST]]' ;; solaris*) symcode='[[BDRT]]' ;; sco3.2v5*) symcode='[[DT]]' ;; sysv4.2uw2*) symcode='[[DT]]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[[ABDT]]' ;; sysv4) symcode='[[DFNSTU]]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[[ABCDGIRSTW]]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[[]] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)" if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot find nm_test_var in $nlist" >&AS_MESSAGE_LOG_FD fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&AS_MESSAGE_LOG_FD fi else echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done ]) if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then AC_MSG_RESULT(failed) else AC_MSG_RESULT(ok) fi _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1], [Take the output of nm and produce a listing of raw symbols and C names]) _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1], [Transform the output of nm in a proper C declaration]) _LT_DECL([global_symbol_to_c_name_address], [lt_cv_sys_global_symbol_to_c_name_address], [1], [Transform the output of nm in a C name address pair]) _LT_DECL([global_symbol_to_c_name_address_lib_prefix], [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1], [Transform the output of nm in a C name address pair when lib prefix is needed]) ]) # _LT_CMD_GLOBAL_SYMBOLS # _LT_COMPILER_PIC([TAGNAME]) # --------------------------- m4_defun([_LT_COMPILER_PIC], [m4_require([_LT_TAG_COMPILER])dnl _LT_TAGVAR(lt_prog_compiler_wl, $1)= _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)= AC_MSG_CHECKING([for $compiler option to produce PIC]) m4_if([$1], [CXX], [ # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else case $host_os in aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, $1)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; ghcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; cxx*) # Digital/Compaq C++ _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. _LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; lcc*) # Lucid _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ], [ if test "$GCC" = yes; then _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac ;; interix[[3-9]]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic fi ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' else _LT_TAGVAR(lt_prog_compiler_static, $1)='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? _LT_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC (with -KPIC) is the default. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; # Lahey Fortran 8.1. lf95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared' _LT_TAGVAR(lt_prog_compiler_static, $1)='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' _LT_TAGVAR(lt_prog_compiler_wl, $1)='' ;; esac ;; esac ;; newsos6) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC -shared' ;; osf3* | osf4* | osf5*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All OSF/1 code is PIC. _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; rdos*) _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' case $cc_basename in f77* | f90* | f95*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';; *) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';; esac ;; sunos4*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then _LT_TAGVAR(lt_prog_compiler_pic, $1)='-Kconform_pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; unicos*) _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; uts4*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-pic' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; *) _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no ;; esac fi ]) case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_TAGVAR(lt_prog_compiler_pic, $1)= ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])" ;; esac AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)]) _LT_TAGDECL([wl], [lt_prog_compiler_wl], [1], [How to pass a linker flag through the compiler]) # # Check to make sure the PIC flag actually works. # if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then _LT_COMPILER_OPTION([if $compiler PIC flag $_LT_TAGVAR(lt_prog_compiler_pic, $1) works], [_LT_TAGVAR(lt_cv_prog_compiler_pic_works, $1)], [$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; *) _LT_TAGVAR(lt_prog_compiler_pic, $1)=" $_LT_TAGVAR(lt_prog_compiler_pic, $1)" ;; esac], [_LT_TAGVAR(lt_prog_compiler_pic, $1)= _LT_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1], [Additional compiler flags for building library objects]) # # Check to make sure the static flag actually works. # wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_TAGVAR(lt_prog_compiler_static, $1)\" _LT_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], _LT_TAGVAR(lt_cv_prog_compiler_static_works, $1), $lt_tmp_static_flag, [], [_LT_TAGVAR(lt_prog_compiler_static, $1)=]) _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1], [Compiler flag to prevent dynamic linking]) ])# _LT_COMPILER_PIC # _LT_LINKER_SHLIBS([TAGNAME]) # ---------------------------- # See if the linker supports building shared libraries. m4_defun([_LT_LINKER_SHLIBS], [AC_REQUIRE([LT_PATH_LD])dnl AC_REQUIRE([LT_PATH_NM])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl m4_require([_LT_DECL_SED])dnl m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl m4_require([_LT_TAG_COMPILER])dnl AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) m4_if([$1], [CXX], [ _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; *) _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ], [ runpath_var= _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_cmds, $1)= _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(old_archive_from_new_cmds, $1)= _LT_TAGVAR(old_archive_from_expsyms_cmds, $1)= _LT_TAGVAR(thread_safe_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list _LT_TAGVAR(include_expsyms, $1)= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu) _LT_TAGVAR(link_all_deplibs, $1)=no ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 _LT_TAGVAR(whole_archive_flag_spec, $1)= tmp_sharedflag='--shared' ;; xl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac _LT_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir' _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) _LT_TAGVAR(ld_shlibs, $1)=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; sunos4*) _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac if test "$_LT_TAGVAR(ld_shlibs, $1)" = no; then runpath_var= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes _LT_TAGVAR(archive_expsym_cmds, $1)='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_TAGVAR(hardcode_minus_L, $1)=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_TAGVAR(hardcode_direct, $1)=unsupported fi ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi _LT_TAGVAR(link_all_deplibs, $1)=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='' ;; m68k) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac ;; bsdi[[45]]*) _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; freebsd1*) _LT_TAGVAR(ld_shlibs, $1)=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; hpux9*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. _LT_TAGVAR(hardcode_minus_L, $1)=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" AC_LINK_IFELSE(int foo(void) {}, _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' ) LDFLAGS="$save_LDFLAGS" else _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes _LT_TAGVAR(link_all_deplibs, $1)=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else _LT_TAGVAR(archive_cmds, $1)='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; newsos6) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' else case $host_os in openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' ;; esac fi else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; os2*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' else _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' fi _LT_TAGVAR(archive_cmds_need_lc, $1)='no' _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' _LT_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' fi ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4) case $host_vendor in sni) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. _LT_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(reload_cmds, $1)='$CC -r -o $output$reload_objs' _LT_TAGVAR(hardcode_direct, $1)=no ;; motorola) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_direct, $1)=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; sysv4.3*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes _LT_TAGVAR(ld_shlibs, $1)=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) _LT_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(ld_shlibs, $1)=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Blargedynsym' ;; esac fi fi ]) AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(with_gnu_ld, $1)=$with_gnu_ld _LT_DECL([], [libext], [0], [Old archive suffix (normally "a")])dnl _LT_DECL([], [shrext_cmds], [1], [Shared library suffix (normally ".so")])dnl _LT_DECL([], [extract_expsyms_cmds], [2], [The commands to extract the exported symbol list from a shared archive]) # # Do we need to explicitly link libc? # case "x$_LT_TAGVAR(archive_cmds_need_lc, $1)" in x|xyes) # Assume -lc should be added _LT_TAGVAR(archive_cmds_need_lc, $1)=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $_LT_TAGVAR(archive_cmds, $1) in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1) pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1) _LT_TAGVAR(allow_undefined_flag, $1)= if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) then _LT_TAGVAR(archive_cmds_need_lc, $1)=no else _LT_TAGVAR(archive_cmds_need_lc, $1)=yes fi _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)]) ;; esac fi ;; esac _LT_TAGDECL([build_libtool_need_lc], [archive_cmds_need_lc], [0], [Whether or not to add -lc for building shared libraries]) _LT_TAGDECL([allow_libtool_libs_with_static_runtimes], [enable_shared_with_static_runtimes], [0], [Whether or not to disallow shared libs when runtime libs are static]) _LT_TAGDECL([], [export_dynamic_flag_spec], [1], [Compiler flag to allow reflexive dlopens]) _LT_TAGDECL([], [whole_archive_flag_spec], [1], [Compiler flag to generate shared objects directly from archives]) _LT_TAGDECL([], [compiler_needs_object], [1], [Whether the compiler copes with passing no objects directly]) _LT_TAGDECL([], [old_archive_from_new_cmds], [2], [Create an old-style archive from a shared archive]) _LT_TAGDECL([], [old_archive_from_expsyms_cmds], [2], [Create a temporary old-style archive to link instead of a shared archive]) _LT_TAGDECL([], [archive_cmds], [2], [Commands used to build a shared archive]) _LT_TAGDECL([], [archive_expsym_cmds], [2]) _LT_TAGDECL([], [module_cmds], [2], [Commands used to build a loadable module if different from building a shared archive.]) _LT_TAGDECL([], [module_expsym_cmds], [2]) _LT_TAGDECL([], [with_gnu_ld], [1], [Whether we are building with GNU ld or not]) _LT_TAGDECL([], [allow_undefined_flag], [1], [Flag that allows shared libraries with undefined symbols to be built]) _LT_TAGDECL([], [no_undefined_flag], [1], [Flag that enforces no undefined symbols]) _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1], [Flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]) _LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1], [[If ld is used when linking, flag to hardcode $libdir into a binary during linking. This must work even if $libdir does not exist]]) _LT_TAGDECL([], [hardcode_libdir_separator], [1], [Whether we need a single "-rpath" flag with a separated argument]) _LT_TAGDECL([], [hardcode_direct], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME${shared_ext} during linking hardcodes DIR into the resulting binary and the resulting library dependency is "absolute", i.e impossible to change by setting ${shlibpath_var} if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_shlibpath_var], [0], [Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into the resulting binary]) _LT_TAGDECL([], [hardcode_automatic], [0], [Set to "yes" if building a shared library automatically hardcodes DIR into the library and all subsequent libraries and executables linked against it]) _LT_TAGDECL([], [inherit_rpath], [0], [Set to yes if linker adds runtime paths of dependent libraries to runtime path list]) _LT_TAGDECL([], [link_all_deplibs], [0], [Whether libtool must link a program against all its dependency libraries]) _LT_TAGDECL([], [fix_srcfile_path], [1], [Fix the shell variable $srcfile for the compiler]) _LT_TAGDECL([], [always_export_symbols], [0], [Set to "yes" if exported symbols are required]) _LT_TAGDECL([], [export_symbols_cmds], [2], [The commands to list exported symbols]) _LT_TAGDECL([], [exclude_expsyms], [1], [Symbols that should not be listed in the preloaded symbols]) _LT_TAGDECL([], [include_expsyms], [1], [Symbols that must always be exported]) _LT_TAGDECL([], [prelink_cmds], [2], [Commands necessary for linking programs (against libraries) with templates]) _LT_TAGDECL([], [file_list_spec], [1], [Specify filename containing input files]) dnl FIXME: Not yet implemented dnl _LT_TAGDECL([], [thread_safe_flag_spec], [1], dnl [Compiler flag to generate thread safe objects]) ])# _LT_LINKER_SHLIBS # _LT_LANG_C_CONFIG([TAG]) # ------------------------ # Ensure that the configuration variables for a C compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_C_CONFIG], [m4_require([_LT_DECL_EGREP])dnl lt_save_CC="$CC" AC_LANG_PUSH(C) # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) LT_SYS_DLOPEN_SELF _LT_CMD_STRIPLIB # Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_CONFIG($1) fi AC_LANG_POP CC="$lt_save_CC" ])# _LT_LANG_C_CONFIG # _LT_PROG_CXX # ------------ # Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++ # compiler, we have our own version here. m4_defun([_LT_PROG_CXX], [ pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes]) AC_PROG_CXX if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then AC_PROG_CXXCPP else _lt_caught_CXX_error=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_CXX dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_CXX], []) # _LT_LANG_CXX_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a C++ compiler are suitably # defined. These variables are subsequently used by _LT_CONFIG to write # the compiler configuration to `libtool'. m4_defun([_LT_LANG_CXX_CONFIG], [AC_REQUIRE([_LT_PROG_CXX])dnl m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_DECL_EGREP])dnl AC_LANG_PUSH(C++) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(compiler_needs_object, $1)=no _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' else _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration LT_PATH_LD # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) _LT_TAGVAR(ld_shlibs, $1)=yes case $host_os in aix3*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. _LT_TAGVAR(archive_cmds, $1)='' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(file_list_spec, $1)='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[[012]]|aix4.[[012]].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 _LT_TAGVAR(hardcode_direct, $1)=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking _LT_TAGVAR(hardcode_minus_L, $1)=yes _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. _LT_TAGVAR(always_export_symbols, $1)=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. _LT_TAGVAR(allow_undefined_flag, $1)='-berok' # Determine the default libpath from the value encoded in an empty # executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_TAGVAR(allow_undefined_flag, $1)="-z nodefs" _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. _LT_SYS_MODULE_PATH_AIX _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_TAGVAR(archive_cmds_need_lc, $1)=yes # This is similar to how AIX traditionally builds its shared # libraries. _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME _LT_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) _LT_DARWIN_LINKER_FEATURES($1) ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; freebsd[[12]]*) # C++ shared libraries reported to be fairly broken before # switch to ELF _LT_TAGVAR(ld_shlibs, $1)=no ;; freebsd-elf*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes ;; gnu*) ;; hpux9*) _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: case $host_cpu in hppa*64*|ia64*) ;; *) _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; interix[[3-9]]*) _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi _LT_TAGVAR(link_all_deplibs, $1)=yes ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: _LT_TAGVAR(inherit_rpath, $1)=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac _LT_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*) _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; m88k*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) _LT_TAGVAR(ld_shlibs, $1)=yes ;; openbsd2*) # C++ shared libraries are fairly broken _LT_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else _LT_TAGVAR(ld_shlibs, $1)=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) _LT_TAGVAR(old_archive_cmds, $1)='$CC -Bstatic -o $oldlib $oldobjs' ;; *) _LT_TAGVAR(old_archive_cmds, $1)='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; cxx*) case $host in osf3*) _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' ;; *) _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*' _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir' ;; esac _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ _LT_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) _LT_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_TAGVAR(link_all_deplibs, $1)=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler _LT_TAGVAR(archive_cmds, $1)='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. _LT_TAGVAR(old_archive_cmds, $1)='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. _LT_TAGVAR(archive_cmds, $1)='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. _LT_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(hardcode_shlibpath_var, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=':' _LT_TAGVAR(link_all_deplibs, $1)=yes _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; *) # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no ;; esac AC_MSG_RESULT([$_LT_TAGVAR(ld_shlibs, $1)]) test "$_LT_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no _LT_TAGVAR(GCC, $1)="$GXX" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes AC_LANG_POP ])# _LT_LANG_CXX_CONFIG # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME]) # --------------------------------- # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. m4_defun([_LT_SYS_HIDDEN_LIBDEPS], [m4_require([_LT_FILEUTILS_DEFAULTS])dnl # Dependencies to place before and after the object being linked: _LT_TAGVAR(predep_objects, $1)= _LT_TAGVAR(postdep_objects, $1)= _LT_TAGVAR(predeps, $1)= _LT_TAGVAR(postdeps, $1)= _LT_TAGVAR(compiler_lib_search_path, $1)= dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each dnl tag define a new lt_????_link_test_code variable, dnl but it's only used here... m4_if([$1], [], [cat > conftest.$ac_ext <<_LT_EOF int a; void foo (void) { a = 0; } _LT_EOF ], [$1], [CXX], [cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF ], [$1], [F77], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer*4 a a=0 return end _LT_EOF ], [$1], [FC], [cat > conftest.$ac_ext <<_LT_EOF subroutine foo implicit none integer a a=0 return end _LT_EOF ], [$1], [GCJ], [cat > conftest.$ac_ext <<_LT_EOF public class foo { private int a; public void bar (void) { a = 0; } }; _LT_EOF ]) dnl Parse the compiler output and extract the necessary dnl objects, libraries and library flags. if AC_TRY_EVAL(ac_compile); then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$_LT_TAGVAR(compiler_lib_search_path, $1)"; then _LT_TAGVAR(compiler_lib_search_path, $1)="${prev}${p}" else _LT_TAGVAR(compiler_lib_search_path, $1)="${_LT_TAGVAR(compiler_lib_search_path, $1)} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$_LT_TAGVAR(postdeps, $1)"; then _LT_TAGVAR(postdeps, $1)="${prev}${p}" else _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$_LT_TAGVAR(predep_objects, $1)"; then _LT_TAGVAR(predep_objects, $1)="$p" else _LT_TAGVAR(predep_objects, $1)="$_LT_TAGVAR(predep_objects, $1) $p" fi else if test -z "$_LT_TAGVAR(postdep_objects, $1)"; then _LT_TAGVAR(postdep_objects, $1)="$p" else _LT_TAGVAR(postdep_objects, $1)="$_LT_TAGVAR(postdep_objects, $1) $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling $1 test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken m4_if([$1], [CXX], [case $host_os in interix[[3-9]]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. _LT_TAGVAR(predep_objects,$1)= _LT_TAGVAR(postdep_objects,$1)= _LT_TAGVAR(postdeps,$1)= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then _LT_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' fi ;; esac ;; esac ]) case " $_LT_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac _LT_TAGVAR(compiler_lib_search_dirs, $1)= if test -n "${_LT_TAGVAR(compiler_lib_search_path, $1)}"; then _LT_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi _LT_TAGDECL([], [compiler_lib_search_dirs], [1], [The directories searched by this compiler when creating a shared library]) _LT_TAGDECL([], [predep_objects], [1], [Dependencies to place before and after the objects being linked to create a shared library]) _LT_TAGDECL([], [postdep_objects], [1]) _LT_TAGDECL([], [predeps], [1]) _LT_TAGDECL([], [postdeps], [1]) _LT_TAGDECL([], [compiler_lib_search_path], [1], [The library search path used internally by the compiler when linking a shared library]) ])# _LT_SYS_HIDDEN_LIBDEPS # _LT_PROG_F77 # ------------ # Since AC_PROG_F77 is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_F77], [ pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes]) AC_PROG_F77 if test -z "$F77" || test "X$F77" = "Xno"; then _lt_disable_F77=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_F77 dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_F77], []) # _LT_LANG_F77_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for a Fortran 77 compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_F77_CONFIG], [AC_REQUIRE([_LT_PROG_F77])dnl AC_LANG_PUSH(Fortran 77) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for f77 test sources. ac_ext=f # Object file extension for compiled f77 test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the F77 compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_F77" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${F77-"f77"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) GCC=$G77 if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$G77" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_F77" != yes AC_LANG_POP ])# _LT_LANG_F77_CONFIG # _LT_PROG_FC # ----------- # Since AC_PROG_FC is broken, in that it returns the empty string # if there is no fortran compiler, we have our own version here. m4_defun([_LT_PROG_FC], [ pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes]) AC_PROG_FC if test -z "$FC" || test "X$FC" = "Xno"; then _lt_disable_FC=yes fi popdef([AC_MSG_ERROR]) ])# _LT_PROG_FC dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([_LT_PROG_FC], []) # _LT_LANG_FC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for a Fortran compiler are # suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_FC_CONFIG], [AC_REQUIRE([_LT_PROG_FC])dnl AC_LANG_PUSH(Fortran) _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(allow_undefined_flag, $1)= _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(archive_expsym_cmds, $1)= _LT_TAGVAR(export_dynamic_flag_spec, $1)= _LT_TAGVAR(hardcode_direct, $1)=no _LT_TAGVAR(hardcode_direct_absolute, $1)=no _LT_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_TAGVAR(hardcode_libdir_separator, $1)= _LT_TAGVAR(hardcode_minus_L, $1)=no _LT_TAGVAR(hardcode_automatic, $1)=no _LT_TAGVAR(inherit_rpath, $1)=no _LT_TAGVAR(module_cmds, $1)= _LT_TAGVAR(module_expsym_cmds, $1)= _LT_TAGVAR(link_all_deplibs, $1)=unknown _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds _LT_TAGVAR(no_undefined_flag, $1)= _LT_TAGVAR(whole_archive_flag_spec, $1)= _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no # Source file extension for fc test sources. ac_ext=${ac_fc_srcext-f} # Object file extension for compiled fc test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # No sense in running all these tests if we already determined that # the FC compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_disable_FC" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="\ subroutine t return end " # Code to be used in simple link tests lt_simple_link_test_code="\ program t end " # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC CC=${FC-"f95"} compiler=$CC GCC=$ac_cv_fc_compiler_gnu _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) if test -n "$compiler"; then AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) AC_MSG_CHECKING([whether to build shared libraries]) test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac AC_MSG_RESULT([$enable_shared]) AC_MSG_CHECKING([whether to build static libraries]) # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) _LT_TAGVAR(GCC, $1)="$ac_cv_fc_compiler_gnu" _LT_TAGVAR(LD, $1)="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... _LT_SYS_HIDDEN_LIBDEPS($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_SYS_DYNAMIC_LINKER($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi # test -n "$compiler" GCC=$lt_save_GCC CC="$lt_save_CC" fi # test "$_lt_disable_FC" != yes AC_LANG_POP ])# _LT_LANG_FC_CONFIG # _LT_LANG_GCJ_CONFIG([TAG]) # -------------------------- # Ensure that the configuration variables for the GNU Java Compiler compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_GCJ_CONFIG], [AC_REQUIRE([LT_PROG_GCJ])dnl AC_LANG_SAVE # Source file extension for Java test sources. ac_ext=java # Object file extension for compiled Java test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC=yes CC=${GCJ-"gcj"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_TAGVAR(LD, $1)="$LD" _LT_CC_BASENAME([$compiler]) # GCJ did not exist at the time GCC didn't implicitly link libc in. _LT_TAGVAR(archive_cmds_need_lc, $1)=no _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds if test -n "$compiler"; then _LT_COMPILER_NO_RTTI($1) _LT_COMPILER_PIC($1) _LT_COMPILER_C_O($1) _LT_COMPILER_FILE_LOCKS($1) _LT_LINKER_SHLIBS($1) _LT_LINKER_HARDCODE_LIBPATH($1) _LT_CONFIG($1) fi AC_LANG_RESTORE GCC=$lt_save_GCC CC="$lt_save_CC" ])# _LT_LANG_GCJ_CONFIG # _LT_LANG_RC_CONFIG([TAG]) # ------------------------- # Ensure that the configuration variables for the Windows resource compiler # are suitably defined. These variables are subsequently used by _LT_CONFIG # to write the compiler configuration to `libtool'. m4_defun([_LT_LANG_RC_CONFIG], [AC_REQUIRE([LT_PROG_RC])dnl AC_LANG_SAVE # Source file extension for RC test sources. ac_ext=rc # Object file extension for compiled RC test sources. objext=o _LT_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_TAG_COMPILER # save warnings/boilerplate of simple test code _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE # Allow CC to be a program name with arguments. lt_save_CC="$CC" lt_save_GCC=$GCC GCC= CC=${RC-"windres"} compiler=$CC _LT_TAGVAR(compiler, $1)=$CC _LT_CC_BASENAME([$compiler]) _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes if test -n "$compiler"; then : _LT_CONFIG($1) fi GCC=$lt_save_GCC AC_LANG_RESTORE CC="$lt_save_CC" ])# _LT_LANG_RC_CONFIG # LT_PROG_GCJ # ----------- AC_DEFUN([LT_PROG_GCJ], [m4_ifdef([AC_PROG_GCJ], [AC_PROG_GCJ], [m4_ifdef([A][M_PROG_GCJ], [A][M_PROG_GCJ], [AC_CHECK_TOOL(GCJ, gcj,) test "x${GCJFLAGS+set}" = xset || GCJFLAGS="-g -O2" AC_SUBST(GCJFLAGS)])])[]dnl ]) # Old name: AU_ALIAS([LT_AC_PROG_GCJ], [LT_PROG_GCJ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_GCJ], []) # LT_PROG_RC # ---------- AC_DEFUN([LT_PROG_RC], [AC_CHECK_TOOL(RC, windres,) ]) # Old name: AU_ALIAS([LT_AC_PROG_RC], [LT_PROG_RC]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_RC], []) # _LT_DECL_EGREP # -------------- # If we don't have a new enough Autoconf to choose the best grep # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_EGREP], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_REQUIRE([AC_PROG_FGREP])dnl test -z "$GREP" && GREP=grep _LT_DECL([], [GREP], [1], [A grep program that handles long lines]) _LT_DECL([], [EGREP], [1], [An ERE matcher]) _LT_DECL([], [FGREP], [1], [A literal string matcher]) dnl Non-bleeding-edge autoconf doesn't subst GREP, so do it here too AC_SUBST([GREP]) ]) # _LT_DECL_OBJDUMP # -------------- # If we don't have a new enough Autoconf to choose the best objdump # available, choose the one first in the user's PATH. m4_defun([_LT_DECL_OBJDUMP], [AC_CHECK_TOOL(OBJDUMP, objdump, false) test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper]) AC_SUBST([OBJDUMP]) ]) # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates # as few characters as possible. Prefer GNU sed if found. m4_defun([_LT_DECL_SED], [AC_PROG_SED test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" _LT_DECL([], [SED], [1], [A sed program that does not truncate output]) _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED m4_ifndef([AC_PROG_SED], [ # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # # macro and use it instead. # m4_defun([AC_PROG_SED], [AC_MSG_CHECKING([for a sed that does not truncate output]) AC_CACHE_VAL(lt_cv_path_SED, [# Loop through the user's path and test for sed and gsed. # Then use that list of sed's as ones to test for truncation. as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris # along with /bin/sed that truncates output. for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do test ! -f $lt_ac_sed && continue cat /dev/null > conftest.in lt_ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >conftest.in # Check for GNU sed and select it if it is found. if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then lt_cv_path_SED=$lt_ac_sed break fi while true; do cat conftest.in conftest.in >conftest.tmp mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break cmp -s conftest.out conftest.nl || break # 10000 chars as input seems more than enough test $lt_ac_count -gt 10 && break lt_ac_count=`expr $lt_ac_count + 1` if test $lt_ac_count -gt $lt_ac_max; then lt_ac_max=$lt_ac_count lt_cv_path_SED=$lt_ac_sed fi done done ]) SED=$lt_cv_path_SED AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ])#AC_PROG_SED ])#m4_ifndef # Old name: AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) # _LT_CHECK_SHELL_FEATURES # ------------------------ # Find out whether the shell is Bourne or XSI compatible, # or has some other useful features. m4_defun([_LT_CHECK_SHELL_FEATURES], [AC_MSG_CHECKING([whether the shell understands some XSI constructs]) # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes AC_MSG_RESULT([$xsi_shell]) _LT_CONFIG_LIBTOOL_INIT([xsi_shell='$xsi_shell']) AC_MSG_CHECKING([whether the shell understands "+="]) lt_shell_append=no ( foo=bar; set foo baz; eval "$[1]+=\$[2]" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes AC_MSG_RESULT([$lt_shell_append]) _LT_CONFIG_LIBTOOL_INIT([lt_shell_append='$lt_shell_append']) if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi _LT_DECL([], [lt_unset], [0], [whether the shell understands "unset"])dnl # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac _LT_DECL([SP2NL], [lt_SP2NL], [1], [turn spaces into newlines])dnl _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl ])# _LT_CHECK_SHELL_FEATURES # _LT_PROG_XSI_SHELLFNS # --------------------- # Bourne and XSI compatible variants of some useful shell functions. m4_defun([_LT_PROG_XSI_SHELLFNS], [case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $[*] )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } dnl func_dirname_and_basename dnl A portable version of this function is already defined in general.m4sh dnl so there is no need for it here. # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[[^=]]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$[@]"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]+=\$[2]" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$[1]=\$$[1]\$[2]" } _LT_EOF ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) # _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME) # ------------------------------------------ m4_define([_LT_MANGLE_OPTION], [[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])]) # _LT_SET_OPTION(MACRO-NAME, OPTION-NAME) # --------------------------------------- # Set option OPTION-NAME for macro MACRO-NAME, and if there is a # matching handler defined, dispatch to it. Other OPTION-NAMEs are # saved as a flag. m4_define([_LT_SET_OPTION], [m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]), _LT_MANGLE_DEFUN([$1], [$2]), [m4_warning([Unknown $1 option `$2'])])[]dnl ]) # _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET]) # ------------------------------------------------------------ # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. m4_define([_LT_IF_OPTION], [m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])]) # _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET) # ------------------------------------------------------- # Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME # are set. m4_define([_LT_UNLESS_OPTIONS], [m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option), [m4_define([$0_found])])])[]dnl m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3 ])[]dnl ]) # _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST) # ---------------------------------------- # OPTION-LIST is a space-separated list of Libtool options associated # with MACRO-NAME. If any OPTION has a matching handler declared with # LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about # the unknown option and exit. m4_defun([_LT_SET_OPTIONS], [# Set options m4_foreach([_LT_Option], m4_split(m4_normalize([$2])), [_LT_SET_OPTION([$1], _LT_Option)]) m4_if([$1],[LT_INIT],[ dnl dnl Simply set some default values (i.e off) if boolean options were not dnl specified: _LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no ]) _LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no ]) dnl dnl If no reference was made to various pairs of opposing options, then dnl we run the default mode handler for the pair. For example, if neither dnl `shared' nor `disable-shared' was passed, we enable building of shared dnl archives by default: _LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED]) _LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC]) _LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC]) _LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install], [_LT_ENABLE_FAST_INSTALL]) ]) ])# _LT_SET_OPTIONS # _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME) # ----------------------------------------- m4_define([_LT_MANGLE_DEFUN], [[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])]) # LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE) # ----------------------------------------------- m4_define([LT_OPTION_DEFINE], [m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl ])# LT_OPTION_DEFINE # dlopen # ------ LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes ]) AU_DEFUN([AC_LIBTOOL_DLOPEN], [_LT_SET_OPTION([LT_INIT], [dlopen]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `dlopen' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], []) # win32-dll # --------- # Declare package support for building win32 dll's. LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) ;; esac test -z "$AS" && AS=as _LT_DECL([], [AS], [0], [Assembler program])dnl test -z "$DLLTOOL" && DLLTOOL=dlltool _LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl test -z "$OBJDUMP" && OBJDUMP=objdump _LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl ])# win32-dll AU_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_REQUIRE([AC_CANONICAL_HOST])dnl _LT_SET_OPTION([LT_INIT], [win32-dll]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `win32-dll' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], []) # _LT_ENABLE_SHARED([DEFAULT]) # ---------------------------- # implement the --enable-shared flag, and supports the `shared' and # `disable-shared' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_SHARED], [m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([shared], [AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@], [build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_shared=]_LT_ENABLE_SHARED_DEFAULT) _LT_DECL([build_libtool_libs], [enable_shared], [0], [Whether or not to build shared libraries]) ])# _LT_ENABLE_SHARED LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])]) # Old names: AC_DEFUN([AC_ENABLE_SHARED], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared]) ]) AC_DEFUN([AC_DISABLE_SHARED], [_LT_SET_OPTION([LT_INIT], [disable-shared]) ]) AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)]) AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_SHARED], []) dnl AC_DEFUN([AM_DISABLE_SHARED], []) # _LT_ENABLE_STATIC([DEFAULT]) # ---------------------------- # implement the --enable-static flag, and support the `static' and # `disable-static' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_STATIC], [m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([static], [AS_HELP_STRING([--enable-static@<:@=PKGS@:>@], [build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_static=]_LT_ENABLE_STATIC_DEFAULT) _LT_DECL([build_old_libs], [enable_static], [0], [Whether or not to build static libraries]) ])# _LT_ENABLE_STATIC LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])]) # Old names: AC_DEFUN([AC_ENABLE_STATIC], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static]) ]) AC_DEFUN([AC_DISABLE_STATIC], [_LT_SET_OPTION([LT_INIT], [disable-static]) ]) AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)]) AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AM_ENABLE_STATIC], []) dnl AC_DEFUN([AM_DISABLE_STATIC], []) # _LT_ENABLE_FAST_INSTALL([DEFAULT]) # ---------------------------------- # implement the --enable-fast-install flag, and support the `fast-install' # and `disable-fast-install' LT_INIT options. # DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'. m4_define([_LT_ENABLE_FAST_INSTALL], [m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl AC_ARG_ENABLE([fast-install], [AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@], [optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])], [p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac], [enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT) _LT_DECL([fast_install], [enable_fast_install], [0], [Whether or not to optimize for fast installation])dnl ])# _LT_ENABLE_FAST_INSTALL LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])]) LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])]) # Old names: AU_DEFUN([AC_ENABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `fast-install' option into LT_INIT's first parameter.]) ]) AU_DEFUN([AC_DISABLE_FAST_INSTALL], [_LT_SET_OPTION([LT_INIT], [disable-fast-install]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `disable-fast-install' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], []) dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], []) # _LT_WITH_PIC([MODE]) # -------------------- # implement the --with-pic flag, and support the `pic-only' and `no-pic' # LT_INIT options. # MODE is either `yes' or `no'. If omitted, it defaults to `both'. m4_define([_LT_WITH_PIC], [AC_ARG_WITH([pic], [AS_HELP_STRING([--with-pic], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [pic_mode="$withval"], [pic_mode=default]) test -z "$pic_mode" && pic_mode=m4_default([$1], [default]) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])]) LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])]) # Old name: AU_DEFUN([AC_LIBTOOL_PICMODE], [_LT_SET_OPTION([LT_INIT], [pic-only]) AC_DIAGNOSE([obsolete], [$0: Remove this warning and the call to _LT_SET_OPTION when you put the `pic-only' option into LT_INIT's first parameter.]) ]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([AC_LIBTOOL_PICMODE], []) m4_define([_LTDL_MODE], []) LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive], [m4_define([_LTDL_MODE], [nonrecursive])]) LT_OPTION_DEFINE([LTDL_INIT], [recursive], [m4_define([_LTDL_MODE], [recursive])]) LT_OPTION_DEFINE([LTDL_INIT], [subproject], [m4_define([_LTDL_MODE], [subproject])]) m4_define([_LTDL_TYPE], []) LT_OPTION_DEFINE([LTDL_INIT], [installable], [m4_define([_LTDL_TYPE], [installable])]) LT_OPTION_DEFINE([LTDL_INIT], [convenience], [m4_define([_LTDL_TYPE], [convenience])]) # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 6 ltsugar.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])]) # lt_join(SEP, ARG1, [ARG2...]) # ----------------------------- # Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their # associated separator. # Needed until we can rely on m4_join from Autoconf 2.62, since all earlier # versions in m4sugar had bugs. m4_define([lt_join], [m4_if([$#], [1], [], [$#], [2], [[$2]], [m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])]) m4_define([_lt_join], [m4_if([$#$2], [2], [], [m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])]) # lt_car(LIST) # lt_cdr(LIST) # ------------ # Manipulate m4 lists. # These macros are necessary as long as will still need to support # Autoconf-2.59 which quotes differently. m4_define([lt_car], [[$1]]) m4_define([lt_cdr], [m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])], [$#], 1, [], [m4_dquote(m4_shift($@))])]) m4_define([lt_unquote], $1) # lt_append(MACRO-NAME, STRING, [SEPARATOR]) # ------------------------------------------ # Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'. # Note that neither SEPARATOR nor STRING are expanded; they are appended # to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked). # No SEPARATOR is output if MACRO-NAME was previously undefined (different # than defined and empty). # # This macro is needed until we can rely on Autoconf 2.62, since earlier # versions of m4sugar mistakenly expanded SEPARATOR but not STRING. m4_define([lt_append], [m4_define([$1], m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])]) # lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...]) # ---------------------------------------------------------- # Produce a SEP delimited list of all paired combinations of elements of # PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list # has the form PREFIXmINFIXSUFFIXn. # Needed until we can rely on m4_combine added in Autoconf 2.62. m4_define([lt_combine], [m4_if(m4_eval([$# > 3]), [1], [m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl [[m4_foreach([_Lt_prefix], [$2], [m4_foreach([_Lt_suffix], ]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[, [_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])]) # lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ]) # ----------------------------------------------------------------------- # Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited # by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ. m4_define([lt_if_append_uniq], [m4_ifdef([$1], [m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1], [lt_append([$1], [$2], [$3])$4], [$5])], [lt_append([$1], [$2], [$3])$4])]) # lt_dict_add(DICT, KEY, VALUE) # ----------------------------- m4_define([lt_dict_add], [m4_define([$1($2)], [$3])]) # lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE) # -------------------------------------------- m4_define([lt_dict_add_subkey], [m4_define([$1($2:$3)], [$4])]) # lt_dict_fetch(DICT, KEY, [SUBKEY]) # ---------------------------------- m4_define([lt_dict_fetch], [m4_ifval([$3], m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]), m4_ifdef([$1($2)], [m4_defn([$1($2)])]))]) # lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE]) # ----------------------------------------------------------------- m4_define([lt_if_dict_fetch], [m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4], [$5], [$6])]) # lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...]) # -------------------------------------------------------------- m4_define([lt_dict_filter], [m4_if([$5], [], [], [lt_join(m4_quote(m4_default([$4], [[, ]])), lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]), [lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl ]) # ltversion.m4 -- version numbers -*- Autoconf -*- # # Copyright (C) 2004 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # Generated from ltversion.in. # serial 3017 ltversion.m4 # This file is part of GNU Libtool m4_define([LT_PACKAGE_VERSION], [2.2.6b]) m4_define([LT_PACKAGE_REVISION], [1.3017]) AC_DEFUN([LTVERSION_VERSION], [macro_version='2.2.6b' macro_revision='1.3017' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # # Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. # serial 4 lt~obsolete.m4 # These exist entirely to fool aclocal when bootstrapping libtool. # # In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN) # which have later been changed to m4_define as they aren't part of the # exported API, or moved to Autoconf or Automake where they belong. # # The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN # in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us # using a macro with the same name in our local m4/libtool.m4 it'll # pull the old libtool.m4 in (it doesn't see our shiny new m4_define # and doesn't know about Autoconf macros at all.) # # So we provide this file, which has a silly filename so it's always # included after everything else. This provides aclocal with the # AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything # because those macros already exist, or will be overwritten later. # We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6. # # Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here. # Yes, that means every name once taken will need to remain here until # we give up compatibility with versions before 1.7, at which point # we need to keep only those names which we still refer to. # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])]) m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])]) m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])]) m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])]) m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])]) m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])]) m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])]) m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])]) m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])]) m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])]) m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])]) m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])]) m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])]) m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])]) m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])]) m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])]) m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])]) m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])]) m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])]) m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])]) m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])]) m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])]) m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])]) m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])]) m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])]) m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])]) m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])]) m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])]) m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])]) m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])]) m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])]) m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])]) m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])]) m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])]) m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])]) m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])]) m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])]) m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])]) m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])]) m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])]) m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])]) m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])]) m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])]) m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])]) m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])]) m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])]) m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])]) m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])]) m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])]) m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])]) m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])]) m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])]) # Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.11' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.11.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.11.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to # `$srcdir', `$srcdir/..', or `$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is `.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [dnl Rely on autoconf to set up CDPATH properly. AC_PREREQ([2.50])dnl # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 9 # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ(2.52)dnl ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 10 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "GCJ", or "OBJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl ifelse([$1], CC, [depcc="$CC" am_compiler_list=], [$1], CXX, [depcc="$CXX" am_compiler_list=], [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], UPC, [depcc="$UPC" am_compiler_list=], [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE(dependency-tracking, [ --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. #serial 5 # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`AS_DIRNAME("$mf")` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`AS_DIRNAME(["$file"])` AS_MKDIR_P([$dirpart/$fdir]) # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking # is enabled. FIXME. This creates each `.P' file that we will # need in order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) ]) # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 8 # AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, # 2005, 2006, 2008, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 16 # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.62])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) AM_MISSING_PROG(AUTOCONF, autoconf) AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) AM_MISSING_PROG(AUTOHEADER, autoheader) AM_MISSING_PROG(MAKEINFO, makeinfo) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AM_PROG_MKDIR_P])dnl # We need awk for the "check" target. The system "awk" is bad on # some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES(CC)], [define([AC_PROG_CC], defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES(CXX)], [define([AC_PROG_CXX], defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES(OBJC)], [define([AC_PROG_OBJC], defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl ]) _AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl dnl The `parallel-tests' driver may need to know about EXEEXT, so add the dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro dnl is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl ]) dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST(install_sh)]) # Copyright (C) 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # AM_MAKE_INCLUDE() # ----------------- # Check to see how make treats includes. AC_DEFUN([AM_MAKE_INCLUDE], [am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi AC_SUBST([am__include]) AC_SUBST([am__quote]) AC_MSG_RESULT([$_am_result]) rm -f confinc confmf ]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 6 # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it supports --run. # If it does, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= AC_MSG_WARN([`missing' script is too old or missing]) fi ]) # Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_MKDIR_P # --------------- # Check for `mkdir -p'. AC_DEFUN([AM_PROG_MKDIR_P], [AC_PREREQ([2.60])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P, dnl while keeping a definition of mkdir_p for backward compatibility. dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile. dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of dnl Makefile.ins that do not define MKDIR_P, so we do our own dnl adjustment using top_builddir (which is defined more often than dnl MKDIR_P). AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl case $mkdir_p in [[\\/$]]* | ?:[[\\/]]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 4 # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # ------------------------------ # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), 1)]) # _AM_SET_OPTIONS(OPTIONS) # ---------------------------------- # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008 # Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 5 # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT(yes)]) # Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor `install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in `make install-strip', and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be `maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006, 2008 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004, 2005 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # serial 2 # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of `v7', `ustar', or `pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. AM_MISSING_PROG([AMTAR], [tar]) m4_if([$1], [v7], [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], [m4_case([$1], [ustar],, [pax],, [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' _am_tools=${am_cv_prog_tar_$1-$_am_tools} # Do not fold the above two line into one, because Tru64 sh and # Solaris sh will not grok spaces in the rhs of `-'. for _am_tool in $_am_tools do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR odin-1.8.5/README0000644000175000017500000000260211322062355010256 00000000000000Welcome to ODIN - the Object oriented Development Interface for NMR ------------------------------------------------------------------- ODIN is an open-source framework for magnetic resonance imaging (MRI). It covers the whole toolchain of MRI, from low-level data acquisition to image reconstruction. In particular, it aims at rapid prototyping of MRI sequences. The sequences can be programmed using a high-level, object oriented, C++ programming interface. It provides advanced sequence analysis tools, such as interactive plotting of k-space trajectories, a user interface for a fast compile-link-test cycle and a powerful MRI simulator which supports different virtual samples. For fast and flexible image reconstruction, ODIN contains a highly customizable, multi-threaded data-processing framework. In addition, ODIN features useful command-line utilities for converting, manipulating and viewing medical image data in various formats (DICOM, NIfTI, binary data, ...). For installation instructions, please see the file 'INSTALL' file. For up-to-date documentation, please take a look at http://od1n.sourceforge.net/documentation.html http://od1n.sourceforge.net/manual/html/index.html The subdirectory 'platforms' contains a short description (HOWTO.txt) how to set up ODIN to work together with the different scanners. For sequence examples, please take a look at the 'sequences' subdirectory. odin-1.8.5/install.macos0000755000175000017500000000557511322062355012107 00000000000000#!/bin/bash # wrapper script to install ODIN on MacOS X command="`basename $0`" usage="usage: $command [-d] " EXTRA_CONFIG_OPTS="" continue="yes" while [ $continue = "yes" ] ; do case "$1" in -d) EXTRA_CONFIG_OPTS="--enable-debug" ; shift 1 ;; *) continue="no" ;; esac done case $# in 2) QTDIR="$1"; INSTALLDIR="$2";; *) echo $usage; exit;; esac if [ ! -f configure ] ; then if ! ./bootstrap then exit -1 fi fi if test -z $(which g++-4.2) ; then # Tiger -> Optimization does not work MCXX="g++" MCXXFLAGS="-O0" else # Leopard -> Optimization only works with GCC4.2 MCXX="g++-4.2" MCXXFLAGS="" fi if [ ! -f Makefile ] ; then if ! LDFLAGS="-Wl,-multiply_defined,suppress" \ CXX="$MCXX" CXXFLAGS="$MCXXFLAGS" \ ./configure $EXTRA_CONFIG_OPTS --with-qt-dir=$QTDIR --prefix=$INSTALLDIR \ --with-extra-include-base=$INSTALLDIR/include \ --with-extra-build-ldflags="-Wl,-F${QTDIR}/lib -Wl,-framework,QtGui,-framework,QtCore,-framework,vecLib" then exit -1 fi fi if ! make install ; then exit -1 fi # Creating bundles for GUI applications for APPLICATION in odin pulsar geoedit miview; do if test -f $INSTALLDIR/bin/$APPLICATION ; then echo -n "Creating bundle for $APPLICATION ..." APPDIR=$INSTALLDIR/bin/$APPLICATION.app mkdir -p $APPDIR echo "APPL????" > $APPDIR/PkgInfo mkdir -p $APPDIR/Contents INFO_PLIST_FILE=$APPDIR/Contents/Info.plist echo "" > $INFO_PLIST_FILE echo "" >> $INFO_PLIST_FILE echo "" >> $INFO_PLIST_FILE echo "" >> $INFO_PLIST_FILE echo " CFBundleIconFile" >> $INFO_PLIST_FILE echo " " >> $INFO_PLIST_FILE echo " CFBundlePackageType" >> $INFO_PLIST_FILE echo " APPL" >> $INFO_PLIST_FILE echo " CFBundleGetInfoString" >> $INFO_PLIST_FILE echo " Created by ODIN" >> $INFO_PLIST_FILE echo " CFBundleSignature" >> $INFO_PLIST_FILE echo " ????" >> $INFO_PLIST_FILE echo " CFBundleExecutable" >> $INFO_PLIST_FILE echo " $APPLICATION" >> $INFO_PLIST_FILE echo " NOTE" >> $INFO_PLIST_FILE echo " Please, do NOT change this file -- It was generated by ODIN" >> $INFO_PLIST_FILE echo "" >> $INFO_PLIST_FILE echo "" >> $INFO_PLIST_FILE mkdir -p $APPDIR/Contents/MacOS mv $INSTALLDIR/bin/$APPLICATION $APPDIR/Contents/MacOS START_SCRIPT=$INSTALLDIR/bin/$APPLICATION echo "#!/bin/sh" > $START_SCRIPT echo "\`dirname \$0\`/$APPLICATION.app/Contents/MacOS/$APPLICATION \$*" >> $START_SCRIPT chmod 755 $START_SCRIPT echo "done" fi done odin-1.8.5/samples/0000755000175000017500000000000011735135552011132 500000000000000odin-1.8.5/samples/Makefile.am0000644000175000017500000000036211455553545013114 00000000000000EXTRA_DIST = modifiedSheppLogan_128x128.smp brain_128x128.smp qualityPhantom_128x128.smp point_spread_function.smp frequency_dist.smp disk_128x128.smp if ONLY_LIBS else sampledir = $(datadir)/odin/samples sample_DATA = $(EXTRA_DIST) endif odin-1.8.5/samples/Makefile.in0000644000175000017500000002713111734622602013117 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = samples DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(sampledir)" DATA = $(sample_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = modifiedSheppLogan_128x128.smp brain_128x128.smp qualityPhantom_128x128.smp point_spread_function.smp frequency_dist.smp disk_128x128.smp @ONLY_LIBS_FALSE@sampledir = $(datadir)/odin/samples @ONLY_LIBS_FALSE@sample_DATA = $(EXTRA_DIST) all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu samples/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu samples/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-sampleDATA: $(sample_DATA) @$(NORMAL_INSTALL) test -z "$(sampledir)" || $(MKDIR_P) "$(DESTDIR)$(sampledir)" @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(sampledir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(sampledir)" || exit $$?; \ done uninstall-sampleDATA: @$(NORMAL_UNINSTALL) @list='$(sample_DATA)'; test -n "$(sampledir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(sampledir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(sampledir)" && rm -f $$files tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(DATA) installdirs: for dir in "$(DESTDIR)$(sampledir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-sampleDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-sampleDATA .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-sampleDATA \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ uninstall uninstall-am uninstall-sampleDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/samples/modifiedSheppLogan_128x128.smp0000644000175000017500000025556411363773560016376 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 200.0 200.0 5.0 ##$FrequencyRange=10.0 ##$FrequencyOffset=0.0 ##$RelaxationT1=1000.0 ##$RelaxationT2=100.0 ##$T1map=( 0 ) ##$T2map=( 0 ) ##$ppmMap=( 0 ) ##$spinDensity=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAP83M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAA gD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKSamZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApJqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkzczMPZqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApM3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9 zczMPZqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+ zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9zczMPZqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICk zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3M zD3NzMw9mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+AACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkzczMPc3MzD3NzMw9mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk zczMPc3MzD2amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9zczMPc3MzD2amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKTNzMw9zczMPZqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+ mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD4AAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9zczMPZqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+ zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKTNzMw9mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+mpmZPpqZ mT6amZk+mpmZPpqZmT6amZk+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9mpmZPpqZmT6amZk+ mpmZPs3MzD7NzMw+zczMPs3MzD6amZk+mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPgAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKTNzEw+mpmZPpqZmT7NzMw+zczMPs3MzD7NzMw+zczMPs3MzD6amZk+ mpmZPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPpqZ mT7NzMw+zczMPs3MzD7NzMw+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApM3MTD7NzEw+mpmZPpqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+ mpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD6amZk+ mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkmpmZPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD4AAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MzD2amZk+mpmZPpqZ mT6amZk+mpmZPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzczMPZqZmT6amZk+mpmZPpqZmT6amZk+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD/NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzMw9mpmZPpqZmT6amZk+ mpmZPpqZmT7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKSamZk+mpmZPpqZmT6amZk+zcxMPs3MTD7NzEw+AACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAA gD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICk AACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICk AACApM3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApM3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAA gKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAA gKTNzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgKQAAICkAACApAAAgKQAAICk AACApAAAgKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAICkAACApAAAgKQAAICkAACApAAAgKQAAICkAACApAAAgKTNzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAICkAACApAAA gKQAAICkAACApAAAgKQAAICkzcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACApAAAgKQAAICkAACApM3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPpqZmT6amZk+ mpmZPpqZmT7NzEw+zcxMPpqZmT6amZk+zcxMPpqZmT6amZk+mpmZPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZmT6amZk+mpmZPpqZmT7NzEw+mpmZPpqZmT7NzEw+ mpmZPpqZmT6amZk+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD6amZk+mpmZPpqZ mT6amZk+zcxMPs3MTD6amZk+mpmZPs3MTD6amZk+mpmZPpqZmT7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD6amZk+mpmZPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD/NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD4AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+ zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD8AAIA/AACAPwAAgD/NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3M TD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPs3MTD4AAIA/AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAP83MTD7NzEw+zcxMPs3MTD7NzEw+zcxMPgAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$B1map=( 0 ) ##$DcoeffMap=( 0 ) ##END= odin-1.8.5/samples/disk_128x128.smp0000644000175000017500000025556311363773560013566 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 200.0 200.0 1.0 ##$FrequencyRange=10.0 ##$FrequencyOffset=0.0 ##$RelaxationT1=800.0 ##$RelaxationT2=200.0 ##$T1map=( 0 ) ##$T2map=( 0 ) ##$ppmMap=( 0 ) ##$spinDensity=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/ AACAPwAAgD8AAIA/AACAPwAAgD8AAIA/AACAPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIA/AACAPwAA gD8AAIA/AACAPwAAgD8AAIA/AACAPwAAgD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$B1map=( 0 ) ##$DcoeffMap=( 0 ) ##END= odin-1.8.5/samples/point_spread_function.smp0000644000175000017500000000055411363773560016177 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 1.0e-6 1.0e-6 1.0e-6 ##$FrequencyRange=10.0 ##$FrequencyOffset=0.0 ##$RelaxationT1=0.0 ##$RelaxationT2=0.0 ##$T1map=( 1, 1, 1, 1, 1 ) 1300.0 ##$T2map=( 1, 1, 1, 1, 1 ) 80.0 ##$ppmMap=( 0 ) ##$spinDensity=( 1, 1, 1, 1, 1 ) 1.0 ##$B1map=( 0 ) ##$DcoeffMap=( 1, 1, 1, 1, 1 ) 0.0 ##END= odin-1.8.5/samples/brain_128x128.smp0000644000175000017500000126510711363773560013723 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 200.0 200.0 4.0 ##$FrequencyRange=10.0 ##$FrequencyOffset=0.0 ##$RelaxationT1=0.0 ##$RelaxationT2=0.0 ##$T1map=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMGm kUQUK4tEAAAAAKT2bUT8RppEUXaKRFtKo0QKPoREeZ6PRAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAodIBE E1GNRHOUUUSP62pEaSdxRN0PN0SplHREiwyFRPRhiUSXBF1Et/RjRJaUckSGynhEbOFMRILg iERi7IREdlF/RK7kiUTOy4BElHGORGbLa0QOj3pEfHqJRAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABFaztEaSVLRAw2CETkpztEOxWRQwAAAABsfBBDM4zaQ3YCX0NDOTRD AAAAAAAAAAAAAAAA8KTpQwAAAABRj4BDz+qRQwAAAAAAAAAAAAAAAAAAAABRIjBEuL4RRPZ/ kEQMCo1EAAAAAJQZpETezo9EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/YLURl+ElELpq8RAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABeGI0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEoeGRJgQPkMAAAAAAAAAAAAAAAAAAAAAtAiNRAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGgl0TIdu1E AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAIU4ZDVR+zQwAAAAAAAAAAAAAAAK/XlkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAACSyGETvLZBEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMPinEMAAPpE AAAAADbqokR4BqVEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADF5a0QAAPpEVP3LQgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMj360MAAAAAAAAAAAAAAACLJpZEdgVnRAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAByMZlE fcChRAAAAAAAAAAARDuoRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAFUOmkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+kQAAPpE AAD6RAAA+kRLWLpEcrOlRGyCp0SRc7dEA/uRRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAC626JDAAAAAAAAAAB9VZpEzCGLRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABOChVEWlUXRB/E1UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAymrMRC53qkQUz75ECMnMRBcmsUQAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAPpEAAD6RAAA+kQAAPpEAAD6RPnrn0T0lYpEyQqFRHleqUQAAPpE AAD6RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADS3XVDozRVRAAAAAAAAAAAJ+mXRAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCohdE+qoNRMIaXEQAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8y9BEAAD6RPbpyES1waJE 55+JRJQdl0QaKrVER6LyRAAAAAAAAAAAAAAAAAAAAACiKc5EAAD6RAAA+kSGp/REAAD6RAAA +kQAAPpEmYCURE3ab0RPGypEgNiRROXDykQSrr5EEF3ARJLGwUQAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAR3zNDR3KXQwAAAAAAAAAAhw2mRNR6MEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA O7ZrRGZ8iESdQVREAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAANO+ZECWWjRMLNnUQAAPpEvfe/RFu7jkQ22EREobqKRENNokTbkLJELajdRAAAAAAAAAAA AAAAAAAAAAAAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kTZsr5EpsOaRLVmHUQhuS9EsQ6XRLG2 i0T1WZJE5kSKRP1dq0QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUZXxDthWCQwAAAAAAAAAA LdWkRIwKiUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAr49RE8/oERWrw1DIRtAQwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6RAqGqEQvUIdEEGWFREjrukTMDMNE4EWRRKE7 U0QHClxE+/KERJY0n0QZn8lEAAAAAAAAAAAAAAAAAAAAAAAA+kQAAPpEAAD6RP9c6kTeXKpE 4czURAAA+kRJ1sREn4t0REH3JETM4iFEAaxdREmxO0Q6yIJECVCsRAAA+kQAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAC/dJtDivurQwAAAAAAAAAA9bGZRLbXi0TfKYREAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPWoTUTxVllEwi8KQwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAooeuRGkWwEQAAPpE WXeoRHQjakS8gYREOVPTRLFKvES7jodEK6BrRFTtLkRovixEltmPRIFnrEQAAPpEAAAAAAAA AAAAAPpEAAAAAAAA+kQUn/dEVg+ZRGmRgkQ09J5EeEaxRN4Mt0TKl6lEktMtRE7TFETkZ0FE hTJFROQxiUTusctEAAD6RAAA+kR3fNlEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF/arQwAA AAAAAAAAAAAAAPabiEQmXZJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 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 0UOYROyfj0SkOoVEu0RgRMixL0RmVSJECSCTRN7gqEQAAPpEHh/pRBHUpkR8FbdEi0qzRICd r0Ry97VEAAD6RAAA+kRzw/BE2l7wRAAA+kQAAPpEAAD6RAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkXmXRAAA AABFj3NEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAk+jeRAAA+kREheJEW8LbRISbuURRwcRE S2/AREOr4EQAAPpEAAD6RAAA+kSUPNlEvoGpRINDzURhBa9EKr+vRPenbUR1HytEBbV5RNSO t0R6kZpEqUzTRAAAAAAAAPpEAAD6RKFGvUQR+qVEmw+cROyknUSE655ERsNCRFXrOEQ+0npE go+WROMFxUQVCeJEoSrtRAAA+kQAAPpEOMPtRDE39UQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA +kRhyYJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMrofEQAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAACHQWhDBaRGRAAAAACCGqVEAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAD6RAAA+kQAAPpEAAD6RCO01ES/l91EAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpE Eh/lRP2CxUQvmMREOh+YRFRcSkRUj3tEwq6qREWgvUT/LdNEAAD6RAAA+kQAAPpEFv3NRKo7 wURMFqpEHHO1RP0FlkSXPT5E5iM7RAWlfkR2CoVELH26ROgiu0SjOOBE7B3fRAAA+kQAAPpE AAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEPl+4RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAADbmaZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD6RAAA+kQAAPpEAAD6RAAA +kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kTIRNVECbGvRCMkrUTMzMNE+n6ZRMMZr0SSBJtE coPwRAAA+kQAAPpEAAAAAAAA+kQAAPpEXGTHREq/n0QVvqhEXwyhRIPAX0STSYVEZuqRRF98 rkQgXLdET5SyRE6itUR7pulEMpznRAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOVVfRAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RKVn qkSSvcNEYxKtRESxvERicKtExG22RMEDwkQc39tEAAD6RAAA+kQAAPpEAAD6RAAA+kTLvbhE 5RK0RMQ+oUSmfJhEpDChRFQlvUTrp6lEqc3URAokxkRF//ZEAAD6RAAA+kQNOuJEAAD6RAAA +kQAAPpEAAD6RAAA+kRuu+ZEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdAOkQAAAAA GrWRRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAajb5QwAAAAAAAAAAkcNbRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPpE AAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpE23rhRB8BtUS8irBEyTavRGs5mESFR5JEj1yyRIQx +EQAAPpEAAAAABrm60QAAPpEAAD6RB+O6kT3UsxEVdugRDxRqURg2LVEk367RExe00QUOMtE AAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACF505EAAAAAP/YkEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHeLvQwAAAAAAAAAAlMloRAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpE 1n7jRBBmxUTxQL9Ekgi8ROpHukTERrFEAAD6RAAA+kQAAPpEAAAAAAAA+kQAAPpEAAD6RDJc +ES1bLhE2H21ROqPxUQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpE AAD6RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbnJJRAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAM73FkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kRLnclEzX3LRDSh5UQAAPpE AAD6RPipp0QAAAAAAAAAAAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA +kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAJRuuEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKUK+0MAAAAA AAAAAORfOEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPpEAAD6RAAA +kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+kQAAPpE AAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAD6RAAA+kQAAPpEAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAALHdDkQAAAAAAAAAAEw1QkQAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAACkqGkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGcT90QAAPpEAAD6RAAA+kQAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPpEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACSHD1EAAAAAAAA AACNuGJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AABxC05EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABb6hxEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1NcWRAAAAAAAAAAAAAAAAJpI PUQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGGGOkTyL5VDAAAAAAAAAAAsZGBEAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAk6QYRGRaR0TeQlNDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZJSNRAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAza5eRNJNEkQw9hJEAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7tnNE 3mQiRL7RDkQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhrY4RNHcYESi3k1EAAAAANiIMUQAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADZTVFE tplGRPOSNEQa9iNEUsYARCKYiUMAAAAAAAAAAJGOA0OgjKNEAAAAAAAAAAAvnvhDZsSxRAAA AABTUuFDPwMfRJ0mFEQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKX6NRAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 8yNzRAAAAACSr21EoyVRRAAAAAAAAAAA4h88RAAAAAAAAAAAP+x8RMoIWkT0sXdEOERzRIs6 Z0Q4XXJEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$T2map=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABf7 UUIBHC1CAAAAAA7uXUIxSoJCYoaHQovffUKCuZ1CVM6AQgAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABKn5pC KFl7QlXXdEJwP3tCYPeaQqUSh0KH1IlCn3iRQhRhk0LGXI5C84uTQrDokUKiu4JC/26aQhlQ lEKT7JJCjMSNQvvSiUJqnH9CYnBoQsTlb0J/MUdC93NrQgAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACw9ZZCNZyZQmoHp0JS6adC4AOkQgAAAACMyL1CQIXHQqweq0ITl7JC AAAAAAAAAAAAAAAA4O6mQgAAAAA9zLpCEiGyQgAAAAAAAAAAAAAAAAAAAADdU5pCO3qxQleC hkI1OopCAAAAAL2XgUKaUXhCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE2IikKN+49C5HqvQgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAMu/sEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYAaxQgLUsUIAAAAAAAAAAAAAAAAAAAAAl59iQgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgulkKWRJpC AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACfzq1Cy4mrQgAAAAAAAAAAAAAAAPy2cUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAJYqjUJ3YKtCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGaNt0L83qZC AAAAAB8ukkKfzXlCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMNIpUIIDKJCT4GzQgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJHTpkIAAAAAAAAAAAAAAABT7VlCJ9lyQgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHpBC oj+xQgAAAAAAAAAA+GRZQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAPc/skIAAAAAAAAAAAAAAAAAAAAAAAAAAFN2zUOOgYFE CG+3RHOpdkS3jTxDj78CQ61rKkP+ZhBDm4zBQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AADzy7ZCAAAAAAAAAADLUYpCez5uQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAB70IJCTy6oQhH7pEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaL9HQ/GFKkOxxWZDEwloQ5tB0EIAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAACORYhEsJ26Q/CO5EMj38JEdSNFRG9YaEKCI41CtkGRQko34ULWnMVD 7nYsQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSR7FCBMyZQgAAAAAAAAAARxJjQgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABv55pCIt+UQimgvkIAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABx0gVE1rJbQ1/hVkNypaFC 1HmtQhBvrEIeqxlDX9p/QwAAAAAAAAAAAAAAAAAAAABPX6tCP27MQl7TP0QPPsJDHGzlQwAA +kQjoIJDIgqiQiazj0IwrppC1naSQvh3fENdzZxDHicXQ8RB1UIAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACStKBCgCG+QgAAAAAAAAAAWVReQnt8aUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA geuXQrh2sUIxZLJCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AADe4blDkm4eQ0ubCEMVTx9E8KnQQsZLkkLijZVC8EelQunapEKZQxZDgNN7QwAAAAAAAAAA AAAAAAAAAADWPUtEu9YVRJEh6UM4KvhD8nOjRINs2UPeI6BCvI+gQhbDo0LGl5hC5qumQgoC gEIuZqRCmkG3QqZeDUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACS8rhC09KsQgAAAAAAAAAA iwKLQgRqWUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA1zabQuAEmUJ2rbJCy3S3QgAAAAAAAAAAAAAAAAAAAAAAAAAA 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 j2yxQp0lrkKSn7BCWc+pQtVsk0JVSbJCkqo6Q8QnJUR4JdpCerKmQvoMwEJBcM9CHzDiQpE7 3EJpbIBDlhPURGVai0S+Is1DczeaQ/8cBUTPkGtEetTcQwAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJnVKQgAA AAA/TENCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjuuWQ5UwzkOhKzJDEmEBQ7iz0EIvyaRC WR6gQttqrUIe8bpCUX61RFfGf0NYzLRCJ7u+QmnEsUK0upxCfL6ZQk7StkKFS+5COzscQ3ab bUP5SGxD+bobRAAAAAC1UrNE8X3YQv6fyULVRbFCCXGlQvuEs0K626xC7h6PQgaNm0Il5p1C i0IHQ8l4nUNbHfVCjGLLQjfJ+EIGZRpD44AuQ1SGGkQToMZEOijARBnHr0Ro/t1ErUBzRD7q BESbQsVCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEcREUIAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAADEicRC/8d+QgAAAAB1nGBCAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAdN7AQxQGQkSS9ttD0tTtQv3rn0I/WKFCdB8JQ9bJgURKFRdEYCBeRKLYGEMf6MxC H3TgQmXMrUIlqIxCag+ZQotgmEIBiKpCSEGjQpz+vEJaOJlDAAD6RK8w9UOYspFD+0S3Qp/c pULArJtCbR2bQrLOqELjKp1CObiqQvtks0LOGdVCgChDQ9+lxkNN065D5FWOREosuES9NqNE HSlRRIQBp0RYP61EM+N1RKLZp0S6IyVE85EKQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABWWz1CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhAjeQ15VEUTSWo5ElIDHRLvv k0TRE21EokGoRKgtfkRz1VREAAD6RLOf3kPSKmRDVbTjQsjXr0ITaqlCExmuQriUwkKIIcNC Q9ytQlkBgkMAAPpEAAAAADUiS0TfccdCjHi2QvbtokKQ3atCUuCtQrBFskKlOqJCo+ewQvLz sUIrLRxDCI6TQ4b8MUQotrlEOddfRJv1rUS+DaNEuRd/RHPLyEQR2p1Efy1rRD71RUMAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASLRKQgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAFwW7UPjT4BEvIKSRI6go0Rc6oFE3k18ROP7iERYBV5EXHOVROww 6EPDPEdD+ET9Qmeg0UKzFMRC/WG6QkP8rELzn+dCewn4QwAA+kRfTIxDohOhQ9jCiUMJ0KhC ujShQgVFpEKVtptCJj2lQjz2pkKChK9ChGvAQkgSPEPGKORDjfRrRMachERA49dEsEuMRA0v mkQAAPpE/y2lRHREmESP4ihDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIlzg0IAAAAA FV5SQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAADKiDQgAAAAAAAAAAjQ9eQgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxNyVE kndERG3kWkQWj4VEoLq9ROmdZEQ++nhEXaX6Q+jlX0PPakNDesMWQ3t03EKN8ahCHx6gQvdS q0J/WMpEAAAAAIO9u0K8w4REjSZjRFIM8UKViaNCCiOrQgpXjkKziKFCyNLEQtWoJ0N0+TRD IiPhQ8PzoETcoZBEX39nRKibkUSvoItEKmOZRM3A2kQYZGNEAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADObmBCAAAAACbqmUIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6dRyQgAAAAAAAAAAKTeBQgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKvL5DOn+dRAv5jETLpHNEMstjROpii0SffI9E QHOAQ0MxHENrsdFCfnigQgwKqUK0S6xCfotBQ4AhckQAAPpEAAAAANgli0SZeHtE48QORGZ2 00JU/r9C8nXFQv1V2EJMf5dDvBVBRAhNgUTiTUFEnZW4REK/1ETlG39ET8OsROVxq0QAAPpE rdUjRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkXUzQgAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAJeiqEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAOzHiUQRF0FETX/WQ0/vHkS5hbFEFlrRQ8epF0NIHbhCHvXDQpV37kKUOF9E 83gDRKZhDUQAAAAAAAAAAEKieETe00ZEDKU0RFc8hEOA01pDQzUgRN4xn0RMnXxEDiupRCZ0 1UQAAPpE3FGwRDfITERIdYNERMkkRAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAPCmckIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAICXpEIAAAAA AAAAAOHTTkIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1WKtDOaqWQ6Km AUQLgIlEWkhyRErtC0RcUPFDBiuVRM5DhUQAAAAAAAAAAAAAAAAAAAAAAAAAAGmDG0R1WltE pMYzRINDWUTZix1EZGh3RG/JhkSwu0BED/A5RGLYLEQk0aNDAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHUwjUIAAAAAAAAAAC4AdUIAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAALSfkEIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOH6dkPl7uxDcG0GRNFYRkQAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABcC8JDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC2KpJCAAAAAAAA AACkEoFCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AADVOHxCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAn6KNCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABeqQQgAAAAAAAAAAAAAAAIWT 8kEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAABf5n0J7i6tCAAAAAAAAAABIV3NCAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAADIF5QrEZnUL85ZBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA16dKQgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuxtTQidxjUL2JKtCAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvWm5C GjufQrJNi0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAijSGQiZRO0L/gk9CAAAAAHcTmUIAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACeY6JC oXuWQuT8nkKC0IlCokq3QkPsp0IAAAAAAAAAAPiRjEK/zHFCAAAAAAAAAACqhmdCFGqTQgAA AAAONcpCnqmpQlmIv0IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/sFvQgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA fG6KQgAAAABhuMFCZqmbQgAAAAAAAAAAwZy9QgAAAAAAAAAAYKg4Qu0tc0L5LnBC++x8QghR j0JnRnBCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$ppmMap=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEyT jT6NppQ+AAAAAH8oyT4wp9Y+D1rVPowEzD6aMrk+feGSPgAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAD5c+ DzRfPtzt8z2AIdw9O0T9Pe6K8TxC9IW96iIbvded1DyENSI+eRK0PhSN8z4uR+I+61biPt94 +D651P0+zjHCPrfmPT4RceY9xGI1Pubgij410mM+HCDIPQAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADj/Hk9zV30O0RA270Wo5i+qb3HvgAAAAAfiDm+mNBJvqsKkb4PnU++ AAAAAAAAAAAAAAAAYIbrPgAAAACwTqo+3x2+PgAAAAAAAAAAAAAAAAAAAABq8jo9tpN6Pt2u AT+ceRs/AAAAAGHCkD40Kb89AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALXvub2keSG+rds7vQAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAADmPGD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNzjPkrmaj8AAAAAAAAAAAAAAAAAAAAAJ24MPQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAF7O/z31E6I9 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAADuJuw/HqXhPwAAAAAAAAAAAAAAAKg2Or0AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAALGz/r3g9X2+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmRsz/o6Cw/ AAAAAPt6Qz3469S9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAadrjy1ehQ+gb1WuwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOopzj8AAAAAAAAAAAAAAAANB+G9x2JNvgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADTpRK+ tbEBPAAAAAAAAAAAhsaxPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAKizCL0AAAAAAAAAAAAAAAAAAAAAAAAAAFsN+73oqP29 m7wPvtzoF75FNRO+t9wWvssNML7QalW+5c9ivgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAwods/AAAAAAAAAABXbBO+vClpvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABJqjW+Dj3Zvg8Hnb4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAfDjXvXt61L2l1QW+isQcvrM0A74AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAABEQge+MKD7vTNfDb5eNyS+I3ssvhUxKL7Bvyq+nXQ5vtRgTr6e/GC+ cyNjvgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAfeQ/ho9cPwAAAAAAAAAA7PxRvgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADSpYM9pIfJvsRDKL8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOjQq+j+IVvkPMD74OHAa+ s0UHvj7nE74psx++ha4KvgAAAAAAAAAAAAAAAAAAAADjBIu9pgoJvuSoFb5+hhC+NJkkvkmv N74/uj2+wlQ7vgmBPL71bUW+705SvjdGYL58vWm+DG9qvqi3Vb4AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABPsPE/cC2APwAAAAAAAAAAnqmvvs/K2r4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA TpeMvjx6Cb9C/zC/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAC+TeC9EPXfvfTE+r3Jqwu+53QSvl6NFL7+Hhi+HlIdvtuXIb5q4Bi+AtnnvQAAAAAAAAAA AAAAAAAAAAAklxO+o/wovvROK753Nzy++kNHvmEHTL53RU2+TbBOvnP1VL7f2F6+kSFqvvfl db7+wIC+NCCEvnnWiL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvIOc/2E5WPwAAAAAAAAAA 9VmgvhZl5L4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAA1Z60vomK+r74sCC/fcwrvwAAAAAAAAAAAAAAAAAAAAAAAAAA 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 08bxvZ8vBL7JDQy+SvITvvfYHb5GkiW+jqcsvrV5Nb5VJkG+fSNNvgUoWL4k8mO+Q9duvg5r eL5yFH2+zsV/voQNgb7oD4O+AkiFvtYZh74ueYm+4PCLvrnyjr5ffpC+sPSQvoqFkr6v25W+ rbqXvrmdl74ed5m+fp2bvhV8m77rsJq+Cd2cvvr8nr5iZKC+UtqhvqcVo76mBqS+zsilvvZr p77CQ6e+h2CovnvFrb6+ALW+6eS3vqNNtb4JcrG+3aewvqT0sL6Kaq++pWytvomrrr4SkrK+ iwC1vrcGtb71P7a+3w+6vvwevr6cy8C+cefCvjWix76VbtC+06rTvpSotr4AAAAAAAAAAAAA AAAAAAAABRnKPgAAAAAAAAAAAAAAAGDOQL8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADu3CC/flTdvAAAAAAAAAAAaOiFvAAA AAAAAAAAAAAAADc3vb1OM569tvWqvZAxx73m9eK9ut36vXORCL591BC+zTAavqpSJb66dy6+ l8g0vj1aPb7bDUq+gChXvtf1Yr5HWG6+XgN6vpXTf778FIC+Z1l/vsJdgb6N24S+S8aHvs2a i74eUY++u9WSvrzHlL74XpW+r7GUvki3lL5QvZW+pPaWvmjtmb7MrJ2+j2efvrMqnr56qp6+ p5ygvj3yob5W8qG+G2ChvkZHor5Yn6W+Zbaovq1oqb7s76q+Vxawvr4Utr449re+KI+1vijB sr6nV7G+nyiwvo5/rr47Nq6+KjCwvmhos75XdbS+EJ6zvmlNtL57e7i+5i2+vp8Fwb5jBsG+ hiDDvumwyr7fs9S+l3fWvgAAAAAAAAAAAAAAAAAAAADHfKM/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAANZpEb8eSXo9AAAAAAAAAAD1mcW8AAAAAAAAAAAAAAAAvpmuvZtBn70yALC9M6/FvQzL 2b0Mbe+93Y4EvjVCDr5EJhe+vP4ivrmHLb5+nzO+d2E6vuM0Rr4Ab1S+cENhvgWwbb5nL3q+ SjuAvpdMgL7SBYC+Y6uBvgZ3hb5IzIi+xB2Nvqxckb5hzJS+0dGWvmBil76Ny5W+UviTvoG1 lb5XOpq+xfOdvi3Jn75Wk6C+LuWfvqOSoL5Y9aK+kaajvsCrob6c/5++VYahviO7pb7MeKm+ qJCrvjtyrb6wvrC++Eq0vlSbtb69KrW+4ce0vlb/sr732K++IOCtvsqLr76Zy7G+klGzvrvL sr5eurC+wECwvj+os76Cjbm+adm8vua2vb718L6++srCvkErzL6FZte+zQHavgAAAAAAAAAA AAAAAAD87D8AAAAAAAAAAAAAAAAAAAAAobsSvwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADuWSW/3GPUvkWIlTsAAAAA0r6yPQAAAAAAAAAA AAAAAAAAAABxp5u9XUWhvS09ub1cZ8q9cSrXvZ95572dnv+9KD4LvjSRFb75YCG+C88svvMb NL585Dq+6hJFviBbUr5Vw1++uPBsvoTeeL4sWH++gEqBvnDWgr59boS+kJOGvg+LiL5rZ4u+ kHWPvgqvk75ZEpe+6bKYvjUnmL4IyJa+vPeYvrEanr4ftaC+IDOgvgjPn75xTqC+jaShviwS pL6DJ6S+vDOivsDWoL4AlaK+OHamvhafqb6jBqu+zqirvn+orb5IBrG+ccOzvpfstb4ESLe+ tcO0vsOtr77R1ay+Kp2uvhcDsL4kibC+8XGwvhokr74dba6+FMKwvikhtb481Le+BQq6vnVE vL47Ub6+vVLEvoBRzb7EN9S+h2q7vgAAAAAAAAAAAAAAALT7BkAAAAAAAAAAAAAAAAA7mqq+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKJ iL4AAAAAAAAAAAAAAAAZVpc9AAAAAAAAAAAAAAAAoAJove+car3cTpG95hKxvQqbw70KYM+9 eWvfvYog970cWAi+P+gTvvh4H77wpyu++/U0vmtJPb5G2ka+DTpSvrZJXr5Kg2q+mnx1vq+a fL4dj4G+Mq+EvubVhr5y+Ie+/MuHvrWLh76KtYq+KIiQvsuklb7JOZm+d16bvts4m75Og5u+ iNOdvgatn77Ofp++sk2fvuMhoL5GIqG+bIOivgfTor7sqaO+w5WkvvB4pb7cRaa+FXanvo69 p76uO6e+O/movuujrb5yLbK+TbK1vu9IuL6Wyba+BCuxvryXrL5j5au++Kurvp3VrL5UqK++ qB+xvgVVsL7b5LC+EiCzviLQtL7IJ7e+c9e5vsUqvL61Lb++4q3CvvPHw77i4sC+AAAAAAAA AAAAAAAAO9f5P4ZXBkAAAAAAAAAAAAAAAABFiwq/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlhn+vQAAAAAAAAAAAAAAADsrhz0AAAAAAAAAAAAA AABQ1nO8bAACveSgWL0OWpK9oGuqvfplvb1cotS9XbfuvWjfBL6wVxG+bzEdvoWLKb6VWzS+ XWA+vlV3SL61DlO+h2JdvmDEZ75KtnG+aad5vnQNgb4WUYW+FiOIvi8Yib5J8Ye+0S6GvtFG iL5Y+o2+k9eSvv79lr62Fpu+M4Wcvrk1m741t5q+K7mcvmB5nr4cS5++uVqfvr6dn77YZKC+ 3vmhvh5+pb7Jvai+aRapvtGdpr6C9KS+vFekvoOFpL5P9aa+iMOrvjFOsL4pyLO+OEu3vpMU uL66rbO+Qv2tvi64qr7Tbam+dEOrvu8LsL58h7O+HSWyvgvcr74zfq++6Dqxvg5AtL5D4ba+ 4OO4vhlJur6TXru+64W7vjL2u76vP62+AAAAAAAAAAAAAAAAbTDyPwuwuT8AAAAAAAAAAAAA AAAYyvy+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALXMdL/sxRK+ AAAAAAAAAAAnqro9AAAAAAAAAAAAAAAAM/3wPAlcEjyOG068FhUMvYraWL2Kp4q9frumvfQH xL2va+C9MXj+vSb5DL53rRi+9SUlvhwdMb73Tju+qv9Dvg5CTr5s5Fm+9m5lvkalb76pV3i+ wh+Bvgxuhr6WnIm+ioOKvka3ib7OX4i+A3mJvloMjb5uaZC+bhGUvsG+mL62X5u+n5CZvoHI l77Cnpm+E62cvgZTnr73eZ6+D1afvkoYob5lbKO+d0qmvqCiqb7yy6q+84iovoHBpb6Nj6S+ oTelvnS5p75rHqu+qSGuvja0sL7dyLS+hqa3vm5Vtb6m/q++mfOrvr7Vqr5w26u+Fi+vvs3z sb6JqLC+vBitvtijq75APK6+3vexvpqZs77I9bO+GP60vutJt75Hi7m+8yC7vkesvr4AAAAA AAAAAAAAAAAAAAAA7j9oPzB8lT0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAf9E5v3j6Fb4AAAAAAAAAABMw/T0AAAAAAAAAAAAAAACur0I9 7GOQPPt/Qbsrdqq84yQfva6Car0OoZW9r9CuvWZfyb0aZ+y9h7QGvio0Er4f7B2+5SkqvmNg Nb5j/j2+KzdIvpqZVb6xamO+QaZuvrX/eL5agIK+leyHvoRkir5QR4u+ZbGLvtCzi75Xi4y+ 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 cL4Db3a+u+R7vsd+gb5bEoW+ErSIvud8jL6mM4++75+PvuhUkb6zopK+MeSRvofPkL6rW5G+ XcmQvoXnjr7U05G+UVCXvufwmr6HA5y+HpSevkDuob7A66K+BPWgvnj3nr5U9p6+6P2fvl9+ oL7mA6C++oedvgoqmb7lJJW+aOaUvoHUl77ZWJq+W/yavttNmr6qOJe+ar6TvtpHkr4F/pK+ zeuRvpiWjr717Iq+5iCKvsnEjL6BBpG+wYaVvmwqm76qjKC+QJGivmWbob5i/6C+5cqlvtde v74AAAAAAAAAAAAAAACZQJ6+QZO1vgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAANacLj7Aivw9AAAAAAAAAAAEY5e8cPO9PH1U5zx/qZE8cOGDO2FT SbwV/dS8NIkVvcByQL0p4Xi9fjqfvQUWwb3PAt29wp3xvbsWAr5sawy+z+MWvrvPIL7D5Su+ pFQ2vpzoP770Mkm+DjtTvkBtXL5wwWS+zrtsvi6Ic74DjXi+ypx8vqNNgL4qDIS+1kiJvlB/ jL4Jk4u+uViLvpuLjr60S5K+TQSUvgh4k751yZC+0vKNvlX4j74AJpW+LraYvmg9mL7dvJe+ xGiavgWMnb6AhJ2+W3Ccvqnnnb6TZKC+8RCgvrHMnb7vOpq+eNaVvuYdkr4zI5G+54+Svj3j k75X55O+92aTvuH2kb5Y55C+/M2Qvp4zkr5cG5K+9MuPvmjHjL619Iu+J+aNvsujkL7uVZK+ SoKTvpFzlb5jXZe+DdCZvsT9m762mpm+w1Wevq72wb4AAAAAAAAAAAAAAAAZHqi+AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0J08PjbbBj4AAAAA 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 Q2ynvUhvu72ePcy950bYvXHV6r0WtQC+MG4Evix5+b2miN69TKXPvbZR0r0dlNy9MT3jvb68 5L1VOeS9cDHlveQk5r1eOee97WznvU0d5r2h5uO9nBfrvShj9b1+2ve9WzLuvYze6b1tXu69 SSjzveD66r3uOtm9JSnSvSsR2r2SwN69W8fSvVaswr2qfra9aV6mvQLnjL2H4qS9+dGCvVa3 kz0AAAAAAAAAADD+FD60G5E9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADT4T2+ AAAAANP1MD8e1RQ/AAAAAAAAAAAAAAAAGweTPn4Gdj68c0U+ZFQdPlNA/j3kiM09SMSePU0D Uz2N+9g8sQYGPEKzorsXG5+8NwgFvQ5CJL0kqES9R7psvcw3ir15W5G9UhmNvUuBir1zWpG9 p2iivdUlsb3pnbu93ZDCvRg1wb2O2sS9przQvfDw1r2aj8+9NaLEvUWrxL2E7NG97kravfXl 0L0Gf729NR2zvXVyqr07UZq9zEiKvSjGhL2KCoy9Ot+avUHtqL0YxbK9zDy/vfJp0b3VN9u9 uZzQvUk/u72mT7S9G228vaa8xL2EVsa9G2vGvbbKyL2MDM29MunMvbJ6yL0zXsW9I/vEvX3H wb0xaMS9yXnNvTWW0r06YtC9aznRveTk173bntu9OFLTvUjtxr3cjcq94fvavZm/3b0QRMm9 vDGyvQAjoL1pX4m9PHpSvSj7cL1JBCO9AAAAAAAAAAAAAAAAgIsuPlDOFz4AAAAAC2fBPlRB BD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHW9ID8AAAAAAAAAAAAAAAAsz5I+ Kb+CPgp1WT7lxy0+fmoMPnCe5z2MYbY9Smt/PaEgIj24orA8ZJpfO7HLY7yYrMO8GG3ivAQv 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 AAAAAAAAAAA1BM0+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANCNfvQAA AAAAAAAA02rqPlpT1z4AAAAAAAAAADWbeD6xvGs+h9JXPqJUPT6xhiY+8KkVPkqaCD5jUf09 9h/yPbAm5T0dotM9yGrFPaJ3vD1lirA93WKiPfk7mT3TN5U94XmXPYNJnz0HKaU9IcqiPVEA mj1HE5Y9ffqXPa7Qnj1XjqU9Si2vPYaUvj1Yh849MarRPaPB1D0jUuE99H3qPQj85j0K1OA9 T9XqPcQW9j2q7vg9lFv2Pf4a+z3y5gA+GlIBPgXQ/D26s/k9UIH3PbxZ7j2FROE9LOvXPQNz 0T1ErMU9jtOzPe/poj1s45o9JKqYPbqWlj2wX5Q90GGUPblGkT0scIo9esKDPaOVdT1c7V49 isRVPYs8Wj1TAV09tlRWPZSBVz398Vk9vphWPZYvSD2bNEE97PVKPb5+WT1q0Vo9bz9cPRmc aT0AM3w9nUt2PQAAAAAAAAAAWUiIPrpzlD4AAAAAAAAAALE1rz4AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2SfI+LwHcPgAAAAAAAAAA57mQPtMS gD4y2GQ+DOtNPjUvPD5HHyg+AlcSPt5iAz4VY/09DRn2PZJy5z1txds9lR3UPYvdyT0WJsA9 07G3PQUSsT2hYLE9iMC3PTQVvD2B+rk9te20PU4HsD335ao9PZmsPU+ltj39bsU9SEfUPfmo 4z3vku49jfv0PepP+j3yAfw9Mhz5PdWb9z0GeAE+pd0HPk9ACT52GQk+e3gOPmSWFD4ydRI+ AiEKPi40Bj5KpwY+t40EPrLl/j1OTPQ9i0HrPZJk3D1RI8g9DQW4PWvNsT33K7E95UetPe7X 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 ZT4Rg2g+cd9tPqKxcj7BynY+izp7Pksagz67Too+fj+PPtP+kD5GAJI+2tiRPih1jT65yog+ NZKIPi5diz5jMYw+2aCMPmQljj6IL44+vHKLPiLoiD7GZog+JYKGPqcGgj6lWHo+icVyPkLE bT5KOmg+W7BjPk14YT6RiF4+nFdXPldxSz4h/0A+SBA4PlxTMj4p/DI+uwk2PmCAMz6BJSs+ kpEkPgQxIz7N7iM+eigkPrdNJT5klSw+sQg0PsdmLj4AAAAAAAAAAAAAAAAAAAAALE27PqSA rT4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFjfkT0AAAAAS6ghP6v5DD8AAAAAAAAAAAAA AAAAAAAAHeWWPgx/pD4kVps+IPuJPt+6dz4+Wms+do9gPvteWj7CQlc+65VXPjKMWT5jAV8+ tdpkPtJRZz4qb2Y+q4hnPjLEbT4fCXI+DuNyPgaxcj4rvnY+OkZ8PjYFgT5+w4I+uTuGPiAL jD7p6JA+zcGTPtQSlT5Z6pQ+vx2QPvM0ij5Ql4g+1k6MPhoBkD7iFZE+Ae2QPpYtkD4fXI8+ wmiOPub0jT6CMIs+D/GFPnyQgD4Qnnk+tqh0PsAUcD5bJGw+qO5qPlCUaD7IfGI+97VYPp9G Tz4bAEc+8QRAPn6rPj5gQT8+Ly86PlZlMD6j1Sc+gZQkPnKUJT5ecSs+ngUyPrT5Oj43oz4+ znwqPgAAAAAAAAAAAAAAAAAAAACshLg+PdS1PgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 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 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAGN47T4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADyb0s/ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJqmvj4B27w++lm6Pi32tz7P17Y++cq2Pj1Q uT64iL0+ZxzCPhsxxj4Z3Mo+Ui3RPjgb1z6rYto+VejbPmUX4D4FluU+kJLpPmi07D50jPE+ DWL6PrVwAT9HHQM/7DECP05lAD/34f8+wE0APwL0/z6ez/0+n5P6Pvww9D6Z5eo+kxzhPtBa 2j67F9U+w1/PPuZnyD5he8A+7By5Pi+qsT7FOKo+whCkPpfRnj7ov5k+dVeTPvHjjD5Jf4c+ swyDPiPReT64KmY+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIrDVD8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAVPimPgAAAABktUw/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAADX5uj4367o+6U26PmSuuT6MSbo+H4q9PtxJwj6j0cc+wGzOPrwg1T653Ns+GlLhPrNe 5D5heuY+uCnuPmXV+D5Laf4+uEL+PrO//z6aJAQ/aCcJP+S/Cz8T3wo/T/gHP8o4Bj8YqgY/ yB8HP/w5Bj/IKwQ/miYBPyh9+T7aw+8+VPDoPkXF4z6JpNw+nyXSPsT1xz5zBsA+d9e4PlGa sD7zeag+WVWgPgUWmT5DP5M+QTeOPvFJiT4o2IM+rXd4PgAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZ5qaPgAA AADj4lY/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgx24Psv5tj729rk+qmy7PsAOvj7vScI+ hzzHPnIYzT4rLtU+NujcPgx34z78Vuo+hdXwPh1h9j6SKgA/cJsGP0m2CT9blgg/pc4HP8/0 Cj9kdA8/zusSPwAAAAD1shA/h5oNP0R6DD+10Qs/wmYKPzabCD/yrwY/hVIDP5ZT/j4fw/c+ GALyPpGZ6T4oEN4+ja3TPoaAyj47K8E+xrO2PplhrD6SYKE+c8GXPqLnkT5uEY4+ztaIPl0K gT4A8m8+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB7THj8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAguc2/2KmmPgAAAAC65VE/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAVtiyPntmtz5UA7w+9MjAPhiYxT5SF8s+divSPoSp2z7zMOQ+XVLrPhWN9D698P4+ bRYEP958CT8UcA8/rTQSPyxPET/MYxA/OjESPwPWFD+VwRc/nS4ZP3vEFz9YsRQ/DJYSPxur ED8Wow4/8E0NP2PyCz/lEAk/3EAFPwAaAj/sDv4+0zj1PtF86j6OtuA+63HWPkH6yT4XUrw+ 7dSvPjgCpD6T6pk+oM2SPr9UjT6u9IU+XTRyPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABsTFI/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsom2PsmbuT4dQL8+CBLHPrJA 0D5v9dk+G1jkPvo67j4kl/c+bvQAP21QBj8JCAs/5g0QP/tcFT+MLRg/FVUYP1ERGD9/EBk/ ds4ZPyhTGz+cYx0/AAAAAF20Gj+46Rc/4J4VP97fEz+LnxI/V8wQPyvQDT/oUwo/QWYHP4Et BD8sOv8+o9v0Psib6j4CE98+tIjQPonuwD5b3LM+HzipPrpbnz7JmZU+kJKLPgIrfD4AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdxJIPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAC7ftj56ccQ+gIrVPp8o5D43zvE+MVn/PklQBT8oNwk/eGEMP4ct Dz8Y2BI/X+gXP/P/Gz8LDh4/goIeP45jHj8GQB0/yq0dP8dJIj8FjyU/I6MhP3+4Gz/MTRg/ vCAYPxnxFj+0chQ/aRIRP2klDj/K0ws/Do0IPxyNAz9hU/s++1TvPoO34j72WdQ+Ne/EPqb2 tz6X5a0+VCmjPrXIlT6wDIY+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAME05j4AAAAA tbIZPwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAWchMPgAAAAAAAAAAoON/PwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9vtg+ RMf1PivWBD/ZeQw/9nMRP5ZFEz/3fhM/YkkTP+d/FD+LXBg/7YsdP1aaIT8FHSM/VXQiP5Nk ID+yEiA/AAAAALBAMD/+BSs/FEwfPxaaGD/W9Rk/4/EYP8BQFj+M3RI/njMQP6xRDj9gZQs/ nEQGP88D/z4wvPE+t8zkPhNJ1z5nsMg+GPq6PgZVrj7Uf6A+AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAADtrfg+AAAAAAT7FD8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVuC+vgAAAAAAAAAA21GJPwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADksQ4/DtUZP7F+HT/MnR4/AzceP0jfHD8EORo/ NdgXP+cHGD9oLhw/fUIhP0MvJD8psCQ/D+MjP/RzIz+jJS0/AAAAAB4PND+pVSI/egwYPyLE GT+3IRk/kY4WPxlrEz+o9RA/tDkPP662DD/pBQg/MvYAP7Pw8z6bQuc+FffaPipxzT6iaL0+ vAOpPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAyGcPPwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAGJ+Kr0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAHHvKD9fBCg/s/snP3v0Iz99YR0/vkcYP63GGD9YQR0/QjwiP74fJj80uig/ OxAqP7sWMz8AAAAAAAAAAAKwJD9IYBg/gacYPxZlGD+qNBY/lRQUP/NVEj80WBA/BpUNP49w CT8lDQM/qq/3PrSC6j4Jtd8+oGnUPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAPgVGj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMoU1L8AAAAA AAAAAGZcRj8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADRaC0/Z2EqP3z6 Ij84URo/MYcWP7qwGT/d0CA/j7woP6wFMD8AAAAAAAAAAAAAAAAAAAAAAAAAAGe0Gj+i+RY/ iFkXP70HFj+TFBU/764UP4UWEz/OGhA/shsNP6GQCj+YvQM/AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJysID8AAAAAAAAAALuxKj8AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+qG8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcfIz/f3Bo/AFQaPwDbIT8AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADFXhc/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB4HC0/AAAAAAAA AAD25Bk/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAB3e8e+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABpXSI/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjxCfPgAAAAAAAAAAAAAAAAF6 pD0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHoLOT44TgA/AAAAAAAAAADt3Bg/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAOclRP3jGPz0i1k6/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAYACvPgAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAamEHPxPtID+VijM/AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAhFw+ Uplcvr1pqL4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAy7N1P/6dcz+4vFc/AAAAAIty5T4AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgoGc/ r5YoPzUuWz+nW4y9JpYovzd+Gb8AAAAAAAAAAIyZsT6S0oU+AAAAAAAAAADx48U+I/9MPwAA AABz4Ro/S7gjP5v8Oz8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXLMsPwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA qhmCPwAAAABq+K4+fA5qPgAAAAAAAAAAymtNPwAAAAAAAAAA7xZPP8ImSD/IPCI/SugcP5Dr LT9AtjM/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$spinDensity=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImY ljwuKLQ8AAAAAFgp0zwZ3wM9BmvqPLDgAj3anuA8pvfvPAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB2JNU8 PO66PGct4Dzc+NM8OWuGPIkqbjzeG4M8jdpnPGoJdDw4foQ8u3W2PC+OnjzU9bM8lCnGPLO0 vjzx3Y88VuFnPAcnhDy0akk8mlG6PHPZhDxNhaw87knVPAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAD3/1E8aYg6POD3fDw2F6g84ymfPAAAAABRKaY8sWFePBK/njwHoaU8 AAAAAAAAAAAAAAAAoApePAAAAADPhoM8G0KLOwAAAAAAAAAAAAAAAAAAAAAmnKc78O3WOwjN dzyV94Y8AAAAANgLvDzh58A8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAI4VlzwX9TI8FjK9OwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAEqNiTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA+FNDPH0pZDwAAAAAAAAAAAAAAAAAAAAA/rKsPAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPG17zyqtoY8 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAT8To8sQ6TPAAAAAAAAAAAAAAAAKeoyjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAEGIzzxFlCo8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSfTTyG9o48 AAAAADQFrDz3JdM8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHCB6zwW8Ok8yxSzOwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAALOtJTwAAAAAAAAAAAAAAAD5vJw80jDUPAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADBUL08 iE8zPAAAAAAAAAAA4huTPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAF02ojwAAAAAAAAAAAAAAAAAAAAAAAAAAMyxjTydbhM9 Ij0pPfWbQD1FTCs9PR1APQ7yTj3mbic9auX3PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AABkWZY8AAAAAAAAAACUG6A89rXNPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAPxvM7hlpFPPIDOjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMs0+PajHST3wVEM9JGs4PQD6DT0AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAA3Fic9O1UTPZSNIz3DWTw9178/PbAgTT0V6To9kycyPXxJHz1J9Bc9 W10MPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCS4E81gjLPAAAAAAAAAAAYNq/PAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACu2UA81L+SPPVNFDwAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAC4njw9xi+5PEhdRz2C6Ew9 rRpJPV4TUj2u5kI9BIwiPQAAAAAAAAAAAAAAAAAAAAB6Df48ZlQKPaUpKT3pyT89meYrPTU2 Kz0dli89VbZKPb7yMz25MjY9lbg6PTkCRD0lhSc9D/0ePSD7Dz0AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABX57A8wbyBPAAAAAAAAAAAl7u6PMPy1TwAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA n4tuPBkuBTyTlNM7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AADe3C490JpMPfn0Oz3s3DE99C9BPX5DOj0XLz09Z8VLPVsUSj1gW0w9JDElPQAAAAAAAAAA AAAAAAAAAABzVSg9Mgg7PejEEz1IrTc9BXEtPR2RDj1qvjw9NSw8PWeaPD2GykI9FRVLPT2K Qz0QdEQ97SdKPZQyQz0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADQttQ8xNUjPAAAAAAAAAAA RAu4PM8k3TwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAaLGdPKPTsTxJPko8Cp5VOwAAAAAAAAAAAAAAAAAAAAAAAAAA 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 NKMuPejgOj3fizI9PkM9PbT7NT01ISM9u1orPTFpMD2yPzU98f8yPTLdLz0eGEI9b04/Pb6b OD0cATw9vxg9Pb/vFz2nGTY9/0o3PUCpOz0majE9+uosPQAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAuLVqPAAA AACeSMQ8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASUTDPGztFD1rGCc99/QgPbjXHD0sMBs9 i8YkPQuhJj3/3R094vwQPVaiDz195hQ9JhI9PQfAOz1beCs9gLY4PcJ2Kj1owCs98C8oPW9J Jj2vHDY9Ak0rPQAAAAA5GPk80QsVPbL2OT3VGDg9Y0MzPWwvOT328TY9JQEvPSgALz1Qjxw9 7lIhPUYYKz13RCQ94G0wPTbYOD2hGCo9EDQ4PbeiNj2Cby49KF0qPVg8Jj2RNxw98uovPXzI MT2zuQY9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKLkQjwAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAgFA8n2aoPAAAAADl27g8AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAykrjPNRiCj1rYBM9yKMhPXilJD2TQiE9rTQWPQGqDz1mChA9D4gOPcqcHz159C89 /ywjPaIFIj3IvzA9u5MzPdBOKT2g0iQ94UEnPTv/Nz0STTo94iQiPYRbrTzJOhY9CuM5Pe+W OT1gLDM9w4ouPUIvOj1yHzg9ofkoPYR8Hz0pWDs9g4o1PZf7Lz03GDY93C4qPYu/LD1alSk9 PmcfPdwuJz1j6CQ9AJ4vPTt9Iz2lTig9UygUPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAABwe6w8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAu03LPGZNGT10LxU9k4YOPaiX Bz0dewQ9L+wRPRsVFz30DAI9KDIhPQejDj0Alic9a3cgPTO6KD3exyo9V9sfPdSlND3d7yU9 j14vPVdmKD2k1yc9AAAAAGHg9jzCFDc9GZtCPVbYNz2S2jI9588sPUNsJT3AESY9oaEuPa9S Kz03A0E9lEk1PYv+Pj0v/zk9RFM7PdYQNT3PORo9iLwaPanxLD1MCCo9cqwtPa7uDj0AAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABiKGPAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAHqB+jzo2/w832r/PADADz3ifAs9iRUXPYN8Dz1p6Rg9siMTPa2d LT3jFyo9uSMuPbrFMz3H9CA9+i8mPYEJLT2/9Bk98IkiPZeYEz2ryIc8Bb8uPTdWLz2g0iw9 Xok7Pbi+Nj2aDzc9jCovPTOFMz3lZzg9Upk7PeGwQj1RRDQ93v8lPVSrKD0c3ig9AHAhPc8T Fz0wdCc9YkgiPUrlJz1Qfho9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlifjsAAAAA f9NZPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAs5hcPAAAAAAAAAAAyq66PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH6AA9 ooQJPYtSBj3yEhE9QeoVPQCEHz0GaBA9v6AcPcTTKj1AQik9eiEsPb4hLD0iUCo9/aIqPaPG Jj29hyA9AAAAADjg9TwHOTM9dVwzPWjjQT0P6UA9hO5DPQQhLT0UpC89V5A9PWxFMD3VVzY9 DeouPWT2KT0bYCM9Ph8nPQUDIz207CE9bzchPYYlKD1XXS49AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAB/Az88AAAAAO+UTzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA17umOwAAAAAAAAAAb4SgPAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABaB5g8pogPPb+xKD0kHxo9UzESPc+/Ej1vkBc9 jqckPZorMD0WXBw9uOAjPSNTNj1XXi896I4nPeq6GT1jvx89AAAAAIBcLzy4Tg89c1oYPckl Lz22+zc9N9QvPbFmLz2nGjQ93NcrParFFj1k1CU9ezcZPasWHz2TSBE9B9kRPXptHT2eVA09 RAAePQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAze9KPAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAACrejTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAABzhgjxTg9k88hoZPRpXGz2jCiE9gJcLPVxNHT1ZhCc9evQqPZj0Iz2Rqhk9 O78GPat8pTwAAAAAAAAAAOgpDz2Gsxc9/e0rPbEoLz3BESI9xMYgPWQ6JT1foTE9wdExPYzN ID2Apic9dTT3PM4eLz0edB49i4D/PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAANquzzwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4WdDwAAAAA AAAAAConmjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADfdIA8RWulPLZS CD0QFwY9PHYXPf3VEj1uqRg9ghYVPWZG/TwAAAAAAAAAAAAAAAAAAAAAAAAAAM3owzyXDBc9 7QYdPeFlKT0UVyo911cbPc3+GT1hCg09o28IPWfU4TxlGNs8AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAJrbmTsAAAAAAAAAABvAmDwAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAL+6sTwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALd8CD2aYdo8fQsIPdk6/zwAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACnjq08AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6b3w8AAAAAAAA AADpa248AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAYK9s7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACZMD48AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA05y4OwAAAAAAAAAAAAAAAN2e ojwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOPVQDuH9hQ8AAAAAAAAAADJyYk8AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAMRJSPCr68TsKLiE8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHVeaPAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAImxePPUIgTxMXm88AAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACY3IQ8 dFtNPK91RjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJBCYPJ5uiDxDfow8AAAAAAbetTsAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQD1Y8 vNEOPH8VMzywIcc7BjeHObLkYzoAAAAAAAAAANM4EjxAO6s8AAAAAAAAAAAO3Rs8SfM3PQAA AABb+EI79pWcO5nsuDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAlBLDPAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA itCDPAAAAAAzbqU78jJyPAAAAAAAAAAAZrEwPAAAAAAAAAAAvQSbPH+Vhjz0iKE8XKzWPPl6 xzxwrYM8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$B1map=( 0 ) ##$DcoeffMap=( 0 ) ##END= odin-1.8.5/samples/qualityPhantom_128x128.smp0000644000175000017500000126510711363773560015647 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 200.0 200.0 4.0 ##$FrequencyRange=10.0 ##$FrequencyOffset=0.0 ##$RelaxationT1=0.0 ##$RelaxationT2=0.0 ##$T1map=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA zAtoQy6IK0NbsyBDoIogQykbKEN9uiBDgEgrQwnAJUPAeSNDFmQbQ6kfUkMxZipD1fAnQ5Wy HUNUiVpD3plbQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAUIAlQ5PEIUMTmzRDRFtUQ7HeH0MKrihDqKxgQ1viHUPplipDPW0pQyyqL0N1OChD kuUkQ/0dW0N0/DBD2PEsQ+CuIkN5Y1VDaiJTQzn3VkPreixDV14mQyzhGkMXBFtDjVEmQ1qh H0MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAEWVVEOCKFtDHW4pQ731JEMYRSNDqM0iQ37PK0MUJCVDvnRYQ8E/ I0NZECZDMuEhQ6WQIENFZB9DEXBVQ3ioI0MyeShDlD0dQyWlVEN8syhDViMoQzAxU0PeR11D SEApQzEwL0M5fitD4ftZQzmyTkPv/SJDLT4gQ3u1IEN0a1VDW+QsQ2whWkMAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0AMmQzVWLkPPs1JD3TslQ+k/I0MAAAAA GuVWQxaxIkP9AilDKBEuQwGfKUP2uypD5aYjQxtoJkNRHx9D0EorQ62BUkPjuCRDVPUfQ3fR L0N9uxxDuckmQ50PJkOijiRDtCgcQ6XuT0Pc0iJDFkciQxndJUO2zihDCdQkQ79wJUNity5D Ux0bQ3U7VENmRyFD2gtVQxkWJkO2LyBDHDQgQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACs4GFDBBMgQ5y7 X0PWzCRDX+shQ5d2I0PNBCRDD4ohQ5L5HkOEaFlDdHAjQ5X6GkNPE1pDZdQsQ06IVUMNtChD +mIfQ0mwK0MJ3R1DxtVVQ1cRJUPytidDLvMsQ5gZIUMhZCJDHpNUQ4e1IEMslBdDmt1YQ+k3 HENedFVDAgEqQ3eAW0NF4yFDSmUtQ9sFIUPi5CVD/N0kQwZWLUOVQldDKMBaQ4TlMENVllRD g+FYQ6WCL0NscBtDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAClpCdDF5EbQ9TnJUOmi1tDiq0hQ8ZxIkNS/l1DO3AlQ5WiJ0PG51FDQhgiQ+Jz JENCJylDuDBcQzSFJENCJCJD6cVUQzpQK0MVax5DF4whQ9sXWEPBXCRDo2MeQ4YCKkPEMSdD /nUlQ7T/HENULiZDTGAVQyveXEP4ICxD2PsrQxmKJUPEjiVDaNUiQ3pDVUNrqlZDFq8VQ6ne VkNzay1DYR8oQ3B+HUONHidDk5sjQ3Q7IkOFTShDGfsiQ+N3H0PMZiFD9dAhQwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkBCND91EpQwCwGEPZmyxD9+xXQ4kfKEPJYCRD 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 MKBVQ4SsL0P3/VZDvqddQ0ouIEMS4SZD1MRdQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAo+UUQ2ZQU0NKCSVD4bZXQ56tUkM82htD2fglQ8fk LkM/KlRDIXdaQz0fI0P6Zh9DR0BaQxCGW0PBmxtDrYlcQxiXXUMPElJDAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABvZHkNUU1lDApQVQxoN XUMPpS5DfTdZQ3rBIUNWlyRDMNVaQ/0KV0OX5ihDGF8hQ2RXL0OIei5DvOkpQwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA WHRWQ1S4JkPFRVJDo+gfQ8s3LEMyJ1tDyYZQQ/kZXENZTlhDs8RYQ91HJkP0xhhDnokfQ+oM VUNAtSBDKJtYQ7jCJEP+ZFpDrWsbQxMGHUPpxSlDbmUyQwAAAABC6iRDAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFoYyQwJHG0Ohhh1D ZX4nQ+ZVF0MnQl5DOutUQxhtMUOjZydDEKoeQ48rYEOoFx1Ds4ApQ/63K0P9VS5DbIktQ4dk UkOiui5D/alVQ+KzKkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEJCJkOD3VpDhtMYQzFBLUMEESdD OGUhQ+72WUM75CFDUqslQ3pBJ0OJq19DDDghQwF0J0PHOy5DJIsrQwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACI/R1DnxImQ6mrHkMClidDvMMWQ14eYEMAAAAA AAAAAImQEUMzhVVDcINfQ4aRJEO7zxNDYoEvQ7ZcUENIuGZDAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAB49WEO/Py1DAAAAAIHWIUPWoSZDemIvQ7d8N0MAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZdWUMAAAAAAAAAAAAAAADiuhZDSL9SQ67xJ0PQhyFD AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABNgjVDQE4iQwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAGZmJUNF/itDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAD4yydDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$T2map=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 42lwQ1SfeUMpXHFDmW95Q2xFdkPwKXhDjyF2Q2FqcEOQs3FDC8psQ6dvbkMwNHND41JnQ/Mf ZUOvAGhDVLhdQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAA46d8Q8gre0MPEn9DVg57Q0YegUOFf4BDKmJ8Q+f6fkPcYHxDqGt7Q4yXfUNyQX5D rOR7Q7uhcEMRxXxDlCBuQ+2vd0NJ/25DUfFzQy3wc0NIKnJDNtprQ0H7cENd5WtDwB1nQ6Ix YUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAFskgUOmyYJDxhCHQ3OChEPLy4VDWuuCQxOEhkNJ5YNDhwGBQ/o8 gEOlIIVDFB+CQ9nceUN6mYFDmKF3QzVdgUON83tDbFJ/Q1TcfENGiHtDx7R3Q/00dkOP5XND FjV4Q/ylekP3cXhD35xzQ948cEOFjnBDMWxuQ2sBa0O0/WNDnOphQ+fbWUMAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAmXmAQ/uPhUOIYYVDfCyEQxa6hEMAAAAA ObWEQ7Nmh0OiE4VDSIeEQ3fahkMHqINDrYCAQ/TEhUP0SoFDD199QzKQeUOPoYFDiROBQwjU gEMvOoJDFy17Q9+0eUMRMHJDcVeAQ1cke0Nl5HpDiDN4Q5cldEN5mXdDiWp3Q9w/eUOiLXND YCB2QySmbUPjlmpDwftrQ4shZUN/mmtDLiRhQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB70oVDCQqKQ7Jz h0PqIopDmWeFQ+zth0PZHYZD+GuHQyzrgkMK2IZD66iEQx6QhEMXOYdDY3KGQysAhkM9KYVD mNaAQ2TQgkOvPINDcvJ/Q+zOhEOQSYNDAx6AQzXvfkMoKnlDLd+BQ0jWe0M6pYJD3Zx3QyY3 eUPYM3NDJcJ4QwciekNMs3hDGUl6Q/oVe0OdHHxDRJtxQ/eDc0MwkXBDac5sQ+clcEOje3FD HmlnQ8dWZkN0olRDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAADO4IpDFpiKQ2qVjUMwqYVDI36KQ27miEN9E4dDZF+DQ9qrhUN9M4ZDWFyGQ/zQ i0MXQYZD5qqFQ+OTh0MDJIJD2p2EQ5xXg0MtmIRD5z+EQ98xiEPnVIND3i+BQ385gkM7GoJD R3SAQwvgg0MXO4BDH0Z+Q6UQgkP4jYBDKhqAQ1WagEN99IBDIKiAQ6NGfUPPjHVDZ9B4Q09+ eENixXhDeylxQ0NYd0NRtG1DNadvQ/J0bEPAxnJDe2RzQ8t6Z0NgtmpDNIpjQwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD3EItD+VKJQ/ryjEOs7IpDovyOQ3+OikMqDYxD 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 d0Oz1HBDlbVzQwp+b0OnhXNDBfRrQ8b2YkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQViEOa2ZNDXnKRQ/qymEMCbZJD SLiTQ6gtl0MWGpRDH2GSQy32lkPy8ZNDDpmOQwwIkEMSH5FDWXKOQ6lIk0NA149DhaOQQ/ow j0NPIYtDrdWMQ4G/kUNAyoxDhjaMQzPHi0NrtYlDHCmOQ/8FjEP7k4xD7AaNQzrOikPQm4tD E/qKQ8P6j0NuT49DXtGIQzCHiEOvT4lDaveLQ7D8h0N5o4hDciOIQ3Eph0MJO4dDNNaGQ2YL hUMxB4hDr6SCQ7TAg0O6OoVDNCuDQ8lrhkN1BYJDcGaEQw2Hg0OPLoJDAyF8Q7XSgUNiNIVD /2CEQww5gUPJ34RD5Lp8Q2GveENhbHhDiDR8Q43Yd0PCeXJD1lJ4Q9ypgEOXjXFDiFNuQ90M cEMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAA75ZRDYNaPQ/gLlEMNx5VDSP6RQwuslEOehJJDfZyTQy5blEN+H5FDivGSQzggkkPFso5D 3Y+PQ8rKk0NJApNDxVWTQ1/IkkOXro1DkTaOQ/mTkUN+kotD9MaTQyFljUN+k49Dgd+LQ588 ikNWaYtDN5+NQ0MfkkOJ8YxDwmyKQ9F7kkOWCoxDdHuKQ4wLi0M+LY5Dc5yKQ3BrikPKgIdD LMOGQ4YCiEOCQYlDZJeIQ+M1iEOqTIpDlRCMQxbdiUO9kYlDUW6FQze1h0NNxYdDpLOCQ3nA hUNmJodDYz+CQ8nVg0PK7YNDCieDQ7V/hEMvKIJDRpmBQ1wegEOGqYBDl6N7Q7oFgUOZxnxD 69+BQ1QbfUNz+XpDcyx4Q6bqbkM3BnJDwM9uQ401aENqJlBDAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAS5aQQzZ7lUNZFphDehOYQ0S9kEOcH5VDsMCYQ9q0 lEPvh5JDLmGQQ7vIkkMWLZFDa9KXQ631jUNpjJZDR3CRQ8+1jkOsyY9D5DmSQziskUOKtY9D DSaSQ/3mkkO6VY9DU/OOQ/EjkEOO3pJDb/OOQ9A0kEOaKZBDdnWRQ52YjUOYl49DjdONQ9Ru jEOXxolDWkaMQxADjUNYNo9DeHmGQ6sxjENO8oxDIbeJQ7xjiUPoKolD+W2JQ9/DikO1XYtD WSGJQwSQiENQjIhD3H+JQ4EKgkMLCYlDCEWGQ7bXhENOwIZDlAuHQwEShENUXIZDT0aCQ/EZ hUNcz4VD9k2EQytzgUMaloNDiiWAQ5p+eENvV39Dk0J4Q1cyfUMTuHlD7fV3Q4+kcUONZnJD aQxtQz3takO6emdDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAZOlEOaDZJD DWySQw3ClEOd5ZJD8vuQQy5jmUNSX5dD0TKTQ0xGlEOSQJJDOXqRQ6IKk0Py541DPoCTQ15m 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 k0Nts5BD+9aRQxIzjEP6349D7HCRQ9oGi0MrK4tD7SCRQ3H9i0PHQIlDDNyRQwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGzB K0PMETNDbqsxQzdEL0O8sTlD3M00Q3fzOUOZN0BDIEE9Q0ICPkOQJj1DFKA/Q+aJR0N9dEND b/NEQ6HcUENAE1RD0kxSQ4+kVEOKmlFDkQxPQ0QpUEM86lhDhCxUQwAAAABoo2JDAAAAAPRK VUNOPl1DSb9gQ0IeY0P5YGxD5hBrQ1QuakO0PG1D5EJuQ6sfb0O7D2tDM9BwQw3VdkNxanBD qvV0Q5VDbkNiuHNDyud/Q9ftekPb5m9DhLt6Q2vJf0PAyHRD4ht4Q7zofUNemXVDxgSAQy8w gUMyVHVDeRWFQ15aiEPXiIRDd0qFQ4YyikOhG4RDjfF4QwAAAAAAAAAAhKaDQ4Rjg0MvfIpD QY95QzR3g0MBs4ZD0DOBQ1DwhENvQYhD5hqBQ9ScdUOxG4JDujGHQ9YsikP4moND87CIQ+bS g0P44IhDGWCIQ40eikPkJ4pD53iIQ1xijUNoKo5DhgyKQwuyikPYpYZD4CSIQw9gjUPme41D yuSMQ5zOjkNcxI5Dt+GMQ0+ejkMgRY9DFfKPQ7gjjEMZc5BDHvGSQ7gCj0NHYoxDmU6OQ79h jUMwlpBDt7mMQwvWkUMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4B8PQxioLUN21TFDrvA8Q9LuOkO0BzRDQFI5Q6lL OkOr3jVD61Q8Q600O0MUHDxDZiRAQxagP0MNTkVDjSZQQ1UwTUNKZU5DI0FWQ5QvT0M6M1VD pNZVQ8uAVEMAAAAA0J1QQwAAAACdD09DAAAAAAAAAAAZAGFDzBVdQ110bEMNv2pDL1JiQ3Dr Z0NsQmpDZGppQ8dXakMGV3NDZkVtQ6mqaUObJHVDzm9uQ7gveUMl2HZDUPpzQxm3cUN1C3JD FIN3Q5LLckMDDHpDrWR6Q4XOe0OORHVDn0OAQ5KdfEOsroVDAfOAQ5TghUPrWIdDsSGGQ6z7 fUMAAAAAAAAAAOxZakM3iohDQk2KQ1tdhkObFYBDCJF/QwAAAAAAAAAAAAAAAAAAAAAAAAAA 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 lRtBQ5UAR0Nspk5DgiBLQzKBRUO60khDai5eQwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAXsgNQ8/0I0N6DSlDUBscQ3vTHEM0/RxDFicLQ6p4 G0MwlxVDGpoRQ4l+B0ObQQ5DadUNQ5INF0MinxBD/gsQQ5/ME0MsmQhDAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPRKPEMGhTlDIg05Q6Tg NEMwEjpD8Vc+QynnNUNgGEVD3DQ2Q72lRUOcu0ND+AI8Q3r0RUM1I0FDwxI+QwAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA RrkEQ/bEGEM17CFDIG4hQ7X4HUPgNhhDfyEXQzR3F0PeUhVD+pMVQw9UEkPIDhVDcDIOQyUz C0MSPRJDbAkHQzenB0Ps2BRD+WMMQ7PSDUMGzxFDP4QHQwAAAAANDQxDAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYMjQ8N7KUMuMShD 5zEsQ3Y3L0M3ky9DcXsrQ/I5L0PHmjJD7XI0Q9FcK0O5jjBDqPVBQxaVOUM/czxDcBI6QxCR OkP0pzdDEdlAQ/wDNkMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANdAGENsdSBDlMsdQxDwEENg2CJD pkUWQ+J2E0NQAQtD8xgMQ8udCUNo6hBDvmoDQ8k8B0PwjwdDMuoFQwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY1iRDIX4sQ0VaLUOsZDZDz2svQ3E6LEMAAAAA AAAAAHgdK0OIcTRDMp4wQ1RTNkM6TzRDeUIyQybuKUOI2kZDAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAOPxCUOCQiFDAAAAAL1wBkNB7BtDVwgIQw0BAkMAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAN5wJUMAAAAAAAAAAAAAAACdBTBDF9ksQ0LCLEPwWyxD AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1HxpDh8MVQwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAACC0K0N+qiZDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAADzVQZDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$ppmMap=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AzFDvplJNb4rKyS+W1wcvrvtEb6vTfC9MEazvUo8ir24C1u9hEoPvaI/qbwkvoe8ZhaIvMm0 H7yVW2e6AY8VPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAUBydvp98kL5pGoS+K2txvqY/XL6QgEe+y4UwvlHdF76pTwO+/HngvS/btr1IiIq9 1QFSvR58KL1k5vO8rk2MvGxvVbuY8Dg8maPVPF4qFD3k8Cs9ZAdkPWJbmz1iQbE9s/KjPUb2 mj0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAK/Iwr78SbK+j9+ovhdEnr6T0ZG+E6OFvnWoeb7q3Wu+FJFZvh+6 Qb6pjSi+hhgSvrde+L2FHsW9sbSVvQlkVr3ZwRS97D/gvLT7trxCBEq88vrMO3f85Tz5JUY9 +Bx9PWZPij3Ao6A9PajGPaQH3D36IdY9xdPJPfq6yj3lR8s9j2TEPWsQxD0AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA18PCvspoub4rLq++omunvuUsor4AAAAA 87WTvie4ib5/j36+vXhtvpNSYb4BL1K+EIc7vkrLIb4rdg2+7F3yvVCYvL2XFoi9UHgxvRfW ybx+V3i8pVBXvI0KnbuffX48SyUhPQ2pcz1ozpY9a26pPTm6wT0Gd+M9Jj37PZeZAD5SOP09 hxz9PQZt/D2ZofQ94dblPW9G0j2qQrk9NTOTPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACuwNG+nVTIvpIg vb6awbO+oAKtvvPWpb5MYJ6+NfOYvoqMk77gDYu+B4CCvssTdL5QHmS+EwJXvlCJSL4e2jO+ z9kbvu09Cr589e69UY+5vcdlgr1UDSW9aa2tvGFlJbwv04m74qTlO7hp5TxRS049bn2HPY6W nz27Mbs93aLbPYgN9j3IdgQ+v0sOPrcjFj4hYxk+EAMYPhzgED4buwI+iWPcPRO8sT2ckoE9 OvsRPZs1rTv3JNO8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAADJ3M++xezHvh+Av76z2bi+iteyvvIFrb7sJai+AZOivlDfmr4JaZS+phiOvsQ0 hb4b8ne+5aVoviTQW75eZE++S/lAvuy7Lb5WThm+esIJvulp7b24Crm9KL6DvVtfNL1wXei8 bwuDvF8ZD7t8f4Y8gqEgPc51cz3U0ZE9r82kPUYZxz2mHe09TSH/Pce6BD6kFhM+VaMiPvB+ KD7vFyc+wx0iPtU5FT6z9vs9xULEPRYqiT2CZhQ9qlCMO3pz5LxPuni9ZFnMvQAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACWRc6+CYjKvhTJyb5/2cS+JAO7vjsPsr5aTqu+ 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 7OGbPhMKkj7IoYc+sxl1PvBgTT68TRM+1nMYPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwI49PlX/Rj6S0y4+pKABPhwKlz1qglw8FkZevRZo AL6F3Ey+mSSWvkOSy74Vk/O+Fl4Bv890Ar+6ygS/ouELv091Fr/dgCG/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgQhT3Z9Qw+G19NPuzo iT64SKg+nfq4PtQuvj43AL4+H9G3PqqjrT4ivqA+PtaSPm/Xgz7KB2U+XusyPgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA umASPpsw/D3mJaQ9Da61PBgAbr2GYx++LnGKvqSE2r7LZCO/nndWv7Qgbb/UmGS/5JVSv87o TL+nRFa/jh9nv/Egeb8a9IS/eJ+Kv/wSjL/iLYy/ELeNvwAAAAAA/5i/AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxaUZv/veGr+3Ng6/ Pvb5vk360r5ll52+Hiw9vmkMbr2YlY09Fx5EPoKHlD6/LLM++Ee/Pkwawj5YI74+QTO0PhOr pT4A65Q+2ISCPm3kVz4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJoV1zxTexO9kIUJvsjwjr6mQQC/ xUNYv8BeoL+W+cW/LxrKv3u5sL+s9JG/4veDvzxmib+9rpi/i1GovwAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACUO1m/ZzA+vx32Gb+Lgt2+bUuFvkD+oL0AAAAA AAAAAO4lsz74l8M+KWfGPoHDwT4UUrg+9v6qPkZumz7sCI0+AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAFaqtb0i90q+AAAAAOlYU7/JEri/N2sDwDXeGMAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP9XFj0AAAAAAAAAAAAAAABUw9E+Se/APkX4uT7soLU+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHNg+/6QOdvwAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAFQD4z7IK7w+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAADqJc2/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$spinDensity=( 1, 1, 1, 128, 128 ) Encoding:base64,littleEndian,float AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA Wq3nPXPlFz7oiSk+iqwyPubcND7x7jI+2XExPoVeMD7LFzI+92AzPhHYMD5NQTQ+VLQwPrAK Jj5vUBM+TrvPPQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAMdUePn7WLz7kYyg+2pYhPrD1Hj4sfCA+c08mPqu3KT6g6Sk+7eosPvX3Jz5QIik+ F2wrPpjAKz4iXS0+fcUsPibtKj5pZSo+YYAqPjVAJD7v+h8+pFIcPgy/ID5IbDA+kLEvPlIk FD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAPrPGz7lrS0+Uh8ePmBrHD50BSY+tbMrPkiDKz5umSc+TIYmPrNa Kj7rmCk+8UgsPhkQKz7BaS8+ItctPkgELT46lSo++fEsPs9kLD4AKC8+6fMtPguhKj4Qlyg+ j1kqPkZcKD4htyU+k/UnPi6oKj4w5Sw+mssfPpOVFj5uwh8+P/8sPuCCEz4AAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAV+YUPo9RJj7k7Bw+NgMmPugCKz4AAAAA i+wbPmnDJD7LrSo+JsArPh/TKT4Kays+TbcpPsIOLD4y5S4+wUMsPohXMj6IHTE+8r4xPkZD ND4E5i4+aXouPq9mMD4BMjA+SyEtPiDgLT7xqy4+Vz8uPjShKz5oHCs+EV4sPpM/LD7+Pyg+ tWcgPnLWIz5znSc+RHAiPgsnHT4oQS0+dBQhPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYThQ+QFArPgrK Gz5gZyQ+pWIlPgKRHz7fwSU+xDcpPm2FLj4E8Ck+/QosPqYGKz5upTA+FlIuPphRLz4S4y8+ 6g0wPtQ3MD4B9i8+n/wzPrubMj70tDA+ExcwPigPMj7ZfTM+CY8wPhywLz7xHzE+LwAxPsNR LT7zwi4+lvktPlF3LT5gqjA+KScxPo57Kz5mtCo+9Z4mPtSsKj6SvSg+KRAjPmX4Kj72Iyg+ lMMePi05Nz76FwU+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAACFOic+YCkhPkzdIT5pYyQ+iWYhPgtDJT44eyg+CbwnPkB6LT5ODjA+T2kuPumc LD4aFDE+EgAwPtNbMj6ClC8+7sAvPladLz4tsTI+DAoyPphbMT7J4jE++nAwPmCuMz4TMjY+ CUgyPpR0ND4suzM+3Dk2PlTLLD5quDA+eGcyPuqJLj6Q2DA+BIUvPoLlMD4qFy4+MO4tPtHF LD6Ekyw+BhcqPvDxKz4lmyk+F58tPg0xLD6cfig+T2gyPjufKT69tTQ+mE8yPgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADeZCM+QGkcPgNwIz7YhiM+7tEjPq6nJj7aoSY+ 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 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1lw8+VrsWPrRjGD58NyA+TXsjPsneJT5nFSc+ ShkoPtCPJz4yViw+S0EuPoowLj6F5Sw+0EAxPjj1Mj6vUzc+YtIzPvxHNz6vyTg+MwI8PrZs Nz5/VTs+zZk+PlLLOj5eZz4+F49APr4wQD7kSj8+YmhAPjoZQj7sxkI++oZDPpwHQT6MRkU+ 2P1CPiixQD6tK0M+oEtBPvSWQz488kA+wMtDPjV2Qz7EvUM+PO1GPq3URz6J/UU+PkdEPtpC RT5NLEU+IGFGPg3GQj6KAUY+DxNJPqnYQz6CoUY+pZNCPjcAQz66Q0A+0G5EPq0xRD7D/j0+ fNpFPgIKQT5hFUI+jFFEPljMRT7AU0E+WwpBPtbgQj5AKkE+/15APtFYQT6ksz4+hn85Poxs PD6ZMTg+2e43Pr1YMz6f7DA+QqYvPulsLT56Jyc+fy0nPmuoJD7UUB8+KT4aPhJ7HD6JaxI+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAirMaPl3G GD6rqRs+e3MePnMQID42DCU+KWwkPnehJz6GHyg+s4wnPncwLj5Oli8+pe4wPhuwMD6waS4+ XKM0PpWCOT7JnTQ+0PI7PgldNj5wOkA+djM9PszeOD6vejg+XMI/PqidQz7hSUE+pzhHPmHv Qj7d7kM+uNxEPnwLQz7G6EQ+lpJBPrTARj7U70I+VFxDPh8qRj6b00A+UipEPixqQj4ZQkY+ w0lEPlIJQj4XB0U+UAxFPskHRT5fpEQ+wX5IPgw4Rj5t9UU+8glGPo8aRT7P2kc+hFNEPmQF RT6XBkM+x3pGPmQkRT4yUEI+5Z9CPrL4Qj4cGEY+54FBPlEsQD5dGEM+CZ0/PtlYQT4ml0M+ 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 RzQQPluNED6hSxE+ueASPvFNET6jOgo+N6wKPgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFhoWPgCTEj5gIg0+HmwNPvqzCz48XQs+niIAPq4B /z1o7PI9Hk7bPXlp3z0+wts9zM7DPXFAsT3yTqc9xgqfPYBzlz3mNJA9AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABnWkT2/SKg9PBiyPbnG uz1tpL49wrvTPah+7T34dO49UPYEPuUfBz4+WQw+7UINPtr8DD6NCBE+OAwLPgAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA d8wQPjPSAj6pfAU+u1QFPq2r/D06ovU9fPPfPRc1yj3o3MU9NwGxPSfOyD3TY9U96FzZPYf4 zT2T2sY93fW8PQdXvT1SQbA9UAuuPfbUqj3LI6Y9fqyfPQAAAAAwYZQ9AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMPyVPbt4lT1UsqI9 ss2nPSm2qj1/YqU9VzGgPfBboj2IR5c98vifPavnqz08IrE9og3LPdH71T1uifA9iJT7PT3s BT7X+QU+M4sIPq27GD4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOE6Az6qBvo9yTfnPTDG3D1hj8A9 bdytPZ0pwT084eA9ZvrmPWOg3z1e58U9+zi1PXJ8pT1LRZ09q6OTPQAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANxY490w2QPTNGlz24+5w9KRWtPflgpz0AAAAA AAAAAMJOkz2IYKU9YUTCPTKe4j1TvOs9WAEBPr00+j2kbvM9AAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAPIGAT7sCs49AAAAAIRQpT0XGZ095FK7PRJ/vD0AAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAOBjlz0AAAAAAAAAAAAAAADZmKQ9wFjKPfO91j133QQ+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgB7k9geygPQAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAEwwjz2vr8E9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAABrgaI9AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== ##$B1map=( 0 ) ##$DcoeffMap=( 0 ) ##END= odin-1.8.5/samples/frequency_dist.smp0000644000175000017500000001471511363773560014633 00000000000000##TITLE=Virtual Sample ##JCAMPDX=4.24 ##DATATYPE=Parameter Values ##$FOV=( 3 ) 1.00000e-06 1.00000e-06 1.00000e-06 ##$FrequencyRange=0.20 ##$FrequencyOffset=0.0 ##$RelaxationT1=0.0 ##$RelaxationT2=0.0 ##$T1map=( 1, 256, 1, 1, 1 ) 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 1300.0 ##$T2map=( 1, 256, 1, 1, 1 ) 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 80.0 ##$ppmMap=( 0 ) ##$spinDensity=( 1, 256, 1, 1, 1 ) 4.19884e-06 4.75790e-06 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00002 0.00002 0.00002 0.00002 0.00002 0.00003 0.00003 0.00003 0.00004 0.00004 0.00005 0.00005 0.00006 0.00006 0.00007 0.00008 0.00009 0.00010 0.00011 0.00012 0.00013 0.00014 0.00015 0.00017 0.00019 0.00020 0.00022 0.00024 0.00027 0.00029 0.00032 0.00034 0.00037 0.00040 0.00044 0.00048 0.00052 0.00056 0.00060 0.00065 0.00070 0.00076 0.00082 0.00088 0.00094 0.00101 0.00108 0.00116 0.00124 0.00133 0.00142 0.00152 0.00162 0.00172 0.00183 0.00195 0.00207 0.00219 0.00232 0.00246 0.00260 0.00275 0.00290 0.00306 0.00322 0.00339 0.00357 0.00375 0.00393 0.00412 0.00432 0.00452 0.00472 0.00493 0.00515 0.00536 0.00558 0.00581 0.00604 0.00627 0.00650 0.00673 0.00697 0.00720 0.00744 0.00768 0.00792 0.00816 0.00839 0.00863 0.00886 0.00909 0.00932 0.00954 0.00976 0.00997 0.01018 0.01038 0.01058 0.01077 0.01095 0.01112 0.01129 0.01144 0.01159 0.01173 0.01186 0.01197 0.01208 0.01217 0.01226 0.01233 0.01239 0.01244 0.01248 0.01250 0.01252 0.01252 0.01250 0.01248 0.01244 0.01239 0.01233 0.01226 0.01217 0.01208 0.01197 0.01186 0.01173 0.01159 0.01144 0.01129 0.01112 0.01095 0.01077 0.01058 0.01038 0.01018 0.00997 0.00976 0.00954 0.00932 0.00909 0.00886 0.00863 0.00839 0.00816 0.00792 0.00768 0.00744 0.00720 0.00697 0.00673 0.00650 0.00627 0.00604 0.00581 0.00558 0.00536 0.00515 0.00493 0.00472 0.00452 0.00432 0.00412 0.00393 0.00375 0.00357 0.00339 0.00322 0.00306 0.00290 0.00275 0.00260 0.00246 0.00232 0.00219 0.00207 0.00195 0.00183 0.00172 0.00162 0.00152 0.00142 0.00133 0.00124 0.00116 0.00108 0.00101 0.00094 0.00088 0.00082 0.00076 0.00070 0.00065 0.00060 0.00056 0.00052 0.00048 0.00044 0.00040 0.00037 0.00034 0.00032 0.00029 0.00027 0.00024 0.00022 0.00020 0.00019 0.00017 0.00015 0.00014 0.00013 0.00012 0.00011 0.00010 0.00009 0.00008 0.00007 0.00006 0.00006 0.00005 0.00005 0.00004 0.00004 0.00003 0.00003 0.00003 0.00002 0.00002 0.00002 0.00002 0.00002 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 0.00001 4.75790e-06 4.19884e-06 ##$B1map=( 0 ) ##$DcoeffMap=( 1, 256, 1, 1, 1 ) 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ##END= odin-1.8.5/ltmain.sh0000755000175000017500000073337711734622576011263 00000000000000# Generated from ltmain.m4sh. # ltmain.sh (GNU libtool) 2.2.6b # Written by Gordon Matzigkeit , 1996 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, # or obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # Usage: $progname [OPTION]... [MODE-ARG]... # # Provide generalized library-building support services. # # --config show all configuration variables # --debug enable verbose shell tracing # -n, --dry-run display commands without modifying any files # --features display basic configuration information and exit # --mode=MODE use operation mode MODE # --preserve-dup-deps don't remove duplicate dependency libraries # --quiet, --silent don't print informational messages # --tag=TAG use configuration variables from tag TAG # -v, --verbose print informational messages (default) # --version print version information # -h, --help print short or long help message # # MODE must be one of the following: # # clean remove files from the build directory # compile compile a source file into a libtool object # execute automatically set library path, then run a program # finish complete the installation of libtool libraries # install install libraries or executables # link create a library or an executable # uninstall remove libraries from an installed directory # # MODE-ARGS vary depending on the MODE. # Try `$progname --help --mode=MODE' for a more detailed description of MODE. # # When reporting a bug, please describe a test case to reproduce it and # include the following information: # # host-triplet: $host # shell: $SHELL # compiler: $LTCC # compiler flags: $LTCFLAGS # linker: $LD (gnu? $with_gnu_ld) # $progname: (GNU libtool) 2.2.6b Debian-2.2.6b-2 # automake: $automake_version # autoconf: $autoconf_version # # Report bugs to . PROGRAM=ltmain.sh PACKAGE=libtool VERSION="2.2.6b Debian-2.2.6b-2" TIMESTAMP="" package_revision=1.3017 # Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # NLS nuisances: We save the old values to restore during execute mode. # Only set LANG and LC_ALL to C if already set. # These must not be set unconditionally because not all systems understand # e.g. LANG=C (notably SCO). lt_user_locale= lt_safe_locale= for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${$lt_var+set}\" = set; then save_$lt_var=\$$lt_var $lt_var=C export $lt_var lt_user_locale=\"$lt_var=\\\$save_\$lt_var; \$lt_user_locale\" lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\" fi" done $lt_unset CDPATH : ${CP="cp -f"} : ${ECHO="echo"} : ${EGREP="/bin/grep -E"} : ${FGREP="/bin/grep -F"} : ${GREP="/bin/grep"} : ${LN_S="ln -s"} : ${MAKE="make"} : ${MKDIR="mkdir"} : ${MV="mv -f"} : ${RM="rm -f"} : ${SED="/bin/sed"} : ${SHELL="${CONFIG_SHELL-/bin/sh}"} : ${Xsed="$SED -e 1s/^X//"} # Global variables: EXIT_SUCCESS=0 EXIT_FAILURE=1 EXIT_MISMATCH=63 # $? = 63 is used to indicate version mismatch to missing. EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. exit_status=$EXIT_SUCCESS # Make sure IFS has a sensible default lt_nl=' ' IFS=" $lt_nl" dirname="s,/[^/]*$,," basename="s,^.*/,," # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # Generated shell functions inserted here. # Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh # is ksh but when the shell is invoked as "sh" and the current value of # the _XPG environment variable is not equal to 1 (one), the special # positional parameter $0, within a function call, is the name of the # function. progpath="$0" # The name of this program: # In the unlikely event $progname began with a '-', it would play havoc with # func_echo (imagine progname=-n), so we prepend ./ in that case: func_dirname_and_basename "$progpath" progname=$func_basename_result case $progname in -*) progname=./$progname ;; esac # Make sure we have an absolute path for reexecution: case $progpath in [\\/]*|[A-Za-z]:\\*) ;; *[\\/]*) progdir=$func_dirname_result progdir=`cd "$progdir" && pwd` progpath="$progdir/$progname" ;; *) save_IFS="$IFS" IFS=: for progdir in $PATH; do IFS="$save_IFS" test -x "$progdir/$progname" && break done IFS="$save_IFS" test -n "$progdir" || progdir=`pwd` progpath="$progdir/$progname" ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed="${SED}"' -e 1s/^X//' sed_quote_subst='s/\([`"$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Re-`\' parameter expansions in output of double_quote_subst that were # `\'-ed in input to the same. If an odd number of `\' preceded a '$' # in input to double_quote_subst, that '$' was protected from expansion. # Since each input `\' is now two `\'s, look for any number of runs of # four `\'s followed by two `\'s and then a '$'. `\' that '$'. bs='\\' bs2='\\\\' bs4='\\\\\\\\' dollar='\$' sed_double_backslash="\ s/$bs4/&\\ /g s/^$bs2$dollar/$bs&/ s/\\([^$bs]\\)$bs2$dollar/\\1$bs2$bs$dollar/g s/\n//g" # Standard options: opt_dry_run=false opt_help=false opt_quiet=false opt_verbose=false opt_warning=: # func_echo arg... # Echo program name prefixed message, along with the current mode # name if it has been set yet. func_echo () { $ECHO "$progname${mode+: }$mode: $*" } # func_verbose arg... # Echo program name prefixed message in verbose mode only. func_verbose () { $opt_verbose && func_echo ${1+"$@"} # A bug in bash halts the script if the last line of a function # fails when set -e is in force, so we need another command to # work around that: : } # func_error arg... # Echo program name prefixed message to standard error. func_error () { $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2 } # func_warning arg... # Echo program name prefixed warning message to standard error. func_warning () { $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2 # bash bug again: : } # func_fatal_error arg... # Echo program name prefixed message to standard error, and exit. func_fatal_error () { func_error ${1+"$@"} exit $EXIT_FAILURE } # func_fatal_help arg... # Echo program name prefixed message to standard error, followed by # a help hint, and exit. func_fatal_help () { func_error ${1+"$@"} func_fatal_error "$help" } help="Try \`$progname --help' for more information." ## default # func_grep expression filename # Check whether EXPRESSION matches any line of FILENAME, without output. func_grep () { $GREP "$1" "$2" >/dev/null 2>&1 } # func_mkdir_p directory-path # Make sure the entire path to DIRECTORY-PATH is available. func_mkdir_p () { my_directory_path="$1" my_dir_list= if test -n "$my_directory_path" && test "$opt_dry_run" != ":"; then # Protect directory names starting with `-' case $my_directory_path in -*) my_directory_path="./$my_directory_path" ;; esac # While some portion of DIR does not yet exist... while test ! -d "$my_directory_path"; do # ...make a list in topmost first order. Use a colon delimited # list incase some portion of path contains whitespace. my_dir_list="$my_directory_path:$my_dir_list" # If the last portion added has no slash in it, the list is done case $my_directory_path in */*) ;; *) break ;; esac # ...otherwise throw away the child directory and loop my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"` done my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'` save_mkdir_p_IFS="$IFS"; IFS=':' for my_dir in $my_dir_list; do IFS="$save_mkdir_p_IFS" # mkdir can fail with a `File exist' error if two processes # try to create one of the directories concurrently. Don't # stop in that case! $MKDIR "$my_dir" 2>/dev/null || : done IFS="$save_mkdir_p_IFS" # Bail out if we (or some other process) failed to create a directory. test -d "$my_directory_path" || \ func_fatal_error "Failed to create \`$1'" fi } # func_mktempdir [string] # Make a temporary directory that won't clash with other running # libtool processes, and avoids race conditions if possible. If # given, STRING is the basename for that directory. func_mktempdir () { my_template="${TMPDIR-/tmp}/${1-$progname}" if test "$opt_dry_run" = ":"; then # Return a directory name, but don't create it in dry-run mode my_tmpdir="${my_template}-$$" else # If mktemp works, use that first and foremost my_tmpdir=`mktemp -d "${my_template}-XXXXXXXX" 2>/dev/null` if test ! -d "$my_tmpdir"; then # Failing that, at least try and use $RANDOM to avoid a race my_tmpdir="${my_template}-${RANDOM-0}$$" save_mktempdir_umask=`umask` umask 0077 $MKDIR "$my_tmpdir" umask $save_mktempdir_umask fi # If we're not in dry-run mode, bomb out on failure test -d "$my_tmpdir" || \ func_fatal_error "cannot create temporary directory \`$my_tmpdir'" fi $ECHO "X$my_tmpdir" | $Xsed } # func_quote_for_eval arg # Aesthetically quote ARG to be evaled later. # This function returns two values: FUNC_QUOTE_FOR_EVAL_RESULT # is double-quoted, suitable for a subsequent eval, whereas # FUNC_QUOTE_FOR_EVAL_UNQUOTED_RESULT has merely all characters # which are still active within double quotes backslashified. func_quote_for_eval () { case $1 in *[\\\`\"\$]*) func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;; *) func_quote_for_eval_unquoted_result="$1" ;; esac case $func_quote_for_eval_unquoted_result in # Double-quote args containing shell metacharacters to delay # word splitting, command substitution and and variable # expansion for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") func_quote_for_eval_result="\"$func_quote_for_eval_unquoted_result\"" ;; *) func_quote_for_eval_result="$func_quote_for_eval_unquoted_result" esac } # func_quote_for_expand arg # Aesthetically quote ARG to be evaled later; same as above, # but do not quote variable references. func_quote_for_expand () { case $1 in *[\\\`\"]*) my_arg=`$ECHO "X$1" | $Xsed \ -e "$double_quote_subst" -e "$sed_double_backslash"` ;; *) my_arg="$1" ;; esac case $my_arg in # Double-quote args containing shell metacharacters to delay # word splitting and command substitution for a subsequent eval. # Many Bourne shells cannot handle close brackets correctly # in scan sets, so we specify it separately. *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") my_arg="\"$my_arg\"" ;; esac func_quote_for_expand_result="$my_arg" } # func_show_eval cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. func_show_eval () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$my_cmd" my_status=$? if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_show_eval_locale cmd [fail_exp] # Unless opt_silent is true, then output CMD. Then, if opt_dryrun is # not true, evaluate CMD. If the evaluation of CMD fails, and FAIL_EXP # is given, then evaluate it. Use the saved locale for evaluation. func_show_eval_locale () { my_cmd="$1" my_fail_exp="${2-:}" ${opt_silent-false} || { func_quote_for_expand "$my_cmd" eval "func_echo $func_quote_for_expand_result" } if ${opt_dry_run-false}; then :; else eval "$lt_user_locale $my_cmd" my_status=$? eval "$lt_safe_locale" if test "$my_status" -eq 0; then :; else eval "(exit $my_status); $my_fail_exp" fi fi } # func_version # Echo version message to standard output and exit. func_version () { $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / { s/^# // s/^# *$// s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/ p }' < "$progpath" exit $? } # func_usage # Echo short help message to standard output and exit. func_usage () { $SED -n '/^# Usage:/,/# -h/ { s/^# // s/^# *$// s/\$progname/'$progname'/ p }' < "$progpath" $ECHO $ECHO "run \`$progname --help | more' for full usage" exit $? } # func_help # Echo long help message to standard output and exit. func_help () { $SED -n '/^# Usage:/,/# Report bugs to/ { s/^# // s/^# *$// s*\$progname*'$progname'* s*\$host*'"$host"'* s*\$SHELL*'"$SHELL"'* s*\$LTCC*'"$LTCC"'* s*\$LTCFLAGS*'"$LTCFLAGS"'* s*\$LD*'"$LD"'* s/\$with_gnu_ld/'"$with_gnu_ld"'/ s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/ s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/ p }' < "$progpath" exit $? } # func_missing_arg argname # Echo program name prefixed message to standard error and set global # exit_cmd. func_missing_arg () { func_error "missing argument for $1" exit_cmd=exit } exit_cmd=: # Check that we have a working $ECHO. if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then # Yippee, $ECHO works! : else # Restart under the correct shell, and then maybe $ECHO will work. exec $SHELL "$progpath" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat </dev/null 2>&1; then taglist="$taglist $tagname" # Evaluate the configuration. Be careful to quote the path # and the sed script, to avoid splitting on whitespace, but # also don't use non-portable quotes within backquotes within # quotes we have to do it in 2 steps: extractedcf=`$SED -n -e "$sed_extractcf" < "$progpath"` eval "$extractedcf" else func_error "ignoring unknown tag $tagname" fi ;; esac } # Parse options once, thoroughly. This comes as soon as possible in # the script to make things like `libtool --version' happen quickly. { # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) shift; set dummy --mode clean ${1+"$@"}; shift ;; compile|compil|compi|comp|com|co|c) shift; set dummy --mode compile ${1+"$@"}; shift ;; execute|execut|execu|exec|exe|ex|e) shift; set dummy --mode execute ${1+"$@"}; shift ;; finish|finis|fini|fin|fi|f) shift; set dummy --mode finish ${1+"$@"}; shift ;; install|instal|insta|inst|ins|in|i) shift; set dummy --mode install ${1+"$@"}; shift ;; link|lin|li|l) shift; set dummy --mode link ${1+"$@"}; shift ;; uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; esac # Parse non-mode specific arguments: while test "$#" -gt 0; do opt="$1" shift case $opt in --config) func_config ;; --debug) preserve_args="$preserve_args $opt" func_echo "enabling shell trace mode" opt_debug='set -x' $opt_debug ;; -dlopen) test "$#" -eq 0 && func_missing_arg "$opt" && break execute_dlfiles="$execute_dlfiles $1" shift ;; --dry-run | -n) opt_dry_run=: ;; --features) func_features ;; --finish) mode="finish" ;; --mode) test "$#" -eq 0 && func_missing_arg "$opt" && break case $1 in # Valid mode arguments: clean) ;; compile) ;; execute) ;; finish) ;; install) ;; link) ;; relink) ;; uninstall) ;; # Catch anything else as an error *) func_error "invalid argument for $opt" exit_cmd=exit break ;; esac mode="$1" shift ;; --preserve-dup-deps) opt_duplicate_deps=: ;; --quiet|--silent) preserve_args="$preserve_args $opt" opt_silent=: ;; --verbose| -v) preserve_args="$preserve_args $opt" opt_silent=false ;; --tag) test "$#" -eq 0 && func_missing_arg "$opt" && break preserve_args="$preserve_args $opt $1" func_enable_tag "$1" # tagname is set here shift ;; # Separate optargs to long options: -dlopen=*|--mode=*|--tag=*) func_opt_split "$opt" set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"} shift ;; -\?|-h) func_usage ;; --help) opt_help=: ;; --version) func_version ;; -*) func_fatal_help "unrecognized option \`$opt'" ;; *) nonopt="$opt" break ;; esac done case $host in *cygwin* | *mingw* | *pw32* | *cegcc*) # don't eliminate duplications in $postdeps and $predeps opt_duplicate_compiler_generated_deps=: ;; *) opt_duplicate_compiler_generated_deps=$opt_duplicate_deps ;; esac # Having warned about all mis-specified options, bail out if # anything was wrong. $exit_cmd $EXIT_FAILURE } # func_check_version_match # Ensure that we are using m4 macros, and libtool script from the same # release of libtool. func_check_version_match () { if test "$package_revision" != "$macro_revision"; then if test "$VERSION" != "$macro_version"; then if test -z "$macro_version"; then cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from an older release. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, but the $progname: definition of this LT_INIT comes from $PACKAGE $macro_version. $progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION $progname: and run autoconf again. _LT_EOF fi else cat >&2 <<_LT_EOF $progname: Version mismatch error. This is $PACKAGE $VERSION, revision $package_revision, $progname: but the definition of this LT_INIT comes from revision $macro_revision. $progname: You should recreate aclocal.m4 with macros from revision $package_revision $progname: of $PACKAGE $VERSION and run autoconf again. _LT_EOF fi exit $EXIT_MISMATCH fi } ## ----------- ## ## Main. ## ## ----------- ## $opt_help || { # Sanity checks first: func_check_version_match if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then func_fatal_configuration "not configured to build any kind of library" fi test -z "$mode" && func_fatal_error "error: you must specify a MODE." # Darwin sucks eval std_shrext=\"$shrext_cmds\" # Only execute mode is allowed to have -dlopen flags. if test -n "$execute_dlfiles" && test "$mode" != execute; then func_error "unrecognized option \`-dlopen'" $ECHO "$help" 1>&2 exit $EXIT_FAILURE fi # Change the help message to a mode-specific one. generic_help="$help" help="Try \`$progname --help --mode=$mode' for more information." } # func_lalib_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_lalib_p () { test -f "$1" && $SED -e 4q "$1" 2>/dev/null \ | $GREP "^# Generated by .*$PACKAGE" > /dev/null 2>&1 } # func_lalib_unsafe_p file # True iff FILE is a libtool `.la' library or `.lo' object file. # This function implements the same check as func_lalib_p without # resorting to external programs. To this end, it redirects stdin and # closes it afterwards, without saving the original file descriptor. # As a safety measure, use it only where a negative result would be # fatal anyway. Works if `file' does not exist. func_lalib_unsafe_p () { lalib_p=no if test -f "$1" && test -r "$1" && exec 5<&0 <"$1"; then for lalib_p_l in 1 2 3 4 do read lalib_p_line case "$lalib_p_line" in \#\ Generated\ by\ *$PACKAGE* ) lalib_p=yes; break;; esac done exec 0<&5 5<&- fi test "$lalib_p" = yes } # func_ltwrapper_script_p file # True iff FILE is a libtool wrapper script # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_script_p () { func_lalib_p "$1" } # func_ltwrapper_executable_p file # True iff FILE is a libtool wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_executable_p () { func_ltwrapper_exec_suffix= case $1 in *.exe) ;; *) func_ltwrapper_exec_suffix=.exe ;; esac $GREP "$magic_exe" "$1$func_ltwrapper_exec_suffix" >/dev/null 2>&1 } # func_ltwrapper_scriptname file # Assumes file is an ltwrapper_executable # uses $file to determine the appropriate filename for a # temporary ltwrapper_script. func_ltwrapper_scriptname () { func_ltwrapper_scriptname_result="" if func_ltwrapper_executable_p "$1"; then func_dirname_and_basename "$1" "" "." func_stripname '' '.exe' "$func_basename_result" func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper" fi } # func_ltwrapper_p file # True iff FILE is a libtool wrapper script or wrapper executable # This function is only a basic sanity check; it will hardly flush out # determined imposters. func_ltwrapper_p () { func_ltwrapper_script_p "$1" || func_ltwrapper_executable_p "$1" } # func_execute_cmds commands fail_cmd # Execute tilde-delimited COMMANDS. # If FAIL_CMD is given, eval that upon failure. # FAIL_CMD may read-access the current command in variable CMD! func_execute_cmds () { $opt_debug save_ifs=$IFS; IFS='~' for cmd in $1; do IFS=$save_ifs eval cmd=\"$cmd\" func_show_eval "$cmd" "${2-:}" done IFS=$save_ifs } # func_source file # Source FILE, adding directory component if necessary. # Note that it is not necessary on cygwin/mingw to append a dot to # FILE even if both FILE and FILE.exe exist: automatic-append-.exe # behavior happens only for exec(3), not for open(2)! Also, sourcing # `FILE.' does not work on cygwin managed mounts. func_source () { $opt_debug case $1 in */* | *\\*) . "$1" ;; *) . "./$1" ;; esac } # func_infer_tag arg # Infer tagged configuration to use if any are available and # if one wasn't chosen via the "--tag" command line option. # Only attempt this if the compiler in the base compile # command doesn't match the default compiler. # arg is usually of the form 'gcc ...' func_infer_tag () { $opt_debug if test -n "$available_tags" && test -z "$tagname"; then CC_quoted= for arg in $CC; do func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case $@ in # Blanks in the command may have been stripped by the calling shell, # but not from the CC environment variable when configure was run. " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;; # Blanks at the start of $base_compile will cause this to fail # if we don't check for them as well. *) for z in $available_tags; do if $GREP "^# ### BEGIN LIBTOOL TAG CONFIG: $z$" < "$progpath" > /dev/null; then # Evaluate the configuration. eval "`${SED} -n -e '/^# ### BEGIN LIBTOOL TAG CONFIG: '$z'$/,/^# ### END LIBTOOL TAG CONFIG: '$z'$/p' < $progpath`" CC_quoted= for arg in $CC; do # Double-quote args containing other shell metacharacters. func_quote_for_eval "$arg" CC_quoted="$CC_quoted $func_quote_for_eval_result" done case "$@ " in " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) # The compiler in the base compile command matches # the one in the tagged configuration. # Assume this is the tagged configuration we want. tagname=$z break ;; esac fi done # If $tagname still isn't set, then no tagged configuration # was found and let the user know that the "--tag" command # line option must be used. if test -z "$tagname"; then func_echo "unable to infer tagged configuration" func_fatal_error "specify a tag with \`--tag'" # else # func_verbose "using $tagname tagged configuration" fi ;; esac fi } # func_write_libtool_object output_name pic_name nonpic_name # Create a libtool object file (analogous to a ".la" file), # but don't create it if we're doing a dry run. func_write_libtool_object () { write_libobj=${1} if test "$build_libtool_libs" = yes; then write_lobj=\'${2}\' else write_lobj=none fi if test "$build_old_libs" = yes; then write_oldobj=\'${3}\' else write_oldobj=none fi $opt_dry_run || { cat >${write_libobj}T <?"'"'"' &()|`$[]' \ && func_warning "libobj name \`$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" objname="$func_basename_result" xdir="$func_dirname_result" lobj=${xdir}$objdir/$objname test -z "$base_compile" && \ func_fatal_help "you must specify a compilation command" # Delete any leftover library objects. if test "$build_old_libs" = yes; then removelist="$obj $lobj $libobj ${libobj}T" else removelist="$lobj $libobj ${libobj}T" fi # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in cygwin* | mingw* | pw32* | os2* | cegcc*) pic_mode=default ;; esac if test "$pic_mode" = no && test "$deplibs_check_method" != pass_all; then # non-PIC code in shared libraries is not supported pic_mode=default fi # Calculate the filename of the output object if compiler does # not support -o with -c if test "$compiler_c_o" = no; then output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} lockfile="$output_obj.lock" else output_obj= need_locks=no lockfile= fi # Lock this critical section if it is needed # We use this script file to make the link, it avoids creating a new file if test "$need_locks" = yes; then until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do func_echo "Waiting for $lockfile to be removed" sleep 2 done elif test "$need_locks" = warn; then if test -f "$lockfile"; then $ECHO "\ *** ERROR, $lockfile exists and contains: `cat $lockfile 2>/dev/null` This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi removelist="$removelist $output_obj" $ECHO "$srcfile" > "$lockfile" fi $opt_dry_run || $RM $removelist removelist="$removelist $lockfile" trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15 if test -n "$fix_srcfile_path"; then eval srcfile=\"$fix_srcfile_path\" fi func_quote_for_eval "$srcfile" qsrcfile=$func_quote_for_eval_result # Only build a PIC object if we are building libtool libraries. if test "$build_libtool_libs" = yes; then # Without this assignment, base_compile gets emptied. fbsd_hideous_sh_bug=$base_compile if test "$pic_mode" != no; then command="$base_compile $qsrcfile $pic_flag" else # Don't build PIC code command="$base_compile $qsrcfile" fi func_mkdir_p "$xdir$objdir" if test -z "$output_obj"; then # Place PIC objects in $objdir command="$command -o $lobj" fi func_show_eval_locale "$command" \ 'test -n "$output_obj" && $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed, then go on to compile the next one if test -n "$output_obj" && test "X$output_obj" != "X$lobj"; then func_show_eval '$MV "$output_obj" "$lobj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi # Allow error messages only from the first compilation. if test "$suppress_opt" = yes; then suppress_output=' >/dev/null 2>&1' fi fi # Only build a position-dependent object if we build old libraries. if test "$build_old_libs" = yes; then if test "$pic_mode" != yes; then # Don't build PIC code command="$base_compile $qsrcfile$pie_flag" else command="$base_compile $qsrcfile $pic_flag" fi if test "$compiler_c_o" = yes; then command="$command -o $obj" fi # Suppress compiler output if we already did a PIC compilation. command="$command$suppress_output" func_show_eval_locale "$command" \ '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' if test "$need_locks" = warn && test "X`cat $lockfile 2>/dev/null`" != "X$srcfile"; then $ECHO "\ *** ERROR, $lockfile contains: `cat $lockfile 2>/dev/null` but it should contain: $srcfile This indicates that another process is trying to use the same temporary object file, and libtool could not work around it because your compiler does not support \`-c' and \`-o' together. If you repeat this compilation, it may succeed, by chance, but you had better avoid parallel builds (make -j) in this platform, or get a better compiler." $opt_dry_run || $RM $removelist exit $EXIT_FAILURE fi # Just move the object if needed if test -n "$output_obj" && test "X$output_obj" != "X$obj"; then func_show_eval '$MV "$output_obj" "$obj"' \ 'error=$?; $opt_dry_run || $RM $removelist; exit $error' fi fi $opt_dry_run || { func_write_libtool_object "$libobj" "$objdir/$objname" "$objname" # Unlock the critical section if it was locked if test "$need_locks" != no; then removelist=$lockfile $RM "$lockfile" fi } exit $EXIT_SUCCESS } $opt_help || { test "$mode" = compile && func_mode_compile ${1+"$@"} } func_mode_help () { # We need to display help for each of the modes. case $mode in "") # Generic help is extracted from the usage comments # at the start of this file. func_help ;; clean) $ECHO \ "Usage: $progname [OPTION]... --mode=clean RM [RM-OPTION]... FILE... Remove files from the build directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, object or program, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; compile) $ECHO \ "Usage: $progname [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE Compile a source file into a libtool library object. This mode accepts the following additional options: -o OUTPUT-FILE set the output file name to OUTPUT-FILE -no-suppress do not suppress compiler output for multiple passes -prefer-pic try to building PIC objects only -prefer-non-pic try to building non-PIC objects only -shared do not build a \`.o' file suitable for static linking -static only build a \`.o' file suitable for static linking COMPILE-COMMAND is a command to be used in creating a \`standard' object file from the given SOURCEFILE. The output file name is determined by removing the directory component from SOURCEFILE, then substituting the C source code suffix \`.c' with the library object suffix, \`.lo'." ;; execute) $ECHO \ "Usage: $progname [OPTION]... --mode=execute COMMAND [ARGS]... Automatically set library path, then run a program. This mode accepts the following additional options: -dlopen FILE add the directory containing FILE to the library path This mode sets the library path environment variable according to \`-dlopen' flags. If any of the ARGS are libtool executable wrappers, then they are translated into their corresponding uninstalled binary, and any of their required library directories are added to the library path. Then, COMMAND is executed, with ARGS as arguments." ;; finish) $ECHO \ "Usage: $progname [OPTION]... --mode=finish [LIBDIR]... Complete the installation of libtool libraries. Each LIBDIR is a directory that contains libtool libraries. The commands that this mode executes may require superuser privileges. Use the \`--dry-run' option if you just want to see what would be executed." ;; install) $ECHO \ "Usage: $progname [OPTION]... --mode=install INSTALL-COMMAND... Install executables or libraries. INSTALL-COMMAND is the installation command. The first component should be either the \`install' or \`cp' program. The following components of INSTALL-COMMAND are treated specially: -inst-prefix PREFIX-DIR Use PREFIX-DIR as a staging area for installation The rest of the components are interpreted as arguments to that command (only BSD-compatible install options are recognized)." ;; link) $ECHO \ "Usage: $progname [OPTION]... --mode=link LINK-COMMAND... Link object files or libraries together to form another library, or to create an executable program. LINK-COMMAND is a command using the C compiler that you would use to create a program from several object files. The following components of LINK-COMMAND are treated specially: -all-static do not do any dynamic linking at all -avoid-version do not add a version suffix if possible -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) -export-symbols SYMFILE try to export only the symbols listed in SYMFILE -export-symbols-regex REGEX try to export only the symbols matching REGEX -LLIBDIR search LIBDIR for required installed libraries -lNAME OUTPUT-FILE requires the installed library libNAME -module build a library that can dlopened -no-fast-install disable the fast-install mode -no-install link a not-installable executable -no-undefined declare that a library does not refer to external symbols -o OUTPUT-FILE create OUTPUT-FILE from the specified objects -objectlist FILE Use a list of object files found in FILE to specify objects -precious-files-regex REGEX don't remove output files matching REGEX -release RELEASE specify package release information -rpath LIBDIR the created library will eventually be installed in LIBDIR -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries -shared only do dynamic linking of libtool libraries -shrext SUFFIX override the standard shared library file extension -static do not do any dynamic linking of uninstalled libtool libraries -static-libtool-libs do not do any dynamic linking of libtool libraries -version-info CURRENT[:REVISION[:AGE]] specify library version info [each variable defaults to 0] -weak LIBNAME declare that the target provides the LIBNAME interface All other options (arguments beginning with \`-') are ignored. Every other argument is treated as a filename. Files ending in \`.la' are treated as uninstalled libtool libraries, other files are standard or library object files. If the OUTPUT-FILE ends in \`.la', then a libtool library is created, only library objects (\`.lo' files) may be specified, and \`-rpath' is required, except when creating a convenience library. If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created using \`ar' and \`ranlib', or on Windows using \`lib'. If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file is created, otherwise an executable program is created." ;; uninstall) $ECHO \ "Usage: $progname [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... Remove libraries from an installation directory. RM is the name of the program to use to delete files associated with each FILE (typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed to RM. If FILE is a libtool library, all the files associated with it are deleted. Otherwise, only FILE itself is deleted using RM." ;; *) func_fatal_help "invalid operation mode \`$mode'" ;; esac $ECHO $ECHO "Try \`$progname --help' for more information about other modes." exit $? } # Now that we've collected a possible --mode arg, show help if necessary $opt_help && func_mode_help # func_mode_execute arg... func_mode_execute () { $opt_debug # The first argument is the command name. cmd="$nonopt" test -z "$cmd" && \ func_fatal_help "you must specify a COMMAND" # Handle -dlopen flags immediately. for file in $execute_dlfiles; do test -f "$file" \ || func_fatal_help "\`$file' is not a file" dir= case $file in *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$lib' is not a valid libtool archive" # Read the libtool library. dlname= library_names= func_source "$file" # Skip this library if it cannot be dlopened. if test -z "$dlname"; then # Warn if it was a shared library. test -n "$library_names" && \ func_warning "\`$file' was not linked with \`-export-dynamic'" continue fi func_dirname "$file" "" "." dir="$func_dirname_result" if test -f "$dir/$objdir/$dlname"; then dir="$dir/$objdir" else if test ! -f "$dir/$dlname"; then func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" fi fi ;; *.lo) # Just add the directory containing the .lo file. func_dirname "$file" "" "." dir="$func_dirname_result" ;; *) func_warning "\`-dlopen' is ignored for non-libtool libraries and objects" continue ;; esac # Get the absolute pathname. absdir=`cd "$dir" && pwd` test -n "$absdir" && dir="$absdir" # Now add the directory to shlibpath_var. if eval "test -z \"\$$shlibpath_var\""; then eval "$shlibpath_var=\"\$dir\"" else eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" fi done # This variable tells wrapper scripts just to set shlibpath_var # rather than running their programs. libtool_execute_magic="$magic" # Check if any of the arguments is a wrapper script. args= for file do case $file in -*) ;; *) # Do a test to see if this is really a libtool program. if func_ltwrapper_script_p "$file"; then func_source "$file" # Transform arg to wrapped name. file="$progdir/$program" elif func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" func_source "$func_ltwrapper_scriptname_result" # Transform arg to wrapped name. file="$progdir/$program" fi ;; esac # Quote arguments (to preserve shell metacharacters). func_quote_for_eval "$file" args="$args $func_quote_for_eval_result" done if test "X$opt_dry_run" = Xfalse; then if test -n "$shlibpath_var"; then # Export the shlibpath_var. eval "export $shlibpath_var" fi # Restore saved environment variables for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES do eval "if test \"\${save_$lt_var+set}\" = set; then $lt_var=\$save_$lt_var; export $lt_var else $lt_unset $lt_var fi" done # Now prepare to actually exec the command. exec_cmd="\$cmd$args" else # Display what would be done. if test -n "$shlibpath_var"; then eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\"" $ECHO "export $shlibpath_var" fi $ECHO "$cmd$args" exit $EXIT_SUCCESS fi } test "$mode" = execute && func_mode_execute ${1+"$@"} # func_mode_finish arg... func_mode_finish () { $opt_debug libdirs="$nonopt" admincmds= if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then for dir do libdirs="$libdirs $dir" done for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. func_execute_cmds "$finish_cmds" 'admincmds="$admincmds '"$cmd"'"' fi if test -n "$finish_eval"; then # Do the single finish_eval. eval cmds=\"$finish_eval\" $opt_dry_run || eval "$cmds" || admincmds="$admincmds $cmds" fi done fi # Exit here if they wanted silent mode. $opt_silent && exit $EXIT_SUCCESS $ECHO "X----------------------------------------------------------------------" | $Xsed $ECHO "Libraries have been installed in:" for libdir in $libdirs; do $ECHO " $libdir" done $ECHO $ECHO "If you ever happen to want to link against installed libraries" $ECHO "in a given directory, LIBDIR, you must either use libtool, and" $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'" $ECHO "flag during linking and do at least one of the following:" if test -n "$shlibpath_var"; then $ECHO " - add LIBDIR to the \`$shlibpath_var' environment variable" $ECHO " during execution" fi if test -n "$runpath_var"; then $ECHO " - add LIBDIR to the \`$runpath_var' environment variable" $ECHO " during linking" fi if test -n "$hardcode_libdir_flag_spec"; then libdir=LIBDIR eval flag=\"$hardcode_libdir_flag_spec\" $ECHO " - use the \`$flag' linker flag" fi if test -n "$admincmds"; then $ECHO " - have your system administrator run these commands:$admincmds" fi if test -f /etc/ld.so.conf; then $ECHO " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" fi $ECHO $ECHO "See any operating system documentation about shared libraries for" case $host in solaris2.[6789]|solaris2.1[0-9]) $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual" $ECHO "pages." ;; *) $ECHO "more information, such as the ld(1) and ld.so(8) manual pages." ;; esac $ECHO "X----------------------------------------------------------------------" | $Xsed exit $EXIT_SUCCESS } test "$mode" = finish && func_mode_finish ${1+"$@"} # func_mode_install arg... func_mode_install () { $opt_debug # There may be an optional sh(1) argument at the beginning of # install_prog (especially on Windows NT). if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || # Allow the use of GNU shtool's install command. $ECHO "X$nonopt" | $GREP shtool >/dev/null; then # Aesthetically quote it. func_quote_for_eval "$nonopt" install_prog="$func_quote_for_eval_result " arg=$1 shift else install_prog= arg=$nonopt fi # The real first argument should be the name of the installation program. # Aesthetically quote it. func_quote_for_eval "$arg" install_prog="$install_prog$func_quote_for_eval_result" # We need to accept at least all the BSD install flags. dest= files= opts= prev= install_type= isdir=no stripme= for arg do if test -n "$dest"; then files="$files $dest" dest=$arg continue fi case $arg in -d) isdir=yes ;; -f) case " $install_prog " in *[\\\ /]cp\ *) ;; *) prev=$arg ;; esac ;; -g | -m | -o) prev=$arg ;; -s) stripme=" -s" continue ;; -*) ;; *) # If the previous option needed an argument, then skip it. if test -n "$prev"; then prev= else dest=$arg continue fi ;; esac # Aesthetically quote the argument. func_quote_for_eval "$arg" install_prog="$install_prog $func_quote_for_eval_result" done test -z "$install_prog" && \ func_fatal_help "you must specify an install program" test -n "$prev" && \ func_fatal_help "the \`$prev' option requires an argument" if test -z "$files"; then if test -z "$dest"; then func_fatal_help "no file or destination specified" else func_fatal_help "you must specify a destination" fi fi # Strip any trailing slash from the destination. func_stripname '' '/' "$dest" dest=$func_stripname_result # Check to see that the destination is a directory. test -d "$dest" && isdir=yes if test "$isdir" = yes; then destdir="$dest" destname= else func_dirname_and_basename "$dest" "" "." destdir="$func_dirname_result" destname="$func_basename_result" # Not a directory, so check to see that there is only one file specified. set dummy $files; shift test "$#" -gt 1 && \ func_fatal_help "\`$dest' is not a directory" fi case $destdir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) for file in $files; do case $file in *.lo) ;; *) func_fatal_help "\`$destdir' must be an absolute directory name" ;; esac done ;; esac # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" staticlibs= future_libdirs= current_libdirs= for file in $files; do # Do each installation. case $file in *.$libext) # Do the static libraries later. staticlibs="$staticlibs $file" ;; *.la) # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$file" \ || func_fatal_help "\`$file' is not a valid libtool archive" library_names= old_library= relink_command= func_source "$file" # Add the libdir to current_libdirs if it is the destination. if test "X$destdir" = "X$libdir"; then case "$current_libdirs " in *" $libdir "*) ;; *) current_libdirs="$current_libdirs $libdir" ;; esac else # Note the libdir as a future libdir. case "$future_libdirs " in *" $libdir "*) ;; *) future_libdirs="$future_libdirs $libdir" ;; esac fi func_dirname "$file" "/" "" dir="$func_dirname_result" dir="$dir$objdir" if test -n "$relink_command"; then # Determine the prefix the user has applied to our future dir. inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that # are installed to the same prefix. # At present, this check doesn't affect windows .dll's that # are installed into $libdir/../bin (currently, that works fine) # but it's something to keep an eye on. test "$inst_prefix_dir" = "$destdir" && \ func_fatal_error "error: cannot install \`$file' to a directory not ending in $libdir" if test -n "$inst_prefix_dir"; then # Stick the inst_prefix_dir data into the link command. relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"` else relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"` fi func_warning "relinking \`$file'" func_show_eval "$relink_command" \ 'func_fatal_error "error: relink \`$file'\'' with the above command before installing it"' fi # See the names of the shared library. set dummy $library_names; shift if test -n "$1"; then realname="$1" shift srcname="$realname" test -n "$relink_command" && srcname="$realname"T # Install the shared library and build the symlinks. func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \ 'exit $?' tstripme="$stripme" case $host_os in cygwin* | mingw* | pw32* | cegcc*) case $realname in *.dll.a) tstripme="" ;; esac ;; esac if test -n "$tstripme" && test -n "$striplib"; then func_show_eval "$striplib $destdir/$realname" 'exit $?' fi if test "$#" -gt 0; then # Delete the old symlinks, and create new ones. # Try `ln -sf' first, because the `ln' binary might depend on # the symlink we replace! Solaris /bin/ln does not understand -f, # so we also need to try rm && ln -s. for linkname do test "$linkname" != "$realname" \ && func_show_eval "(cd $destdir && { $LN_S -f $realname $linkname || { $RM $linkname && $LN_S $realname $linkname; }; })" done fi # Do each command in the postinstall commands. lib="$destdir/$realname" func_execute_cmds "$postinstall_cmds" 'exit $?' fi # Install the pseudo-library for information purposes. func_basename "$file" name="$func_basename_result" instname="$dir/$name"i func_show_eval "$install_prog $instname $destdir/$name" 'exit $?' # Maybe install the static library, too. test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" ;; *.lo) # Install (i.e. copy) a libtool object. # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # Deduce the name of the destination old-style object file. case $destfile in *.lo) func_lo2o "$destfile" staticdest=$func_lo2o_result ;; *.$objext) staticdest="$destfile" destfile= ;; *) func_fatal_help "cannot copy a libtool object to \`$destfile'" ;; esac # Install the libtool object if requested. test -n "$destfile" && \ func_show_eval "$install_prog $file $destfile" 'exit $?' # Install the old object if enabled. if test "$build_old_libs" = yes; then # Deduce the name of the old-style object file. func_lo2o "$file" staticobj=$func_lo2o_result func_show_eval "$install_prog \$staticobj \$staticdest" 'exit $?' fi exit $EXIT_SUCCESS ;; *) # Figure out destination file name, if it wasn't already specified. if test -n "$destname"; then destfile="$destdir/$destname" else func_basename "$file" destfile="$func_basename_result" destfile="$destdir/$destfile" fi # If the file is missing, and there is a .exe on the end, strip it # because it is most likely a libtool script we actually want to # install stripped_ext="" case $file in *.exe) if test ! -f "$file"; then func_stripname '' '.exe' "$file" file=$func_stripname_result stripped_ext=".exe" fi ;; esac # Do a test to see if this is really a libtool program. case $host in *cygwin* | *mingw*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result else func_stripname '' '.exe' "$file" wrapper=$func_stripname_result fi ;; *) wrapper=$file ;; esac if func_ltwrapper_script_p "$wrapper"; then notinst_deplibs= relink_command= func_source "$wrapper" # Check the variables that should have been set. test -z "$generated_by_libtool_version" && \ func_fatal_error "invalid libtool wrapper script \`$wrapper'" finalize=yes for lib in $notinst_deplibs; do # Check to see that each library is installed. libdir= if test -f "$lib"; then func_source "$lib" fi libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test if test -n "$libdir" && test ! -f "$libfile"; then func_warning "\`$lib' has not been installed in \`$libdir'" finalize=no fi done relink_command= func_source "$wrapper" outputname= if test "$fast_install" = no && test -n "$relink_command"; then $opt_dry_run || { if test "$finalize" = yes; then tmpdir=`func_mktempdir` func_basename "$file$stripped_ext" file="$func_basename_result" outputname="$tmpdir/$file" # Replace the output file specification. relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` $opt_silent || { func_quote_for_expand "$relink_command" eval "func_echo $func_quote_for_expand_result" } if eval "$relink_command"; then : else func_error "error: relink \`$file' with the above command before installing it" $opt_dry_run || ${RM}r "$tmpdir" continue fi file="$outputname" else func_warning "cannot relink \`$file'" fi } else # Install the binary that we compiled earlier. file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` fi fi # remove .exe since cygwin /usr/bin/install will append another # one anyway case $install_prog,$host in */usr/bin/install*,*cygwin*) case $file:$destfile in *.exe:*.exe) # this is ok ;; *.exe:*) destfile=$destfile.exe ;; *:*.exe) func_stripname '' '.exe' "$destfile" destfile=$func_stripname_result ;; esac ;; esac func_show_eval "$install_prog\$stripme \$file \$destfile" 'exit $?' $opt_dry_run || if test -n "$outputname"; then ${RM}r "$tmpdir" fi ;; esac done for file in $staticlibs; do func_basename "$file" name="$func_basename_result" # Set up the ranlib parameters. oldlib="$destdir/$name" func_show_eval "$install_prog \$file \$oldlib" 'exit $?' if test -n "$stripme" && test -n "$old_striplib"; then func_show_eval "$old_striplib $oldlib" 'exit $?' fi # Do each command in the postinstall commands. func_execute_cmds "$old_postinstall_cmds" 'exit $?' done test -n "$future_libdirs" && \ func_warning "remember to run \`$progname --finish$future_libdirs'" if test -n "$current_libdirs"; then # Maybe just do a dry run. $opt_dry_run && current_libdirs=" -n$current_libdirs" exec_cmd='$SHELL $progpath $preserve_args --finish$current_libdirs' else exit $EXIT_SUCCESS fi } test "$mode" = install && func_mode_install ${1+"$@"} # func_generate_dlsyms outputname originator pic_p # Extract symbols from dlprefiles and create ${outputname}S.o with # a dlpreopen symbol table. func_generate_dlsyms () { $opt_debug my_outputname="$1" my_originator="$2" my_pic_p="${3-no}" my_prefix=`$ECHO "$my_originator" | sed 's%[^a-zA-Z0-9]%_%g'` my_dlsyms= if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then if test -n "$NM" && test -n "$global_symbol_pipe"; then my_dlsyms="${my_outputname}S.c" else func_error "not configured to extract global symbols from dlpreopened files" fi fi if test -n "$my_dlsyms"; then case $my_dlsyms in "") ;; *.c) # Discover the nlist of each of the dlfiles. nlist="$output_objdir/${my_outputname}.nm" func_show_eval "$RM $nlist ${nlist}S ${nlist}T" # Parse the name list into a source file. func_verbose "creating $output_objdir/$my_dlsyms" $opt_dry_run || $ECHO > "$output_objdir/$my_dlsyms" "\ /* $my_dlsyms - symbol resolution table for \`$my_outputname' dlsym emulation. */ /* Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION */ #ifdef __cplusplus extern \"C\" { #endif /* External symbol declarations for the compiler. */\ " if test "$dlself" = yes; then func_verbose "generating symbol list for \`$output'" $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist" # Add our own program objects to the symbol list. progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` for progfile in $progfiles; do func_verbose "extracting global C symbols from \`$progfile'" $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'" done if test -n "$exclude_expsyms"; then $opt_dry_run || { eval '$EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi if test -n "$export_symbols_regex"; then $opt_dry_run || { eval '$EGREP -e "$export_symbols_regex" "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' } fi # Prepare the list of exported symbols if test -z "$export_symbols"; then export_symbols="$output_objdir/$outputname.exp" $opt_dry_run || { $RM $export_symbols eval "${SED} -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in *cygwin* | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; esac } else $opt_dry_run || { eval "${SED} -e 's/\([].[*^$]\)/\\\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$outputname.exp"' eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in *cygwin | *mingw* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; esac } fi fi for dlprefile in $dlprefiles; do func_verbose "extracting global C symbols from \`$dlprefile'" func_basename "$dlprefile" name="$func_basename_result" $opt_dry_run || { eval '$ECHO ": $name " >> "$nlist"' eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'" } done $opt_dry_run || { # Make sure we have at least an empty file. test -f "$nlist" || : > "$nlist" if test -n "$exclude_expsyms"; then $EGREP -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T $MV "$nlist"T "$nlist" fi # Try sorting and uniquifying the output. if $GREP -v "^: " < "$nlist" | if sort -k 3 /dev/null 2>&1; then sort -k 3 else sort +2 fi | uniq > "$nlist"S; then : else $GREP -v "^: " < "$nlist" > "$nlist"S fi if test -f "$nlist"S; then eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"' else $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms" fi $ECHO >> "$output_objdir/$my_dlsyms" "\ /* The mapping between symbol names and symbols. */ typedef struct { const char *name; void *address; } lt_dlsymlist; " case $host in *cygwin* | *mingw* | *cegcc* ) $ECHO >> "$output_objdir/$my_dlsyms" "\ /* DATA imports from DLLs on WIN32 con't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */" lt_dlsym_const= ;; *osf5*) echo >> "$output_objdir/$my_dlsyms" "\ /* This system does not cope well with relocations in const data */" lt_dlsym_const= ;; *) lt_dlsym_const=const ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ extern $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[]; $lt_dlsym_const lt_dlsymlist lt_${my_prefix}_LTX_preloaded_symbols[] = {\ { \"$my_originator\", (void *) 0 }," case $need_lib_prefix in no) eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; *) eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms" ;; esac $ECHO >> "$output_objdir/$my_dlsyms" "\ {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt_${my_prefix}_LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif\ " } # !$opt_dry_run pic_flag_for_symtable= case "$compile_command " in *" -static "*) ;; *) case $host in # compiling the symbol table file with pic_flag works around # a FreeBSD bug that causes programs to crash when -lm is # linked before any other PIC object. But we must not use # pic_flag when linking with -static. The problem exists in # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;; *-*-hpux*) pic_flag_for_symtable=" $pic_flag" ;; *) if test "X$my_pic_p" != Xno; then pic_flag_for_symtable=" $pic_flag" fi ;; esac ;; esac symtab_cflags= for arg in $LTCFLAGS; do case $arg in -pie | -fpie | -fPIE) ;; *) symtab_cflags="$symtab_cflags $arg" ;; esac done # Now compile the dynamic symbol file. func_show_eval '(cd $output_objdir && $LTCC$symtab_cflags -c$no_builtin_flag$pic_flag_for_symtable "$my_dlsyms")' 'exit $?' # Clean up the generated files. func_show_eval '$RM "$output_objdir/$my_dlsyms" "$nlist" "${nlist}S" "${nlist}T"' # Transform the symbol file into the correct name. symfileobj="$output_objdir/${my_outputname}S.$objext" case $host in *cygwin* | *mingw* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` else compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` fi ;; *) compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"` ;; esac ;; *) func_fatal_error "unknown suffix for \`$my_dlsyms'" ;; esac else # We keep going just in case the user didn't refer to # lt_preloaded_symbols. The linker will fail if global_symbol_pipe # really was required. # Nullify the symbol file. compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` fi } # func_win32_libid arg # return the library type of file 'arg' # # Need a lot of goo to handle *both* DLLs and import libs # Has to be a shell function in order to 'eat' the argument # that is supplied when $file_magic_command is called. func_win32_libid () { $opt_debug win32_libid_type="unknown" win32_fileres=`file -L $1 2>/dev/null` case $win32_fileres in *ar\ archive\ import\ library*) # definitely import win32_libid_type="x86 archive import" ;; *ar\ archive*) # could be an import, or static if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then win32_nmres=`eval $NM -f posix -A $1 | $SED -n -e ' 1,100{ / I /{ s,.*,import, p q } }'` case $win32_nmres in import*) win32_libid_type="x86 archive import";; *) win32_libid_type="x86 archive static";; esac fi ;; *DLL*) win32_libid_type="x86 DLL" ;; *executable*) # but shell scripts are "executable" too... case $win32_fileres in *MS\ Windows\ PE\ Intel*) win32_libid_type="x86 DLL" ;; esac ;; esac $ECHO "$win32_libid_type" } # func_extract_an_archive dir oldlib func_extract_an_archive () { $opt_debug f_ex_an_ar_dir="$1"; shift f_ex_an_ar_oldlib="$1" func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?' if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then : else func_fatal_error "object name conflicts in archive: $f_ex_an_ar_dir/$f_ex_an_ar_oldlib" fi } # func_extract_archives gentop oldlib ... func_extract_archives () { $opt_debug my_gentop="$1"; shift my_oldlibs=${1+"$@"} my_oldobjs="" my_xlib="" my_xabs="" my_xdir="" for my_xlib in $my_oldlibs; do # Extract the objects. case $my_xlib in [\\/]* | [A-Za-z]:[\\/]*) my_xabs="$my_xlib" ;; *) my_xabs=`pwd`"/$my_xlib" ;; esac func_basename "$my_xlib" my_xlib="$func_basename_result" my_xlib_u=$my_xlib while :; do case " $extracted_archives " in *" $my_xlib_u "*) func_arith $extracted_serial + 1 extracted_serial=$func_arith_result my_xlib_u=lt$extracted_serial-$my_xlib ;; *) break ;; esac done extracted_archives="$extracted_archives $my_xlib_u" my_xdir="$my_gentop/$my_xlib_u" func_mkdir_p "$my_xdir" case $host in *-darwin*) func_verbose "Extracting $my_xabs" # Do not bother doing anything if just a dry run $opt_dry_run || { darwin_orig_dir=`pwd` cd $my_xdir || exit $? darwin_archive=$my_xabs darwin_curdir=`pwd` darwin_base_archive=`basename "$darwin_archive"` darwin_arches=`$LIPO -info "$darwin_archive" 2>/dev/null | $GREP Architectures 2>/dev/null || true` if test -n "$darwin_arches"; then darwin_arches=`$ECHO "$darwin_arches" | $SED -e 's/.*are://'` darwin_arch= func_verbose "$darwin_base_archive has multiple architectures $darwin_arches" for darwin_arch in $darwin_arches ; do func_mkdir_p "unfat-$$/${darwin_base_archive}-${darwin_arch}" $LIPO -thin $darwin_arch -output "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" "${darwin_archive}" cd "unfat-$$/${darwin_base_archive}-${darwin_arch}" func_extract_an_archive "`pwd`" "${darwin_base_archive}" cd "$darwin_curdir" $RM "unfat-$$/${darwin_base_archive}-${darwin_arch}/${darwin_base_archive}" done # $darwin_arches ## Okay now we've a bunch of thin objects, gotta fatten them up :) darwin_filelist=`find unfat-$$ -type f -name \*.o -print -o -name \*.lo -print | $SED -e "$basename" | sort -u` darwin_file= darwin_files= for darwin_file in $darwin_filelist; do darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP` $LIPO -create -output "$darwin_file" $darwin_files done # $darwin_filelist $RM -rf unfat-$$ cd "$darwin_orig_dir" else cd $darwin_orig_dir func_extract_an_archive "$my_xdir" "$my_xabs" fi # $darwin_arches } # !$opt_dry_run ;; *) func_extract_an_archive "$my_xdir" "$my_xabs" ;; esac my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP` done func_extract_archives_result="$my_oldobjs" } # func_emit_wrapper_part1 [arg=no] # # Emit the first part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part1 () { func_emit_wrapper_part1_arg1=no if test -n "$1" ; then func_emit_wrapper_part1_arg1=$1 fi $ECHO "\ #! $SHELL # $output - temporary wrapper script for $objdir/$outputname # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # The $output program cannot be directly executed until all the libtool # libraries that it depends on are installed. # # This wrapper script should never be moved out of the build directory. # If it is, it will not operate correctly. # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. Xsed='${SED} -e 1s/^X//' sed_quote_subst='$sed_quote_subst' # Be Bourne compatible if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in *posix*) set -o posix;; esac fi BIN_SH=xpg4; export BIN_SH # for Tru64 DUALCASE=1; export DUALCASE # for MKS sh # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH relink_command=\"$relink_command\" # This environment variable determines our operation mode. if test \"\$libtool_install_magic\" = \"$magic\"; then # install mode needs the following variables: generated_by_libtool_version='$macro_version' notinst_deplibs='$notinst_deplibs' else # When we are sourced in execute mode, \$file and \$ECHO are already set. if test \"\$libtool_execute_magic\" != \"$magic\"; then ECHO=\"$qecho\" file=\"\$0\" # Make sure echo works. if test \"X\$1\" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then # Yippee, \$ECHO works! : else # Restart under the correct shell, and then maybe \$ECHO will work. exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} fi fi\ " $ECHO "\ # Find the directory that this script lives in. thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` test \"x\$thisdir\" = \"x\$file\" && thisdir=. # Follow symbolic links until we get to the real thisdir. file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\` while test -n \"\$file\"; do destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` # If there was a directory component, then change thisdir. if test \"x\$destdir\" != \"x\$file\"; then case \"\$destdir\" in [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; *) thisdir=\"\$thisdir/\$destdir\" ;; esac fi file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\` file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\` done " } # end: func_emit_wrapper_part1 # func_emit_wrapper_part2 [arg=no] # # Emit the second part of a libtool wrapper script on stdout. # For more information, see the description associated with # func_emit_wrapper(), below. func_emit_wrapper_part2 () { func_emit_wrapper_part2_arg1=no if test -n "$1" ; then func_emit_wrapper_part2_arg1=$1 fi $ECHO "\ # Usually 'no', except on cygwin/mingw when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then # special case for '.' if test \"\$thisdir\" = \".\"; then thisdir=\`pwd\` fi # remove .libs from thisdir case \"\$thisdir\" in *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;; $objdir ) thisdir=. ;; esac fi # Try to get the absolute directory name. absdir=\`cd \"\$thisdir\" && pwd\` test -n \"\$absdir\" && thisdir=\"\$absdir\" " if test "$fast_install" = yes; then $ECHO "\ program=lt-'$outputname'$exeext progdir=\"\$thisdir/$objdir\" if test ! -f \"\$progdir/\$program\" || { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | ${SED} 1q\`; \\ test \"X\$file\" != \"X\$progdir/\$program\"; }; then file=\"\$\$-\$program\" if test ! -d \"\$progdir\"; then $MKDIR \"\$progdir\" else $RM \"\$progdir/\$file\" fi" $ECHO "\ # relink executable if necessary if test -n \"\$relink_command\"; then if relink_command_output=\`eval \$relink_command 2>&1\`; then : else $ECHO \"\$relink_command_output\" >&2 $RM \"\$progdir/\$file\" exit 1 fi fi $MV \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || { $RM \"\$progdir/\$program\"; $MV \"\$progdir/\$file\" \"\$progdir/\$program\"; } $RM \"\$progdir/\$file\" fi" else $ECHO "\ program='$outputname' progdir=\"\$thisdir/$objdir\" " fi $ECHO "\ if test -f \"\$progdir/\$program\"; then" # Export our shlibpath_var if we have one. if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then $ECHO "\ # Add our own library path to $shlibpath_var $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" # Some systems cannot cope with colon-terminated $shlibpath_var # The second colon is a workaround for a bug in BeOS R4 sed $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` export $shlibpath_var " fi # fixup the dll searchpath if we need to. if test -n "$dllsearchpath"; then $ECHO "\ # Add the dll search path components to the executable PATH PATH=$dllsearchpath:\$PATH " fi $ECHO "\ if test \"\$libtool_execute_magic\" != \"$magic\"; then # Run the actual program with our arguments. " case $host in # Backslashes separate directories on plain windows *-*-mingw | *-*-os2* | *-cegcc*) $ECHO "\ exec \"\$progdir\\\\\$program\" \${1+\"\$@\"} " ;; *) $ECHO "\ exec \"\$progdir/\$program\" \${1+\"\$@\"} " ;; esac $ECHO "\ \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2 exit 1 fi else # The program doesn't exist. \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2 \$ECHO \"This script is just a wrapper for \$program.\" 1>&2 $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2 exit 1 fi fi\ " } # end: func_emit_wrapper_part2 # func_emit_wrapper [arg=no] # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to # incorporate the script contents within a cygwin/mingw # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. # # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory in which it is stored is # the $objdir directory. This is a cygwin/mingw-specific # behavior. func_emit_wrapper () { func_emit_wrapper_arg1=no if test -n "$1" ; then func_emit_wrapper_arg1=$1 fi # split this up so that func_emit_cwrapperexe_src # can call each part independently. func_emit_wrapper_part1 "${func_emit_wrapper_arg1}" func_emit_wrapper_part2 "${func_emit_wrapper_arg1}" } # func_to_host_path arg # # Convert paths to host format when used with build tools. # Intended for use with "native" mingw (where libtool itself # is running under the msys shell), or in the following cross- # build environments: # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # where wine is equipped with the `winepath' executable. # In the native mingw case, the (msys) shell automatically # converts paths for any non-msys applications it launches, # but that facility isn't available from inside the cwrapper. # Similar accommodations are necessary for $host mingw and # $build cygwin. Calling this function does no harm for other # $host/$build combinations not listed above. # # ARG is the path (on $build) that should be converted to # the proper representation for $host. The result is stored # in $func_to_host_path_result. func_to_host_path () { func_to_host_path_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' case $build in *mingw* ) # actually, msys # awkward: cmd appends spaces to result lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_path_tmp1=`( cmd //c echo "$1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_path_tmp1=`cygpath -w "$1"` func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # Unfortunately, winepath does not exit with a non-zero # error code, so we are forced to check the contents of # stdout. On the other hand, if the command is not # found, the shell will set an exit code of 127 and print # *an error message* to stdout. So we must check for both # error code of zero AND non-empty stdout, which explains # the odd construction: func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null` if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\ $SED -e "$lt_sed_naive_backslashify"` else # Allow warning below. func_to_host_path_result="" fi ;; esac if test -z "$func_to_host_path_result" ; then func_error "Could not determine host path corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback: func_to_host_path_result="$1" fi ;; esac fi } # end: func_to_host_path # func_to_host_pathlist arg # # Convert pathlists to host format when used with build tools. # See func_to_host_path(), above. This function supports the # following $build/$host combinations (but does no harm for # combinations not listed here): # $build $host # mingw (msys) mingw [e.g. native] # cygwin mingw # *nix + wine mingw # # Path separators are also converted from $build format to # $host format. If ARG begins or ends with a path separator # character, it is preserved (but converted to $host format) # on output. # # ARG is a pathlist (on $build) that should be converted to # the proper representation on $host. The result is stored # in $func_to_host_pathlist_result. func_to_host_pathlist () { func_to_host_pathlist_result="$1" if test -n "$1" ; then case $host in *mingw* ) lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g' # Remove leading and trailing path separator characters from # ARG. msys behavior is inconsistent here, cygpath turns them # into '.;' and ';.', and winepath ignores them completely. func_to_host_pathlist_tmp2="$1" # Once set for this call, this variable should not be # reassigned. It is used in tha fallback case. func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e 's|^:*||' -e 's|:*$||'` case $build in *mingw* ) # Actually, msys. # Awkward: cmd appends spaces to result. lt_sed_strip_trailing_spaces="s/[ ]*\$//" func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; *cygwin* ) func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"` func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\ $SED -e "$lt_sed_naive_backslashify"` ;; * ) # unfortunately, winepath doesn't convert pathlists func_to_host_pathlist_result="" func_to_host_pathlist_oldIFS=$IFS IFS=: for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do IFS=$func_to_host_pathlist_oldIFS if test -n "$func_to_host_pathlist_f" ; then func_to_host_path "$func_to_host_pathlist_f" if test -n "$func_to_host_path_result" ; then if test -z "$func_to_host_pathlist_result" ; then func_to_host_pathlist_result="$func_to_host_path_result" else func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result" fi fi fi IFS=: done IFS=$func_to_host_pathlist_oldIFS ;; esac if test -z "$func_to_host_pathlist_result" ; then func_error "Could not determine the host path(s) corresponding to" func_error " '$1'" func_error "Continuing, but uninstalled executables may not work." # Fallback. This may break if $1 contains DOS-style drive # specifications. The fix is not to complicate the expression # below, but for the user to provide a working wine installation # with winepath so that path translation in the cross-to-mingw # case works properly. lt_replace_pathsep_nix_to_dos="s|:|;|g" func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\ $SED -e "$lt_replace_pathsep_nix_to_dos"` fi # Now, add the leading and trailing path separators back case "$1" in :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result" ;; esac case "$1" in *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;" ;; esac ;; esac fi } # end: func_to_host_pathlist # func_emit_cwrapperexe_src # emit the source code for a wrapper executable on stdout # Must ONLY be called from within func_mode_link because # it depends on a number of variable set therein. func_emit_cwrapperexe_src () { cat < #include #ifdef _MSC_VER # include # include # include # define setmode _setmode #else # include # include # ifdef __CYGWIN__ # include # define HAVE_SETENV # ifdef __STRICT_ANSI__ char *realpath (const char *, char *); int putenv (char *); int setenv (const char *, const char *, int); # endif # endif #endif #include #include #include #include #include #include #include #include #if defined(PATH_MAX) # define LT_PATHMAX PATH_MAX #elif defined(MAXPATHLEN) # define LT_PATHMAX MAXPATHLEN #else # define LT_PATHMAX 1024 #endif #ifndef S_IXOTH # define S_IXOTH 0 #endif #ifndef S_IXGRP # define S_IXGRP 0 #endif #ifdef _MSC_VER # define S_IXUSR _S_IEXEC # define stat _stat # ifndef _INTPTR_T_DEFINED # define intptr_t int # endif #endif #ifndef DIR_SEPARATOR # define DIR_SEPARATOR '/' # define PATH_SEPARATOR ':' #endif #if defined (_WIN32) || defined (__MSDOS__) || defined (__DJGPP__) || \ defined (__OS2__) # define HAVE_DOS_BASED_FILE_SYSTEM # define FOPEN_WB "wb" # ifndef DIR_SEPARATOR_2 # define DIR_SEPARATOR_2 '\\' # endif # ifndef PATH_SEPARATOR_2 # define PATH_SEPARATOR_2 ';' # endif #endif #ifndef DIR_SEPARATOR_2 # define IS_DIR_SEPARATOR(ch) ((ch) == DIR_SEPARATOR) #else /* DIR_SEPARATOR_2 */ # define IS_DIR_SEPARATOR(ch) \ (((ch) == DIR_SEPARATOR) || ((ch) == DIR_SEPARATOR_2)) #endif /* DIR_SEPARATOR_2 */ #ifndef PATH_SEPARATOR_2 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR) #else /* PATH_SEPARATOR_2 */ # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2) #endif /* PATH_SEPARATOR_2 */ #ifdef __CYGWIN__ # define FOPEN_WB "wb" #endif #ifndef FOPEN_WB # define FOPEN_WB "w" #endif #ifndef _O_BINARY # define _O_BINARY 0 #endif #define XMALLOC(type, num) ((type *) xmalloc ((num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free ((void *) stale); stale = 0; } \ } while (0) #undef LTWRAPPER_DEBUGPRINTF #if defined DEBUGWRAPPER # define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args static void ltwrapper_debugprintf (const char *fmt, ...) { va_list args; va_start (args, fmt); (void) vfprintf (stderr, fmt, args); va_end (args); } #else # define LTWRAPPER_DEBUGPRINTF(args) #endif const char *program_name = NULL; void *xmalloc (size_t num); char *xstrdup (const char *string); const char *base_name (const char *name); char *find_executable (const char *wrapper); char *chase_symlinks (const char *pathspec); int make_executable (const char *path); int check_executable (const char *path); char *strendzap (char *str, const char *pat); void lt_fatal (const char *message, ...); void lt_setenv (const char *name, const char *value); char *lt_extend_str (const char *orig_value, const char *add, int to_end); void lt_opt_process_env_set (const char *arg); void lt_opt_process_env_prepend (const char *arg); void lt_opt_process_env_append (const char *arg); int lt_split_name_value (const char *arg, char** name, char** value); void lt_update_exe_path (const char *name, const char *value); void lt_update_lib_path (const char *name, const char *value); static const char *script_text_part1 = EOF func_emit_wrapper_part1 yes | $SED -e 's/\([\\"]\)/\\\1/g' \ -e 's/^/ "/' -e 's/$/\\n"/' echo ";" cat <"))); for (i = 0; i < newargc; i++) { LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d] : %s\n", i, (newargz[i] ? newargz[i] : ""))); } EOF case $host_os in mingw*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz); if (rval == -1) { /* failed to start process */ LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno)); return 127; } return rval; EOF ;; *) cat <<"EOF" execv (lt_argv_zero, newargz); return rval; /* =127, but avoids unused variable warning */ EOF ;; esac cat <<"EOF" } void * xmalloc (size_t num) { void *p = (void *) malloc (num); if (!p) lt_fatal ("Memory exhausted"); return p; } char * xstrdup (const char *string) { return string ? strcpy ((char *) xmalloc (strlen (string) + 1), string) : NULL; } const char * base_name (const char *name) { const char *base; #if defined (HAVE_DOS_BASED_FILE_SYSTEM) /* Skip over the disk name in MSDOS pathnames. */ if (isalpha ((unsigned char) name[0]) && name[1] == ':') name += 2; #endif for (base = name; *name; name++) if (IS_DIR_SEPARATOR (*name)) base = name + 1; return base; } int check_executable (const char *path) { struct stat st; LTWRAPPER_DEBUGPRINTF (("(check_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if ((stat (path, &st) >= 0) && (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) return 1; else return 0; } int make_executable (const char *path) { int rval = 0; struct stat st; LTWRAPPER_DEBUGPRINTF (("(make_executable) : %s\n", path ? (*path ? path : "EMPTY!") : "NULL!")); if ((!path) || (!*path)) return 0; if (stat (path, &st) >= 0) { rval = chmod (path, st.st_mode | S_IXOTH | S_IXGRP | S_IXUSR); } return rval; } /* Searches for the full path of the wrapper. Returns newly allocated full path name if found, NULL otherwise Does not chase symlinks, even on platforms that support them. */ char * find_executable (const char *wrapper) { int has_slash = 0; const char *p; const char *p_next; /* static buffer for getcwd */ char tmp[LT_PATHMAX + 1]; int tmp_len; char *concat_name; LTWRAPPER_DEBUGPRINTF (("(find_executable) : %s\n", wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!")); if ((wrapper == NULL) || (*wrapper == '\0')) return NULL; /* Absolute path? */ #if defined (HAVE_DOS_BASED_FILE_SYSTEM) if (isalpha ((unsigned char) wrapper[0]) && wrapper[1] == ':') { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } else { #endif if (IS_DIR_SEPARATOR (wrapper[0])) { concat_name = xstrdup (wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } #if defined (HAVE_DOS_BASED_FILE_SYSTEM) } #endif for (p = wrapper; *p; p++) if (*p == '/') { has_slash = 1; break; } if (!has_slash) { /* no slashes; search PATH */ const char *path = getenv ("PATH"); if (path != NULL) { for (p = path; *p; p = p_next) { const char *q; size_t p_len; for (q = p; *q; q++) if (IS_PATH_SEPARATOR (*q)) break; p_len = q - p; p_next = (*q == '\0' ? q : q + 1); if (p_len == 0) { /* empty path: current directory */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); } else { concat_name = XMALLOC (char, p_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, p, p_len); concat_name[p_len] = '/'; strcpy (concat_name + p_len + 1, wrapper); } if (check_executable (concat_name)) return concat_name; XFREE (concat_name); } } /* not found in PATH; assume curdir */ } /* Relative path | not found in path: prepend cwd */ if (getcwd (tmp, LT_PATHMAX) == NULL) lt_fatal ("getcwd failed"); tmp_len = strlen (tmp); concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1); memcpy (concat_name, tmp, tmp_len); concat_name[tmp_len] = '/'; strcpy (concat_name + tmp_len + 1, wrapper); if (check_executable (concat_name)) return concat_name; XFREE (concat_name); return NULL; } char * chase_symlinks (const char *pathspec) { #ifndef S_ISLNK return xstrdup (pathspec); #else char buf[LT_PATHMAX]; struct stat s; char *tmp_pathspec = xstrdup (pathspec); char *p; int has_symlinks = 0; while (strlen (tmp_pathspec) && !has_symlinks) { LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n", tmp_pathspec)); if (lstat (tmp_pathspec, &s) == 0) { if (S_ISLNK (s.st_mode) != 0) { has_symlinks = 1; break; } /* search backwards for last DIR_SEPARATOR */ p = tmp_pathspec + strlen (tmp_pathspec) - 1; while ((p > tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) p--; if ((p == tmp_pathspec) && (!IS_DIR_SEPARATOR (*p))) { /* no more DIR_SEPARATORS left */ break; } *p = '\0'; } else { char *errstr = strerror (errno); lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr); } } XFREE (tmp_pathspec); if (!has_symlinks) { return xstrdup (pathspec); } tmp_pathspec = realpath (pathspec, buf); if (tmp_pathspec == 0) { lt_fatal ("Could not follow symlinks for %s", pathspec); } return xstrdup (tmp_pathspec); #endif } char * strendzap (char *str, const char *pat) { size_t len, patlen; assert (str != NULL); assert (pat != NULL); len = strlen (str); patlen = strlen (pat); if (patlen <= len) { str += len - patlen; if (strcmp (str, pat) == 0) *str = '\0'; } return str; } static void lt_error_core (int exit_status, const char *mode, const char *message, va_list ap) { fprintf (stderr, "%s: %s: ", program_name, mode); vfprintf (stderr, message, ap); fprintf (stderr, ".\n"); if (exit_status >= 0) exit (exit_status); } void lt_fatal (const char *message, ...) { va_list ap; va_start (ap, message); lt_error_core (EXIT_FAILURE, "FATAL", message, ap); va_end (ap); } void lt_setenv (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n", (name ? name : ""), (value ? value : ""))); { #ifdef HAVE_SETENV /* always make a copy, for consistency with !HAVE_SETENV */ char *str = xstrdup (value); setenv (name, str, 1); #else int len = strlen (name) + 1 + strlen (value) + 1; char *str = XMALLOC (char, len); sprintf (str, "%s=%s", name, value); if (putenv (str) != EXIT_SUCCESS) { XFREE (str); } #endif } } char * lt_extend_str (const char *orig_value, const char *add, int to_end) { char *new_value; if (orig_value && *orig_value) { int orig_value_len = strlen (orig_value); int add_len = strlen (add); new_value = XMALLOC (char, add_len + orig_value_len + 1); if (to_end) { strcpy (new_value, orig_value); strcpy (new_value + orig_value_len, add); } else { strcpy (new_value, add); strcpy (new_value + add_len, orig_value); } } else { new_value = xstrdup (add); } return new_value; } int lt_split_name_value (const char *arg, char** name, char** value) { const char *p; int len; if (!arg || !*arg) return 1; p = strchr (arg, (int)'='); if (!p) return 1; *value = xstrdup (++p); len = strlen (arg) - strlen (*value); *name = XMALLOC (char, len); strncpy (*name, arg, len-1); (*name)[len - 1] = '\0'; return 0; } void lt_opt_process_env_set (const char *arg) { char *name = NULL; char *value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg); } lt_setenv (name, value); XFREE (name); XFREE (value); } void lt_opt_process_env_prepend (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg); } new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_opt_process_env_append (const char *arg) { char *name = NULL; char *value = NULL; char *new_value = NULL; if (lt_split_name_value (arg, &name, &value) != 0) { XFREE (name); XFREE (value); lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg); } new_value = lt_extend_str (getenv (name), value, 1); lt_setenv (name, new_value); XFREE (new_value); XFREE (name); XFREE (value); } void lt_update_exe_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); /* some systems can't cope with a ':'-terminated path #' */ int len = strlen (new_value); while (((len = strlen (new_value)) > 0) && IS_PATH_SEPARATOR (new_value[len-1])) { new_value[len-1] = '\0'; } lt_setenv (name, new_value); XFREE (new_value); } } void lt_update_lib_path (const char *name, const char *value) { LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n", (name ? name : ""), (value ? value : ""))); if (name && *name && value && *value) { char *new_value = lt_extend_str (getenv (name), value, 0); lt_setenv (name, new_value); XFREE (new_value); } } EOF } # end: func_emit_cwrapperexe_src # func_mode_link arg... func_mode_link () { $opt_debug case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # which system we are compiling for in order to pass an extra # flag for every libtool invocation. # allow_undefined=no # FIXME: Unfortunately, there are problems with the above when trying # to make a dll which has undefined symbols, in which case not # even a static library is built. For now, we need to specify # -no-undefined on the libtool link line when we can be certain # that all symbols are satisfied, otherwise we get a static library. allow_undefined=yes ;; *) allow_undefined=yes ;; esac libtool_args=$nonopt base_compile="$nonopt $@" compile_command=$nonopt finalize_command=$nonopt compile_rpath= finalize_rpath= compile_shlibpath= finalize_shlibpath= convenience= old_convenience= deplibs= old_deplibs= compiler_flags= linker_flags= dllsearchpath= lib_search_path=`pwd` inst_prefix_dir= new_inherited_linker_flags= avoid_version=no dlfiles= dlprefiles= dlself=no export_dynamic=no export_symbols= export_symbols_regex= generated= libobjs= ltlibs= module=no no_install=no objs= non_pic_objects= precious_files_regex= prefer_static_libs=no preload=no prev= prevarg= release= rpath= xrpath= perm_rpath= temp_rpath= thread_safe=no vinfo= vinfo_number=no weak_libs= single_module="${wl}-single_module" func_infer_tag $base_compile # We need to know -static, to get the right output filenames. for arg do case $arg in -shared) test "$build_libtool_libs" != yes && \ func_fatal_configuration "can not build a shared library" build_old_libs=no break ;; -all-static | -static | -static-libtool-libs) case $arg in -all-static) if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then func_warning "complete static linking is impossible in this configuration" fi if test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; -static) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=built ;; -static-libtool-libs) if test -z "$pic_flag" && test -n "$link_static_flag"; then dlopen_self=$dlopen_self_static fi prefer_static_libs=yes ;; esac build_libtool_libs=no build_old_libs=yes break ;; esac done # See if our shared archives depend on static archives. test -n "$old_archive_from_new_cmds" && build_old_libs=yes # Go through the arguments, transforming them on the way. while test "$#" -gt 0; do arg="$1" shift func_quote_for_eval "$arg" qarg=$func_quote_for_eval_unquoted_result func_append libtool_args " $func_quote_for_eval_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then case $prev in output) func_append compile_command " @OUTPUT@" func_append finalize_command " @OUTPUT@" ;; esac case $prev in dlfiles|dlprefiles) if test "$preload" = no; then # Add the symbol object into the linking commands. func_append compile_command " @SYMFILE@" func_append finalize_command " @SYMFILE@" preload=yes fi case $arg in *.la | *.lo) ;; # We handle these cases below. force) if test "$dlself" = no; then dlself=needless export_dynamic=yes fi prev= continue ;; self) if test "$prev" = dlprefiles; then dlself=yes elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then dlself=yes else dlself=needless export_dynamic=yes fi prev= continue ;; *) if test "$prev" = dlfiles; then dlfiles="$dlfiles $arg" else dlprefiles="$dlprefiles $arg" fi prev= continue ;; esac ;; expsyms) export_symbols="$arg" test -f "$arg" \ || func_fatal_error "symbol file \`$arg' does not exist" prev= continue ;; expsyms_regex) export_symbols_regex="$arg" prev= continue ;; framework) case $host in *-*-darwin*) case "$deplibs " in *" $qarg.ltframework "*) ;; *) deplibs="$deplibs $qarg.ltframework" # this is fixed later ;; esac ;; esac prev= continue ;; inst_prefix) inst_prefix_dir="$arg" prev= continue ;; objectlist) if test -f "$arg"; then save_arg=$arg moreargs= for fil in `cat "$save_arg"` do # moreargs="$moreargs $fil" arg=$fil # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi done else func_fatal_error "link input file \`$arg' does not exist" fi arg=$save_arg prev= continue ;; precious_regex) precious_files_regex="$arg" prev= continue ;; release) release="-$arg" prev= continue ;; rpath | xrpath) # We need an absolute path. case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac if test "$prev" = rpath; then case "$rpath " in *" $arg "*) ;; *) rpath="$rpath $arg" ;; esac else case "$xrpath " in *" $arg "*) ;; *) xrpath="$xrpath $arg" ;; esac fi prev= continue ;; shrext) shrext_cmds="$arg" prev= continue ;; weak) weak_libs="$weak_libs $arg" prev= continue ;; xcclinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xcompiler) compiler_flags="$compiler_flags $qarg" prev= func_append compile_command " $qarg" func_append finalize_command " $qarg" continue ;; xlinker) linker_flags="$linker_flags $qarg" compiler_flags="$compiler_flags $wl$qarg" prev= func_append compile_command " $wl$qarg" func_append finalize_command " $wl$qarg" continue ;; *) eval "$prev=\"\$arg\"" prev= continue ;; esac fi # test -n "$prev" prevarg="$arg" case $arg in -all-static) if test -n "$link_static_flag"; then # See comment for -static flag below, for more details. func_append compile_command " $link_static_flag" func_append finalize_command " $link_static_flag" fi continue ;; -allow-undefined) # FIXME: remove this flag sometime in the future. func_fatal_error "\`-allow-undefined' must not be used because it is the default" ;; -avoid-version) avoid_version=yes continue ;; -dlopen) prev=dlfiles continue ;; -dlpreopen) prev=dlprefiles continue ;; -export-dynamic) export_dynamic=yes continue ;; -export-symbols | -export-symbols-regex) if test -n "$export_symbols" || test -n "$export_symbols_regex"; then func_fatal_error "more than one -exported-symbols argument is not allowed" fi if test "X$arg" = "X-export-symbols"; then prev=expsyms else prev=expsyms_regex fi continue ;; -framework) prev=framework continue ;; -inst-prefix-dir) prev=inst_prefix continue ;; # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* # so, if we see these flags be careful not to treat them like -L -L[A-Z][A-Z]*:*) case $with_gcc/$host in no/*-*-irix* | /*-*-irix*) func_append compile_command " $arg" func_append finalize_command " $arg" ;; esac continue ;; -L*) func_stripname '-L' '' "$arg" dir=$func_stripname_result if test -z "$dir"; then if test "$#" -gt 0; then func_fatal_error "require no space between \`-L' and \`$1'" else func_fatal_error "need path for \`-L' option" fi fi # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) absdir=`cd "$dir" && pwd` test -z "$absdir" && \ func_fatal_error "cannot determine absolute directory name of \`$dir'" dir="$absdir" ;; esac case "$deplibs " in *" -L$dir "*) ;; *) deplibs="$deplibs -L$dir" lib_search_path="$lib_search_path $dir" ;; esac case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; ::) dllsearchpath=$dir;; *) dllsearchpath="$dllsearchpath:$dir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac continue ;; -l*) if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*) # These systems don't actually have a C or math library (as such) continue ;; *-*-os2*) # These systems don't actually have a C library (as such) test "X$arg" = "X-lc" && continue ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. test "X$arg" = "X-lc" && continue ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C and math libraries are in the System framework deplibs="$deplibs System.ltframework" continue ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype test "X$arg" = "X-lc" && continue ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work test "X$arg" = "X-lc" && continue ;; esac elif test "X$arg" = "X-lc_r"; then case $host in *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc_r directly, use -pthread flag. continue ;; esac fi deplibs="$deplibs $arg" continue ;; -module) module=yes continue ;; # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. -model|-arch|-isysroot) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" prev=xcompiler continue ;; -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) compiler_flags="$compiler_flags $arg" func_append compile_command " $arg" func_append finalize_command " $arg" case "$new_inherited_linker_flags " in *" $arg "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;; esac continue ;; -multi_module) single_module="${wl}-multi_module" continue ;; -no-fast-install) fast_install=no continue ;; -no-install) case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-darwin* | *-cegcc*) # The PATH hackery in wrapper scripts is required on Windows # and Darwin in order for the loader to find any dlls it needs. func_warning "\`-no-install' is ignored for $host" func_warning "assuming \`-no-fast-install' instead" fast_install=no ;; *) no_install=yes ;; esac continue ;; -no-undefined) allow_undefined=no continue ;; -objectlist) prev=objectlist continue ;; -o) prev=output ;; -precious-files-regex) prev=precious_regex continue ;; -release) prev=release continue ;; -rpath) prev=rpath continue ;; -R) prev=xrpath continue ;; -R*) func_stripname '-R' '' "$arg" dir=$func_stripname_result # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) ;; *) func_fatal_error "only absolute run-paths are allowed" ;; esac case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac continue ;; -shared) # The effects of -shared are defined in a previous loop. continue ;; -shrext) prev=shrext continue ;; -static | -static-libtool-libs) # The effects of -static are defined in a previous loop. # We used to do the same as -all-static on platforms that # didn't have a PIC flag, but the assumption that the effects # would be equivalent was wrong. It would break on at least # Digital Unix and AIX. continue ;; -thread-safe) thread_safe=yes continue ;; -version-info) prev=vinfo continue ;; -version-number) prev=vinfo vinfo_number=yes continue ;; -weak) prev=weak continue ;; -Wc,*) func_stripname '-Wc,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Wl,*) func_stripname '-Wl,' '' "$arg" args=$func_stripname_result arg= save_ifs="$IFS"; IFS=',' for flag in $args; do IFS="$save_ifs" func_quote_for_eval "$flag" arg="$arg $wl$func_quote_for_eval_result" compiler_flags="$compiler_flags $wl$func_quote_for_eval_result" linker_flags="$linker_flags $func_quote_for_eval_result" done IFS="$save_ifs" func_stripname ' ' '' "$arg" arg=$func_stripname_result ;; -Xcompiler) prev=xcompiler continue ;; -Xlinker) prev=xlinker continue ;; -XCClinker) prev=xcclinker continue ;; # -msg_* for osf cc -msg_*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; # -64, -mips[0-9] enable 64-bit mode on the SGI compiler # -r[0-9][0-9]* specifies the processor on the SGI compiler # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler # +DA*, +DD* enable 64-bit mode on the HP compiler # -q* pass through compiler args for the IBM compiler # -m*, -t[45]*, -txscale* pass through architecture-specific # compiler args for GCC # -F/path gives path to uninstalled frameworks, gcc on darwin # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC # @file GCC response files -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" func_append compile_command " $arg" func_append finalize_command " $arg" compiler_flags="$compiler_flags $arg" continue ;; # Some other compiler flag. -* | +*) func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; *.$objext) # A standard object. objs="$objs $arg" ;; *.lo) # A libtool-controlled object. # Check to see that this really is a libtool object. if func_lalib_unsafe_p "$arg"; then pic_object= non_pic_object= # Read the .lo file func_source "$arg" if test -z "$pic_object" || test -z "$non_pic_object" || test "$pic_object" = none && test "$non_pic_object" = none; then func_fatal_error "cannot find name of object for \`$arg'" fi # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" if test "$pic_object" != none; then # Prepend the subdirectory the object is found in. pic_object="$xdir$pic_object" if test "$prev" = dlfiles; then if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then dlfiles="$dlfiles $pic_object" prev= continue else # If libtool objects are unsupported, then we need to preload. prev=dlprefiles fi fi # CHECK ME: I think I busted this. -Ossama if test "$prev" = dlprefiles; then # Preload the old-style object. dlprefiles="$dlprefiles $pic_object" prev= fi # A PIC object. func_append libobjs " $pic_object" arg="$pic_object" fi # Non-PIC object. if test "$non_pic_object" != none; then # Prepend the subdirectory the object is found in. non_pic_object="$xdir$non_pic_object" # A standard non-PIC object func_append non_pic_objects " $non_pic_object" if test -z "$pic_object" || test "$pic_object" = none ; then arg="$non_pic_object" fi else # If the PIC object exists, use it instead. # $xdir was prepended to $pic_object above. non_pic_object="$pic_object" func_append non_pic_objects " $non_pic_object" fi else # Only an error if not doing a dry-run. if $opt_dry_run; then # Extract subdirectory from the argument. func_dirname "$arg" "/" "" xdir="$func_dirname_result" func_lo2o "$arg" pic_object=$xdir$objdir/$func_lo2o_result non_pic_object=$xdir$func_lo2o_result func_append libobjs " $pic_object" func_append non_pic_objects " $non_pic_object" else func_fatal_error "\`$arg' is not a valid libtool object" fi fi ;; *.$libext) # An archive. deplibs="$deplibs $arg" old_deplibs="$old_deplibs $arg" continue ;; *.la) # A libtool-controlled library. if test "$prev" = dlfiles; then # This library was specified with -dlopen. dlfiles="$dlfiles $arg" prev= elif test "$prev" = dlprefiles; then # The library was specified with -dlpreopen. dlprefiles="$dlprefiles $arg" prev= else deplibs="$deplibs $arg" fi continue ;; # Some other compiler argument. *) # Unknown arguments in both finalize_command and compile_command need # to be aesthetically quoted because they are evaled later. func_quote_for_eval "$arg" arg="$func_quote_for_eval_result" ;; esac # arg # Now actually substitute the argument into the commands. if test -n "$arg"; then func_append compile_command " $arg" func_append finalize_command " $arg" fi done # argument parsing loop test -n "$prev" && \ func_fatal_help "the \`$prevarg' option requires an argument" if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then eval arg=\"$export_dynamic_flag_spec\" func_append compile_command " $arg" func_append finalize_command " $arg" fi oldlibs= # calculate the name of the file, without its directory func_basename "$output" outputname="$func_basename_result" libobjs_save="$libobjs" if test -n "$shlibpath_var"; then # get the directories listed in $shlibpath_var eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` else shlib_search_path= fi eval sys_lib_search_path=\"$sys_lib_search_path_spec\" eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" func_dirname "$output" "/" "" output_objdir="$func_dirname_result$objdir" # Create the object directory. func_mkdir_p "$output_objdir" # Determine the type of output case $output in "") func_fatal_help "you must specify an output file" ;; *.$libext) linkmode=oldlib ;; *.lo | *.$objext) linkmode=obj ;; *.la) linkmode=lib ;; *) linkmode=prog ;; # Anything else should be a program. esac specialdeplibs= libs= # Find all interdependent deplibs by searching for libraries # that are linked more than once (e.g. -la -lb -la) for deplib in $deplibs; do if $opt_duplicate_deps ; then case "$libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi libs="$libs $deplib" done if test "$linkmode" = lib; then libs="$predeps $libs $compiler_lib_search_path $postdeps" # Compute libraries that are listed more than once in $predeps # $postdeps and mark them as special (i.e., whose duplicates are # not to be eliminated). pre_post_deps= if $opt_duplicate_compiler_generated_deps; then for pre_post_dep in $predeps $postdeps; do case "$pre_post_deps " in *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;; esac pre_post_deps="$pre_post_deps $pre_post_dep" done fi pre_post_deps= fi deplibs= newdependency_libs= newlib_search_path= need_relink=no # whether we're linking any uninstalled libtool libraries notinst_deplibs= # not-installed libtool libraries notinst_path= # paths that contain not-installed libtool libraries case $linkmode in lib) passes="conv dlpreopen link" for file in $dlfiles $dlprefiles; do case $file in *.la) ;; *) func_fatal_help "libraries can \`-dlopen' only libtool libraries: $file" ;; esac done ;; prog) compile_deplibs= finalize_deplibs= alldeplibs=no newdlfiles= newdlprefiles= passes="conv scan dlopen dlpreopen link" ;; *) passes="conv" ;; esac for pass in $passes; do # The preopen pass in lib mode reverses $deplibs; put it back here # so that -L comes before libs that need it for instance... if test "$linkmode,$pass" = "lib,link"; then ## FIXME: Find the place where the list is rebuilt in the wrong ## order, and fix it there properly tmp_deplibs= for deplib in $deplibs; do tmp_deplibs="$deplib $tmp_deplibs" done deplibs="$tmp_deplibs" fi if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan"; then libs="$deplibs" deplibs= fi if test "$linkmode" = prog; then case $pass in dlopen) libs="$dlfiles" ;; dlpreopen) libs="$dlprefiles" ;; link) libs="$deplibs %DEPLIBS%" test "X$link_all_deplibs" != Xno && libs="$libs $dependency_libs" ;; esac fi if test "$linkmode,$pass" = "lib,dlpreopen"; then # Collect and forward deplibs of preopened libtool libs for lib in $dlprefiles; do # Ignore non-libtool-libs dependency_libs= case $lib in *.la) func_source "$lib" ;; esac # Collect preopened libtool deplibs, except any this library # has declared as weak libs for deplib in $dependency_libs; do deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"` case " $weak_libs " in *" $deplib_base "*) ;; *) deplibs="$deplibs $deplib" ;; esac done done libs="$dlprefiles" fi if test "$pass" = dlopen; then # Collect dlpreopened libraries save_deplibs="$deplibs" deplibs= fi for deplib in $libs; do lib= found=no case $deplib in -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else compiler_flags="$compiler_flags $deplib" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -l*) if test "$linkmode" != lib && test "$linkmode" != prog; then func_warning "\`-l' is ignored for archives/objects" continue fi func_stripname '-l' '' "$deplib" name=$func_stripname_result if test "$linkmode" = lib; then searchdirs="$newlib_search_path $lib_search_path $compiler_lib_search_dirs $sys_lib_search_path $shlib_search_path" else searchdirs="$newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path" fi for searchdir in $searchdirs; do for search_ext in .la $std_shrext .so .a; do # Search the libtool library lib="$searchdir/lib${name}${search_ext}" if test -f "$lib"; then if test "$search_ext" = ".la"; then found=yes else found=no fi break 2 fi done done if test "$found" != yes; then # deplib doesn't seem to be a libtool library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue else # deplib is a libtool library # If $allow_libtool_libs_with_static_runtimes && $deplib is a stdlib, # We need to do some special things here, and not later. if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $deplib "*) if func_lalib_p "$lib"; then library_names= old_library= func_source "$lib" for l in $old_library $library_names; do ll="$l" done if test "X$ll" = "X$old_library" ; then # only static version available found=no func_dirname "$lib" "" "." ladir="$func_dirname_result" lib=$ladir/$old_library if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" test "$linkmode" = lib && newdependency_libs="$deplib $newdependency_libs" fi continue fi fi ;; *) ;; esac fi fi ;; # -l *.ltframework) if test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else deplibs="$deplib $deplibs" if test "$linkmode" = lib ; then case "$new_inherited_linker_flags " in *" $deplib "*) ;; * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;; esac fi fi continue ;; -L*) case $linkmode in lib) deplibs="$deplib $deplibs" test "$pass" = conv && continue newdependency_libs="$deplib $newdependency_libs" func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; prog) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi if test "$pass" = scan; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; *) func_warning "\`-L' is ignored for archives/objects" ;; esac # linkmode continue ;; # -L -R*) if test "$pass" = link; then func_stripname '-R' '' "$deplib" dir=$func_stripname_result # Make sure the xrpath contains only unique directories. case "$xrpath " in *" $dir "*) ;; *) xrpath="$xrpath $dir" ;; esac fi deplibs="$deplib $deplibs" continue ;; *.la) lib="$deplib" ;; *.$libext) if test "$pass" = conv; then deplibs="$deplib $deplibs" continue fi case $linkmode in lib) # Linking convenience modules into shared libraries is allowed, # but linking other static libraries is non-portable. case " $dlpreconveniencelibs " in *" $deplib "*) ;; *) valid_a_lib=no case $deplibs_check_method in match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \ | $EGREP "$match_pattern_regex" > /dev/null; then valid_a_lib=yes fi ;; pass_all) valid_a_lib=yes ;; esac if test "$valid_a_lib" != yes; then $ECHO $ECHO "*** Warning: Trying to link with static lib archive $deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because the file extensions .$libext of this argument makes me believe" $ECHO "*** that it is just a static archive that I should not use here." else $ECHO $ECHO "*** Warning: Linking the shared library $output against the" $ECHO "*** static library $deplib is not portable!" deplibs="$deplib $deplibs" fi ;; esac continue ;; prog) if test "$pass" != link; then deplibs="$deplib $deplibs" else compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" fi continue ;; esac # linkmode ;; # *.$libext *.lo | *.$objext) if test "$pass" = conv; then deplibs="$deplib $deplibs" elif test "$linkmode" = prog; then if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlopen support or we're linking statically, # we need to preload. newdlprefiles="$newdlprefiles $deplib" compile_deplibs="$deplib $compile_deplibs" finalize_deplibs="$deplib $finalize_deplibs" else newdlfiles="$newdlfiles $deplib" fi fi continue ;; %DEPLIBS%) alldeplibs=yes continue ;; esac # case $deplib if test "$found" = yes || test -f "$lib"; then : else func_fatal_error "cannot find the library \`$lib' or unhandled argument \`$deplib'" fi # Check to see that this really is a libtool archive. func_lalib_unsafe_p "$lib" \ || func_fatal_error "\`$lib' is not a valid libtool archive" func_dirname "$lib" "" "." ladir="$func_dirname_result" dlname= dlopen= dlpreopen= libdir= library_names= old_library= inherited_linker_flags= # If the library was installed with an old release of libtool, # it will not redefine variables installed, or shouldnotlink installed=yes shouldnotlink=no avoidtemprpath= # Read the .la file func_source "$lib" # Convert "-framework foo" to "foo.ltframework" if test -n "$inherited_linker_flags"; then tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'` for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do case " $new_inherited_linker_flags " in *" $tmp_inherited_linker_flag "*) ;; *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";; esac done fi dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` if test "$linkmode,$pass" = "lib,link" || test "$linkmode,$pass" = "prog,scan" || { test "$linkmode" != prog && test "$linkmode" != lib; }; then test -n "$dlopen" && dlfiles="$dlfiles $dlopen" test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" fi if test "$pass" = conv; then # Only check for convenience libraries deplibs="$lib $deplibs" if test -z "$libdir"; then if test -z "$old_library"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # It is a libtool convenience library, so add in its objects. convenience="$convenience $ladir/$objdir/$old_library" old_convenience="$old_convenience $ladir/$objdir/$old_library" tmp_libs= for deplib in $dependency_libs; do deplibs="$deplib $deplibs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done elif test "$linkmode" != prog && test "$linkmode" != lib; then func_fatal_error "\`$lib' is not a convenience library" fi continue fi # $pass = conv # Get the name of the library we link against. linklib= for l in $old_library $library_names; do linklib="$l" done if test -z "$linklib"; then func_fatal_error "cannot find name of link library for \`$lib'" fi # This library was specified with -dlopen. if test "$pass" = dlopen; then if test -z "$libdir"; then func_fatal_error "cannot -dlopen a convenience library: \`$lib'" fi if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then # If there is no dlname, no dlopen support or we're linking # statically, we need to preload. We also need to preload any # dependent libraries so libltdl's deplib preloader doesn't # bomb out in the load deplibs phase. dlprefiles="$dlprefiles $lib $dependency_libs" else newdlfiles="$newdlfiles $lib" fi continue fi # $pass = dlopen # We need an absolute path. case $ladir in [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; *) abs_ladir=`cd "$ladir" && pwd` if test -z "$abs_ladir"; then func_warning "cannot determine absolute directory name of \`$ladir'" func_warning "passing it literally to the linker, although it might fail" abs_ladir="$ladir" fi ;; esac func_basename "$lib" laname="$func_basename_result" # Find the relevant object directory and library name. if test "X$installed" = Xyes; then if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then func_warning "library \`$lib' was moved." dir="$ladir" absdir="$abs_ladir" libdir="$abs_ladir" else dir="$libdir" absdir="$libdir" fi test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes else if test ! -f "$ladir/$objdir/$linklib" && test -f "$abs_ladir/$linklib"; then dir="$ladir" absdir="$abs_ladir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" else dir="$ladir/$objdir" absdir="$abs_ladir/$objdir" # Remove this search path later notinst_path="$notinst_path $abs_ladir" fi fi # $installed = yes func_stripname 'lib' '.la' "$laname" name=$func_stripname_result # This library was specified with -dlpreopen. if test "$pass" = dlpreopen; then if test -z "$libdir" && test "$linkmode" = prog; then func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'" fi # Prefer using a static library (so that no silly _DYNAMIC symbols # are required to link). if test -n "$old_library"; then newdlprefiles="$newdlprefiles $dir/$old_library" # Keep a list of preopened convenience libraries to check # that they are being used correctly in the link pass. test -z "$libdir" && \ dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library" # Otherwise, use the dlname, so that lt_dlopen finds it. elif test -n "$dlname"; then newdlprefiles="$newdlprefiles $dir/$dlname" else newdlprefiles="$newdlprefiles $dir/$linklib" fi fi # $pass = dlpreopen if test -z "$libdir"; then # Link the convenience library if test "$linkmode" = lib; then deplibs="$dir/$old_library $deplibs" elif test "$linkmode,$pass" = "prog,link"; then compile_deplibs="$dir/$old_library $compile_deplibs" finalize_deplibs="$dir/$old_library $finalize_deplibs" else deplibs="$lib $deplibs" # used for prog,scan pass fi continue fi if test "$linkmode" = prog && test "$pass" != link; then newlib_search_path="$newlib_search_path $ladir" deplibs="$lib $deplibs" linkalldeplibs=no if test "$link_all_deplibs" != no || test -z "$library_names" || test "$build_libtool_libs" = no; then linkalldeplibs=yes fi tmp_libs= for deplib in $dependency_libs; do case $deplib in -L*) func_stripname '-L' '' "$deplib" newlib_search_path="$newlib_search_path $func_stripname_result" ;; esac # Need to link against all dependency_libs? if test "$linkalldeplibs" = yes; then deplibs="$deplib $deplibs" else # Need to hardcode shared library paths # or/and link against static libraries newdependency_libs="$deplib $newdependency_libs" fi if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done # for deplib continue fi # $linkmode = prog... if test "$linkmode,$pass" = "prog,link"; then if test -n "$library_names" && { { test "$prefer_static_libs" = no || test "$prefer_static_libs,$installed" = "built,yes"; } || test -z "$old_library"; }; then # We need to hardcode the library path if test -n "$shlibpath_var" && test -z "$avoidtemprpath" ; then # Make sure the rpath contains only unique directories. case "$temp_rpath:" in *"$absdir:"*) ;; *) temp_rpath="$temp_rpath$absdir:" ;; esac fi # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi # $linkmode,$pass = prog,link... if test "$alldeplibs" = yes && { test "$deplibs_check_method" = pass_all || { test "$build_libtool_libs" = yes && test -n "$library_names"; }; }; then # We only need to search for static libraries continue fi fi link_static=no # Whether the deplib will be linked statically use_static_libs=$prefer_static_libs if test "$use_static_libs" = built && test "$installed" = yes; then use_static_libs=no fi if test -n "$library_names" && { test "$use_static_libs" = no || test -z "$old_library"; }; then case $host in *cygwin* | *mingw* | *cegcc*) # No point in relinking DLLs because paths are not encoded notinst_deplibs="$notinst_deplibs $lib" need_relink=no ;; *) if test "$installed" = no; then notinst_deplibs="$notinst_deplibs $lib" need_relink=yes fi ;; esac # This is a shared library # Warn about portability, can't link against -module's on some # systems (darwin). Don't bleat about dlopened modules though! dlopenmodule="" for dlpremoduletest in $dlprefiles; do if test "X$dlpremoduletest" = "X$lib"; then dlopenmodule="$dlpremoduletest" break fi done if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then $ECHO if test "$linkmode" = prog; then $ECHO "*** Warning: Linking the executable $output against the loadable module" else $ECHO "*** Warning: Linking the shared library $output against the loadable module" fi $ECHO "*** $linklib is not portable!" fi if test "$linkmode" = lib && test "$hardcode_into_libs" = yes; then # Hardcode the library path. # Skip directories that are in the system default run-time # search path. case " $sys_lib_dlsearch_path " in *" $absdir "*) ;; *) case "$compile_rpath " in *" $absdir "*) ;; *) compile_rpath="$compile_rpath $absdir" esac ;; esac case " $sys_lib_dlsearch_path " in *" $libdir "*) ;; *) case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" esac ;; esac fi if test -n "$old_archive_from_expsyms_cmds"; then # figure out the soname set dummy $library_names shift realname="$1" shift libname=`eval "\\$ECHO \"$libname_spec\""` # use dlname if we got it. it's perfectly good, no? if test -n "$dlname"; then soname="$dlname" elif test -n "$soname_spec"; then # bleh windows case $host in *cygwin* | mingw* | *cegcc*) func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; esac eval soname=\"$soname_spec\" else soname="$realname" fi # Make a new name for the extract_expsyms_cmds to use soroot="$soname" func_basename "$soroot" soname="$func_basename_result" func_stripname 'lib' '.dll' "$soname" newlib=libimp-$func_stripname_result.a # If the library has no export list, then create one now if test -f "$output_objdir/$soname-def"; then : else func_verbose "extracting exported symbol list from \`$soname'" func_execute_cmds "$extract_expsyms_cmds" 'exit $?' fi # Create $newlib if test -f "$output_objdir/$newlib"; then :; else func_verbose "generating import library for \`$soname'" func_execute_cmds "$old_archive_from_expsyms_cmds" 'exit $?' fi # make sure the library variables are pointing to the new library dir=$output_objdir linklib=$newlib fi # test -n "$old_archive_from_expsyms_cmds" if test "$linkmode" = prog || test "$mode" != relink; then add_shlibpath= add_dir= add= lib_linked=yes case $hardcode_action in immediate | unsupported) if test "$hardcode_direct" = no; then add="$dir/$linklib" case $host in *-*-sco3.2v5.0.[024]*) add_dir="-L$dir" ;; *-*-sysv4*uw2*) add_dir="-L$dir" ;; *-*-sysv5OpenUNIX* | *-*-sysv5UnixWare7.[01].[10]* | \ *-*-unixware7*) add_dir="-L$dir" ;; *-*-darwin* ) # if the lib is a (non-dlopened) module then we can not # link against it, someone is ignoring the earlier warnings if /usr/bin/file -L $add 2> /dev/null | $GREP ": [^:]* bundle" >/dev/null ; then if test "X$dlopenmodule" != "X$lib"; then $ECHO "*** Warning: lib $linklib is a module, not a shared library" if test -z "$old_library" ; then $ECHO $ECHO "*** And there doesn't seem to be a static archive available" $ECHO "*** The link will probably fail, sorry" else add="$dir/$old_library" fi elif test -n "$old_library"; then add="$dir/$old_library" fi fi esac elif test "$hardcode_minus_L" = no; then case $host in *-*-sunos*) add_shlibpath="$dir" ;; esac add_dir="-L$dir" add="-l$name" elif test "$hardcode_shlibpath_var" = no; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; relink) if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$dir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$dir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then add_shlibpath="$dir" add="-l$name" else lib_linked=no fi ;; *) lib_linked=no ;; esac if test "$lib_linked" != yes; then func_fatal_configuration "unsupported hardcode properties" fi if test -n "$add_shlibpath"; then case :$compile_shlibpath: in *":$add_shlibpath:"*) ;; *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; esac fi if test "$linkmode" = prog; then test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" test -n "$add" && compile_deplibs="$add $compile_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" if test "$hardcode_direct" != yes && test "$hardcode_minus_L" != yes && test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac fi fi fi if test "$linkmode" = prog || test "$mode" = relink; then add_shlibpath= add_dir= add= # Finalize command for both is simple: just hardcode it. if test "$hardcode_direct" = yes && test "$hardcode_direct_absolute" = no; then add="$libdir/$linklib" elif test "$hardcode_minus_L" = yes; then add_dir="-L$libdir" add="-l$name" elif test "$hardcode_shlibpath_var" = yes; then case :$finalize_shlibpath: in *":$libdir:"*) ;; *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; esac add="-l$name" elif test "$hardcode_automatic" = yes; then if test -n "$inst_prefix_dir" && test -f "$inst_prefix_dir$libdir/$linklib" ; then add="$inst_prefix_dir$libdir/$linklib" else add="$libdir/$linklib" fi else # We cannot seem to hardcode it, guess we'll fake it. add_dir="-L$libdir" # Try looking first in the location we're being installed to. if test -n "$inst_prefix_dir"; then case $libdir in [\\/]*) add_dir="$add_dir -L$inst_prefix_dir$libdir" ;; esac fi add="-l$name" fi if test "$linkmode" = prog; then test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" test -n "$add" && finalize_deplibs="$add $finalize_deplibs" else test -n "$add_dir" && deplibs="$add_dir $deplibs" test -n "$add" && deplibs="$add $deplibs" fi fi elif test "$linkmode" = prog; then # Here we assume that one of hardcode_direct or hardcode_minus_L # is not unsupported. This is valid on all known static and # shared platforms. if test "$hardcode_direct" != unsupported; then test -n "$old_library" && linklib="$old_library" compile_deplibs="$dir/$linklib $compile_deplibs" finalize_deplibs="$dir/$linklib $finalize_deplibs" else compile_deplibs="-l$name -L$dir $compile_deplibs" finalize_deplibs="-l$name -L$dir $finalize_deplibs" fi elif test "$build_libtool_libs" = yes; then # Not a shared library if test "$deplibs_check_method" != pass_all; then # We're trying link a shared library against a static one # but the system doesn't support it. # Just print a warning and add the library to dependency_libs so # that the program can be linked against the static library. $ECHO $ECHO "*** Warning: This system can not link to static lib archive $lib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have." if test "$module" = yes; then $ECHO "*** But as you try to build a module library, libtool will still create " $ECHO "*** a static module, that should work as long as the dlopening application" $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi else deplibs="$dir/$old_library $deplibs" link_static=yes fi fi # link shared/static library? if test "$linkmode" = lib; then if test -n "$dependency_libs" && { test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes || test "$link_static" = yes; }; then # Extract -R from dependency_libs temp_deplibs= for libdir in $dependency_libs; do case $libdir in -R*) func_stripname '-R' '' "$libdir" temp_xrpath=$func_stripname_result case " $xrpath " in *" $temp_xrpath "*) ;; *) xrpath="$xrpath $temp_xrpath";; esac;; *) temp_deplibs="$temp_deplibs $libdir";; esac done dependency_libs="$temp_deplibs" fi newlib_search_path="$newlib_search_path $absdir" # Link against this library test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" # ... and its dependency_libs tmp_libs= for deplib in $dependency_libs; do newdependency_libs="$deplib $newdependency_libs" if $opt_duplicate_deps ; then case "$tmp_libs " in *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; esac fi tmp_libs="$tmp_libs $deplib" done if test "$link_all_deplibs" != no; then # Add the search paths of all dependency libraries for deplib in $dependency_libs; do path= case $deplib in -L*) path="$deplib" ;; *.la) func_dirname "$deplib" "" "." dir="$func_dirname_result" # We need an absolute path. case $dir in [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; *) absdir=`cd "$dir" && pwd` if test -z "$absdir"; then func_warning "cannot determine absolute directory name of \`$dir'" absdir="$dir" fi ;; esac if $GREP "^installed=no" $deplib > /dev/null; then case $host in *-*-darwin*) depdepl= eval deplibrary_names=`${SED} -n -e 's/^library_names=\(.*\)$/\1/p' $deplib` if test -n "$deplibrary_names" ; then for tmp in $deplibrary_names ; do depdepl=$tmp done if test -f "$absdir/$objdir/$depdepl" ; then depdepl="$absdir/$objdir/$depdepl" darwin_install_name=`${OTOOL} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` if test -z "$darwin_install_name"; then darwin_install_name=`${OTOOL64} -L $depdepl | awk '{if (NR == 2) {print $1;exit}}'` fi compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}" linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}" path= fi fi ;; *) path="-L$absdir/$objdir" ;; esac else eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" test "$absdir" != "$libdir" && \ func_warning "\`$deplib' seems to be moved" path="-L$absdir" fi ;; esac case " $deplibs " in *" $path "*) ;; *) deplibs="$path $deplibs" ;; esac done fi # link_all_deplibs != no fi # linkmode = lib done # for deplib in $libs if test "$pass" = link; then if test "$linkmode" = "prog"; then compile_deplibs="$new_inherited_linker_flags $compile_deplibs" finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs" else compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` fi fi dependency_libs="$newdependency_libs" if test "$pass" = dlpreopen; then # Link the dlpreopened libraries before other libraries for deplib in $save_deplibs; do deplibs="$deplib $deplibs" done fi if test "$pass" != dlopen; then if test "$pass" != conv; then # Make sure lib_search_path contains only unique directories. lib_search_path= for dir in $newlib_search_path; do case "$lib_search_path " in *" $dir "*) ;; *) lib_search_path="$lib_search_path $dir" ;; esac done newlib_search_path= fi if test "$linkmode,$pass" != "prog,link"; then vars="deplibs" else vars="compile_deplibs finalize_deplibs" fi for var in $vars dependency_libs; do # Add libraries to $var in reverse order eval tmp_libs=\"\$$var\" new_libs= for deplib in $tmp_libs; do # FIXME: Pedantically, this is the right thing to do, so # that some nasty dependency loop isn't accidentally # broken: #new_libs="$deplib $new_libs" # Pragmatically, this seems to cause very few problems in # practice: case $deplib in -L*) new_libs="$deplib $new_libs" ;; -R*) ;; *) # And here is the reason: when a library appears more # than once as an explicit dependence of a library, or # is implicitly linked in more than once by the # compiler, it is considered special, and multiple # occurrences thereof are not removed. Compare this # with having the same library being listed as a # dependency of multiple other libraries: in this case, # we know (pedantically, we assume) the library does not # need to be listed more than once, so we keep only the # last copy. This is not always right, but it is rare # enough that we require users that really mean to play # such unportable linking tricks to link the library # using -Wl,-lname, so that libtool does not consider it # for duplicate removal. case " $specialdeplibs " in *" $deplib "*) new_libs="$deplib $new_libs" ;; *) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$deplib $new_libs" ;; esac ;; esac ;; esac done tmp_libs= for deplib in $new_libs; do case $deplib in -L*) case " $tmp_libs " in *" $deplib "*) ;; *) tmp_libs="$tmp_libs $deplib" ;; esac ;; *) tmp_libs="$tmp_libs $deplib" ;; esac done eval $var=\"$tmp_libs\" done # for var fi # Last step: remove runtime libs from dependency_libs # (they stay in deplibs) tmp_libs= for i in $dependency_libs ; do case " $predeps $postdeps $compiler_lib_search_path " in *" $i "*) i="" ;; esac if test -n "$i" ; then tmp_libs="$tmp_libs $i" fi done dependency_libs=$tmp_libs done # for pass if test "$linkmode" = prog; then dlfiles="$newdlfiles" fi if test "$linkmode" = prog || test "$linkmode" = lib; then dlprefiles="$newdlprefiles" fi case $linkmode in oldlib) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for archives" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for archives" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for archives" test -n "$xrpath" && \ func_warning "\`-R' is ignored for archives" test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for archives" test -n "$release" && \ func_warning "\`-release' is ignored for archives" test -n "$export_symbols$export_symbols_regex" && \ func_warning "\`-export-symbols' is ignored for archives" # Now set the variables for building old libraries. build_libtool_libs=no oldlibs="$output" objs="$objs$old_deplibs" ;; lib) # Make sure we only generate libraries of the form `libNAME.la'. case $outputname in lib*) func_stripname 'lib' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" ;; *) test "$module" = no && \ func_fatal_help "libtool library \`$output' must begin with \`lib'" if test "$need_lib_prefix" != no; then # Add the "lib" prefix for modules if required func_stripname '' '.la' "$outputname" name=$func_stripname_result eval shared_ext=\"$shrext_cmds\" eval libname=\"$libname_spec\" else func_stripname '' '.la' "$outputname" libname=$func_stripname_result fi ;; esac if test -n "$objs"; then if test "$deplibs_check_method" != pass_all; then func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs" else $ECHO $ECHO "*** Warning: Linking the shared library $output against the non-libtool" $ECHO "*** objects $objs is not portable!" libobjs="$libobjs $objs" fi fi test "$dlself" != no && \ func_warning "\`-dlopen self' is ignored for libtool libraries" set dummy $rpath shift test "$#" -gt 1 && \ func_warning "ignoring multiple \`-rpath's for a libtool library" install_libdir="$1" oldlibs= if test -z "$rpath"; then if test "$build_libtool_libs" = yes; then # Building a libtool convenience library. # Some compilers have problems with a `.al' extension so # convenience libraries should have the same extension an # archive normally would. oldlibs="$output_objdir/$libname.$libext $oldlibs" build_libtool_libs=convenience build_old_libs=yes fi test -n "$vinfo" && \ func_warning "\`-version-info/-version-number' is ignored for convenience libraries" test -n "$release" && \ func_warning "\`-release' is ignored for convenience libraries" else # Parse the version information argument. save_ifs="$IFS"; IFS=':' set dummy $vinfo 0 0 0 shift IFS="$save_ifs" test -n "$7" && \ func_fatal_help "too many parameters to \`-version-info'" # convert absolute version numbers to libtool ages # this retains compatibility with .la files and attempts # to make the code below a bit more comprehensible case $vinfo_number in yes) number_major="$1" number_minor="$2" number_revision="$3" # # There are really only two kinds -- those that # use the current revision as the major version # and those that subtract age and use age as # a minor version. But, then there is irix # which has an extra 1 added just for fun # case $version_type in darwin|linux|osf|windows|none) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_revision" ;; freebsd-aout|freebsd-elf|sunos) current="$number_major" revision="$number_minor" age="0" ;; irix|nonstopux) func_arith $number_major + $number_minor current=$func_arith_result age="$number_minor" revision="$number_minor" lt_irix_increment=no ;; *) func_fatal_configuration "$modename: unknown library version type \`$version_type'" ;; esac ;; no) current="$1" revision="$2" age="$3" ;; esac # Check that each of the things are valid numbers. case $current in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "CURRENT \`$current' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $revision in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "REVISION \`$revision' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac case $age in 0|[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]) ;; *) func_error "AGE \`$age' must be a nonnegative integer" func_fatal_error "\`$vinfo' is not valid version information" ;; esac if test "$age" -gt "$current"; then func_error "AGE \`$age' is greater than the current interface number \`$current'" func_fatal_error "\`$vinfo' is not valid version information" fi # Calculate the version variables. major= versuffix= verstring= case $version_type in none) ;; darwin) # Like Linux, but with the current version available in # verstring for coding it into the library header func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" # Darwin ld doesn't like 0 for these options... func_arith $current + 1 minor_current=$func_arith_result xlcverstring="${wl}-compatibility_version ${wl}$minor_current ${wl}-current_version ${wl}$minor_current.$revision" verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" ;; freebsd-aout) major=".$current" versuffix=".$current.$revision"; ;; freebsd-elf) major=".$current" versuffix=".$current" ;; irix | nonstopux) if test "X$lt_irix_increment" = "Xno"; then func_arith $current - $age else func_arith $current - $age + 1 fi major=$func_arith_result case $version_type in nonstopux) verstring_prefix=nonstopux ;; *) verstring_prefix=sgi ;; esac verstring="$verstring_prefix$major.$revision" # Add in all the interfaces that we are compatible with. loop=$revision while test "$loop" -ne 0; do func_arith $revision - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring_prefix$major.$iface:$verstring" done # Before this point, $major must not contain `.'. major=.$major versuffix="$major.$revision" ;; linux) func_arith $current - $age major=.$func_arith_result versuffix="$major.$age.$revision" ;; osf) func_arith $current - $age major=.$func_arith_result versuffix=".$current.$age.$revision" verstring="$current.$age.$revision" # Add in all the interfaces that we are compatible with. loop=$age while test "$loop" -ne 0; do func_arith $current - $loop iface=$func_arith_result func_arith $loop - 1 loop=$func_arith_result verstring="$verstring:${iface}.0" done # Make executables depend on our current version. verstring="$verstring:${current}.0" ;; qnx) major=".$current" versuffix=".$current" ;; sunos) major=".$current" versuffix=".$current.$revision" ;; windows) # Use '-' rather than '.', since we only want one # extension on DOS 8.3 filesystems. func_arith $current - $age major=$func_arith_result versuffix="-$major" ;; *) func_fatal_configuration "unknown library version type \`$version_type'" ;; esac # Clear the version info if we defaulted, and they specified a release. if test -z "$vinfo" && test -n "$release"; then major= case $version_type in darwin) # we can't check for "0.0" in archive_cmds due to quoting # problems, so we reset it completely verstring= ;; *) verstring="0.0" ;; esac if test "$need_version" = no; then versuffix= else versuffix=".0.0" fi fi # Remove version info from name if versioning should be avoided if test "$avoid_version" = yes && test "$need_version" = no; then major= versuffix= verstring="" fi # Check to see if the archive will have undefined symbols. if test "$allow_undefined" = yes; then if test "$allow_undefined_flag" = unsupported; then func_warning "undefined symbols not allowed in $host shared libraries" build_libtool_libs=no build_old_libs=yes fi else # Don't allow undefined symbols. allow_undefined_flag="$no_undefined_flag" fi fi func_generate_dlsyms "$libname" "$libname" "yes" libobjs="$libobjs $symfileobj" test "X$libobjs" = "X " && libobjs= if test "$mode" != relink; then # Remove our outputs, but don't remove object files since they # may have been created when compiling PIC objects. removelist= tempremovelist=`$ECHO "$output_objdir/*"` for p in $tempremovelist; do case $p in *.$objext | *.gcno) ;; $output_objdir/$outputname | $output_objdir/$libname.* | $output_objdir/${libname}${release}.*) if test "X$precious_files_regex" != "X"; then if $ECHO "$p" | $EGREP -e "$precious_files_regex" >/dev/null 2>&1 then continue fi fi removelist="$removelist $p" ;; *) ;; esac done test -n "$removelist" && \ func_show_eval "${RM}r \$removelist" fi # Now set the variables for building old libraries. if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then oldlibs="$oldlibs $output_objdir/$libname.$libext" # Transform .lo files to .o files. oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` fi # Eliminate all temporary directories. #for path in $notinst_path; do # lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"` # deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"` # dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"` #done if test -n "$xrpath"; then # If the user specified any rpath flags, then add them. temp_xrpath= for libdir in $xrpath; do temp_xrpath="$temp_xrpath -R$libdir" case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then dependency_libs="$temp_xrpath $dependency_libs" fi fi # Make sure dlfiles contains only unique files that won't be dlpreopened old_dlfiles="$dlfiles" dlfiles= for lib in $old_dlfiles; do case " $dlprefiles $dlfiles " in *" $lib "*) ;; *) dlfiles="$dlfiles $lib" ;; esac done # Make sure dlprefiles contains only unique files old_dlprefiles="$dlprefiles" dlprefiles= for lib in $old_dlprefiles; do case "$dlprefiles " in *" $lib "*) ;; *) dlprefiles="$dlprefiles $lib" ;; esac done if test "$build_libtool_libs" = yes; then if test -n "$rpath"; then case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*) # these systems don't actually have a c library (as such)! ;; *-*-rhapsody* | *-*-darwin1.[012]) # Rhapsody C library is in the System framework deplibs="$deplibs System.ltframework" ;; *-*-netbsd*) # Don't link with libc until the a.out ld.so is fixed. ;; *-*-openbsd* | *-*-freebsd* | *-*-dragonfly*) # Do not include libc due to us having libc/libc_r. ;; *-*-sco3.2v5* | *-*-sco5v6*) # Causes problems with __ctype ;; *-*-sysv4.2uw2* | *-*-sysv5* | *-*-unixware* | *-*-OpenUNIX*) # Compiler inserts libc in the correct place for threads to work ;; *) # Add libc to deplibs on all other systems if necessary. if test "$build_libtool_need_lc" = "yes"; then deplibs="$deplibs -lc" fi ;; esac fi # Transform deplibs into only deplibs that can be linked in shared. name_save=$name libname_save=$libname release_save=$release versuffix_save=$versuffix major_save=$major # I'm not sure if I'm treating the release correctly. I think # release should show up in the -l (ie -lgmp5) so we don't want to # add it in twice. Is that correct? release="" versuffix="" major="" newdeplibs= droppeddeps=no case $deplibs_check_method in pass_all) # Don't check for shared/static. Everything works. # This might be a little naive. We might want to check # whether the library exists or not. But this is on # osf3 & osf4 and I'm not really sure... Just # implementing what was already the behavior. newdeplibs=$deplibs ;; test_compile) # This code stresses the "libraries are programs" paradigm to its # limits. Maybe even breaks it. We compile a program, linking it # against the deplibs as a proxy for the library. Then we can check # whether they linked in statically or dynamically with ldd. $opt_dry_run || $RM conftest.c cat > conftest.c </dev/null` for potent_lib in $potential_libs; do # Follow soft links. if ls -lLd "$potent_lib" 2>/dev/null | $GREP " -> " >/dev/null; then continue fi # The statement above tries to avoid entering an # endless loop below, in case of cyclic links. # We might still enter an endless loop, since a link # loop can be closed while we follow links, # but so what? potlib="$potent_lib" while test -h "$potlib" 2>/dev/null; do potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'` case $potliblink in [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; esac done if eval $file_magic_cmd \"\$potlib\" 2>/dev/null | $SED -e 10q | $EGREP "$file_magic_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for file magic test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a file magic. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; match_pattern*) set dummy $deplibs_check_method; shift match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"` for a_deplib in $deplibs; do case $a_deplib in -l*) func_stripname -l '' "$a_deplib" name=$func_stripname_result if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then case " $predeps $postdeps " in *" $a_deplib "*) newdeplibs="$newdeplibs $a_deplib" a_deplib="" ;; esac fi if test -n "$a_deplib" ; then libname=`eval "\\$ECHO \"$libname_spec\""` for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do potential_libs=`ls $i/$libname[.-]* 2>/dev/null` for potent_lib in $potential_libs; do potlib="$potent_lib" # see symlink-check above in file_magic test if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \ $EGREP "$match_pattern_regex" > /dev/null; then newdeplibs="$newdeplibs $a_deplib" a_deplib="" break 2 fi done done fi if test -n "$a_deplib" ; then droppeddeps=yes $ECHO $ECHO "*** Warning: linker path does not have real file for library $a_deplib." $ECHO "*** I have the capability to make that library automatically link in when" $ECHO "*** you link to this library. But I can only do this if you have a" $ECHO "*** shared version of the library, which you do not appear to have" $ECHO "*** because I did check the linker path looking for a file starting" if test -z "$potlib" ; then $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)" else $ECHO "*** with $libname and none of the candidates passed a file format test" $ECHO "*** using a regex pattern. Last file checked: $potlib" fi fi ;; *) # Add a -L argument. newdeplibs="$newdeplibs $a_deplib" ;; esac done # Gone through all deplibs. ;; none | unknown | *) newdeplibs="" tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \ -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'` if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then for i in $predeps $postdeps ; do # can't use Xsed below, because $i might contain '/' tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"` done fi if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[ ]//g' | $GREP . >/dev/null; then $ECHO if test "X$deplibs_check_method" = "Xnone"; then $ECHO "*** Warning: inter-library dependencies are not supported in this platform." else $ECHO "*** Warning: inter-library dependencies are not known to be supported." fi $ECHO "*** All declared inter-library dependencies are being dropped." droppeddeps=yes fi ;; esac versuffix=$versuffix_save major=$major_save release=$release_save libname=$libname_save name=$name_save case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library with the System framework newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac if test "$droppeddeps" = yes; then if test "$module" = yes; then $ECHO $ECHO "*** Warning: libtool could not satisfy all declared inter-library" $ECHO "*** dependencies of module $libname. Therefore, libtool will create" $ECHO "*** a static module, that should work as long as the dlopening" $ECHO "*** application is linked with the -dlopen flag." if test -z "$global_symbol_pipe"; then $ECHO $ECHO "*** However, this would only work if libtool was able to extract symbol" $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could" $ECHO "*** not find such a program. So, this module is probably useless." $ECHO "*** \`nm' from GNU binutils and a full rebuild may help." fi if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi else $ECHO "*** The inter-library dependencies that have been dropped here will be" $ECHO "*** automatically added whenever a program is linked with this library" $ECHO "*** or is declared to -dlopen it." if test "$allow_undefined" = no; then $ECHO $ECHO "*** Since this library must not contain undefined symbols," $ECHO "*** because either the platform does not support them or" $ECHO "*** it was explicitly requested with -no-undefined," $ECHO "*** libtool will only create a static version of it." if test "$build_old_libs" = no; then oldlibs="$output_objdir/$libname.$libext" build_libtool_libs=module build_old_libs=yes else build_libtool_libs=no fi fi fi fi # Done checking deplibs! deplibs=$newdeplibs fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" case $host in *-*-darwin*) newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done deplibs="$new_libs" # All the library-specific variables (install_libdir is set above). library_names= old_library= dlname= # Test again, we may have decided not to build it any more if test "$build_libtool_libs" = yes; then if test "$hardcode_into_libs" = yes; then # Hardcode the library paths hardcode_libdirs= dep_rpath= rpath="$finalize_rpath" test "$mode" != relink && rpath="$compile_rpath$rpath" for libdir in $rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" dep_rpath="$dep_rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" if test -n "$hardcode_libdir_flag_spec_ld"; then eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\" else eval dep_rpath=\"$hardcode_libdir_flag_spec\" fi fi if test -n "$runpath_var" && test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" fi test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" fi shlibpath="$finalize_shlibpath" test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" if test -n "$shlibpath"; then eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" fi # Get the real and link names of the library. eval shared_ext=\"$shrext_cmds\" eval library_names=\"$library_names_spec\" set dummy $library_names shift realname="$1" shift if test -n "$soname_spec"; then eval soname=\"$soname_spec\" else soname="$realname" fi if test -z "$dlname"; then dlname=$soname fi lib="$output_objdir/$realname" linknames= for link do linknames="$linknames $link" done # Use standard objects if they are pic test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` test "X$libobjs" = "X " && libobjs= delfiles= if test -n "$export_symbols" && test -n "$include_expsyms"; then $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp" export_symbols="$output_objdir/$libname.uexp" delfiles="$delfiles $export_symbols" fi orig_export_symbols= case $host_os in cygwin* | mingw* | cegcc*) if test -n "$export_symbols" && test -z "$export_symbols_regex"; then # exporting using user supplied symfile if test "x`$SED 1q $export_symbols`" != xEXPORTS; then # and it's NOT already a .def file. Must figure out # which of the given symbols are data symbols and tag # them as such. So, trigger use of export_symbols_cmds. # export_symbols gets reassigned inside the "prepare # the list of exported symbols" if statement, so the # include_expsyms logic still works. orig_export_symbols="$export_symbols" export_symbols= always_export_symbols=yes fi fi ;; esac # Prepare the list of exported symbols if test -z "$export_symbols"; then if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols cmds=$export_symbols_cmds save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" func_len " $cmd" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then func_show_eval "$cmd" 'exit $?' skipped_export=false else # The command line is too long to execute in one step. func_verbose "using reloadable object file for export list..." skipped_export=: # Break out early, otherwise skipped_export may be # set to false by a later but shorter cmd. break fi done IFS="$save_ifs" if test -n "$export_symbols_regex" && test "X$skipped_export" != "X:"; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi fi if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi tmp_deplibs= for test_deplib in $deplibs; do case " $convenience " in *" $test_deplib "*) ;; *) tmp_deplibs="$tmp_deplibs $test_deplib" ;; esac done deplibs="$tmp_deplibs" if test -n "$convenience"; then if test -n "$whole_archive_flag_spec" && test "$compiler_needs_object" = yes && test -z "$libobjs"; then # extract the archives, so we have objects to list. # TODO: could optimize this to just extract one archive. whole_archive_flag_spec= fi if test -n "$whole_archive_flag_spec"; then save_libobjs=$libobjs eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= else gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $convenience libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi fi if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then eval flag=\"$thread_safe_flag_spec\" linker_flags="$linker_flags $flag" fi # Make a backup of the uninstalled library when relinking if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $? fi # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then eval test_cmds=\"$module_expsym_cmds\" cmds=$module_expsym_cmds else eval test_cmds=\"$module_cmds\" cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then eval test_cmds=\"$archive_expsym_cmds\" cmds=$archive_expsym_cmds else eval test_cmds=\"$archive_cmds\" cmds=$archive_cmds fi fi if test "X$skipped_export" != "X:" && func_len " $test_cmds" && len=$func_len_result && test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then : else # The command line is too long to link in one step, link piecewise # or, if using GNU ld and skipped_export is not :, use a linker # script. # Save the value of $output and $libobjs because we want to # use them later. If we have whole_archive_flag_spec, we # want to use save_libobjs as it was before # whole_archive_flag_spec was expanded, because we can't # assume the linker understands whole_archive_flag_spec. # This may have to be revisited, in case too many # convenience libraries get linked in and end up exceeding # the spec. if test -z "$convenience" || test -z "$whole_archive_flag_spec"; then save_libobjs=$libobjs fi save_output=$output output_la=`$ECHO "X$output" | $Xsed -e "$basename"` # Clear the reloadable object creation command queue and # initialize k to one. test_cmds= concat_cmds= objlist= last_robj= k=1 if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then output=${output_objdir}/${output_la}.lnkscript func_verbose "creating GNU ld script: $output" $ECHO 'INPUT (' > $output for obj in $save_libobjs do $ECHO "$obj" >> $output done $ECHO ')' >> $output delfiles="$delfiles $output" elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then output=${output_objdir}/${output_la}.lnk func_verbose "creating linker input file list: $output" : > $output set x $save_libobjs shift firstobj= if test "$compiler_needs_object" = yes; then firstobj="$1 " shift fi for obj do $ECHO "$obj" >> $output done delfiles="$delfiles $output" output=$firstobj\"$file_list_spec$output\" else if test -n "$save_libobjs"; then func_verbose "creating reloadable object files..." output=$output_objdir/$output_la-${k}.$objext eval test_cmds=\"$reload_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 # Loop over the list of objects to be linked. for obj in $save_libobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result if test "X$objlist" = X || test "$len" -lt "$max_cmd_len"; then func_append objlist " $obj" else # The command $test_cmds is almost too long, add a # command to the queue. if test "$k" -eq 1 ; then # The first file doesn't have a previous command to add. eval concat_cmds=\"$reload_cmds $objlist $last_robj\" else # All subsequent reloadable object files will link in # the last one created. eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\" fi last_robj=$output_objdir/$output_la-${k}.$objext func_arith $k + 1 k=$func_arith_result output=$output_objdir/$output_la-${k}.$objext objlist=$obj func_len " $last_robj" func_arith $len0 + $func_len_result len=$func_arith_result fi done # Handle the remaining objects by creating one last # reloadable object file. All subsequent reloadable object # files will link in the last one created. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\" if test -n "$last_robj"; then eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\" fi delfiles="$delfiles $output" else output= fi if ${skipped_export-false}; then func_verbose "generating symbol list for \`$libname.la'" export_symbols="$output_objdir/$libname.exp" $opt_dry_run || $RM $export_symbols libobjs=$output # Append the command to create the export file. test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\$concat_cmds$export_symbols_cmds\" if test -n "$last_robj"; then eval concat_cmds=\"\$concat_cmds~\$RM $last_robj\" fi fi test -n "$save_libobjs" && func_verbose "creating a temporary reloadable object file: $output" # Loop through the commands generated above and execute them. save_ifs="$IFS"; IFS='~' for cmd in $concat_cmds; do IFS="$save_ifs" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" if test -n "$export_symbols_regex" && ${skipped_export-false}; then func_show_eval '$EGREP -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' func_show_eval '$MV "${export_symbols}T" "$export_symbols"' fi fi if ${skipped_export-false}; then if test -n "$export_symbols" && test -n "$include_expsyms"; then tmp_export_symbols="$export_symbols" test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols" $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"' fi if test -n "$orig_export_symbols"; then # The given exports_symbols file has to be filtered, so filter it. func_verbose "filter symbol list for \`$libname.la' to tag DATA exports" # FIXME: $output_objdir/$libname.filter potentially contains lots of # 's' commands which not all seds can handle. GNU sed should be fine # though. Also, the filter scales superlinearly with the number of # global variables. join(1) would be nice here, but unfortunately # isn't a blessed tool. $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter delfiles="$delfiles $export_symbols $output_objdir/$libname.filter" export_symbols=$output_objdir/$libname.def $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols fi fi libobjs=$output # Restore the value of output. output=$save_output if test -n "$convenience" && test -n "$whole_archive_flag_spec"; then eval libobjs=\"\$libobjs $whole_archive_flag_spec\" test "X$libobjs" = "X " && libobjs= fi # Expand the library linking commands again to reset the # value of $libobjs for piecewise linking. # Do each of the archive commands. if test "$module" = yes && test -n "$module_cmds" ; then if test -n "$export_symbols" && test -n "$module_expsym_cmds"; then cmds=$module_expsym_cmds else cmds=$module_cmds fi else if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then cmds=$archive_expsym_cmds else cmds=$archive_cmds fi fi fi if test -n "$delfiles"; then # Append the command to remove temporary files to $cmds. eval cmds=\"\$cmds~\$RM $delfiles\" fi # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles libobjs="$libobjs $func_extract_archives_result" test "X$libobjs" = "X " && libobjs= fi save_ifs="$IFS"; IFS='~' for cmd in $cmds; do IFS="$save_ifs" eval cmd=\"$cmd\" $opt_silent || { func_quote_for_expand "$cmd" eval "func_echo $func_quote_for_expand_result" } $opt_dry_run || eval "$cmd" || { lt_exit=$? # Restore the uninstalled library and exit if test "$mode" = relink; then ( cd "$output_objdir" && \ $RM "${realname}T" && \ $MV "${realname}U" "$realname" ) fi exit $lt_exit } done IFS="$save_ifs" # Restore the uninstalled library and exit if test "$mode" = relink; then $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $? if test -n "$convenience"; then if test -z "$whole_archive_flag_spec"; then func_show_eval '${RM}r "$gentop"' fi fi exit $EXIT_SUCCESS fi # Create links to the real library. for linkname in $linknames; do if test "$realname" != "$linkname"; then func_show_eval '(cd "$output_objdir" && $RM "$linkname" && $LN_S "$realname" "$linkname")' 'exit $?' fi done # If -module or -export-dynamic was specified, set the dlname. if test "$module" = yes || test "$export_dynamic" = yes; then # On all known operating systems, these are identical. dlname="$soname" fi fi ;; obj) if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then func_warning "\`-dlopen' is ignored for objects" fi case " $deplibs" in *\ -l* | *\ -L*) func_warning "\`-l' and \`-L' are ignored for objects" ;; esac test -n "$rpath" && \ func_warning "\`-rpath' is ignored for objects" test -n "$xrpath" && \ func_warning "\`-R' is ignored for objects" test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for objects" test -n "$release" && \ func_warning "\`-release' is ignored for objects" case $output in *.lo) test -n "$objs$old_deplibs" && \ func_fatal_error "cannot build library object \`$output' from non-libtool objects" libobj=$output func_lo2o "$libobj" obj=$func_lo2o_result ;; *) libobj= obj="$output" ;; esac # Delete the old objects. $opt_dry_run || $RM $obj $libobj # Objects from convenience libraries. This assumes # single-version convenience libraries. Whenever we create # different ones for PIC/non-PIC, this we'll have to duplicate # the extraction. reload_conv_objs= gentop= # reload_cmds runs $LD directly, so let us get rid of # -Wl from whole_archive_flag_spec and hope we can get by with # turning comma into space.. wl= if test -n "$convenience"; then if test -n "$whole_archive_flag_spec"; then eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\" reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'` else gentop="$output_objdir/${obj}x" generated="$generated $gentop" func_extract_archives $gentop $convenience reload_conv_objs="$reload_objs $func_extract_archives_result" fi fi # Create the old-style object. reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test output="$obj" func_execute_cmds "$reload_cmds" 'exit $?' # Exit if we aren't doing a library object file. if test -z "$libobj"; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS fi if test "$build_libtool_libs" != yes; then if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi # Create an invalid libtool object if no PIC, so that we don't # accidentally link it into a program. # $show "echo timestamp > $libobj" # $opt_dry_run || eval "echo timestamp > $libobj" || exit $? exit $EXIT_SUCCESS fi if test -n "$pic_flag" || test "$pic_mode" != default; then # Only do commands if we really have different PIC objects. reload_objs="$libobjs $reload_conv_objs" output="$libobj" func_execute_cmds "$reload_cmds" 'exit $?' fi if test -n "$gentop"; then func_show_eval '${RM}r "$gentop"' fi exit $EXIT_SUCCESS ;; prog) case $host in *cygwin*) func_stripname '' '.exe' "$output" output=$func_stripname_result.exe;; esac test -n "$vinfo" && \ func_warning "\`-version-info' is ignored for programs" test -n "$release" && \ func_warning "\`-release' is ignored for programs" test "$preload" = yes \ && test "$dlopen_support" = unknown \ && test "$dlopen_self" = unknown \ && test "$dlopen_self_static" = unknown && \ func_warning "\`LT_INIT([dlopen])' not used. Assuming no dlopen support." case $host in *-*-rhapsody* | *-*-darwin1.[012]) # On Rhapsody replace the C library is the System framework compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'` ;; esac case $host in *-*-darwin*) # Don't allow lazy linking, it breaks C++ global constructors # But is supposedly fixed on 10.4 or later (yay!). if test "$tagname" = CXX ; then case ${MACOSX_DEPLOYMENT_TARGET-10.0} in 10.[0123]) compile_command="$compile_command ${wl}-bind_at_load" finalize_command="$finalize_command ${wl}-bind_at_load" ;; esac fi # Time to change all our "foo.ltframework" stuff back to "-framework foo" compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'` ;; esac # move library search paths that coincide with paths to not yet # installed libraries to the beginning of the library search list new_libs= for path in $notinst_path; do case " $new_libs " in *" -L$path/$objdir "*) ;; *) case " $compile_deplibs " in *" -L$path/$objdir "*) new_libs="$new_libs -L$path/$objdir" ;; esac ;; esac done for deplib in $compile_deplibs; do case $deplib in -L*) case " $new_libs " in *" $deplib "*) ;; *) new_libs="$new_libs $deplib" ;; esac ;; *) new_libs="$new_libs $deplib" ;; esac done compile_deplibs="$new_libs" compile_command="$compile_command $compile_deplibs" finalize_command="$finalize_command $finalize_deplibs" if test -n "$rpath$xrpath"; then # If the user specified any rpath flags, then add them. for libdir in $rpath $xrpath; do # This is the magic to use -rpath. case "$finalize_rpath " in *" $libdir "*) ;; *) finalize_rpath="$finalize_rpath $libdir" ;; esac done fi # Now hardcode the library paths rpath= hardcode_libdirs= for libdir in $compile_rpath $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$perm_rpath " in *" $libdir "*) ;; *) perm_rpath="$perm_rpath $libdir" ;; esac fi case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`${ECHO} "$libdir" | ${SED} -e 's*/lib$*/bin*'` case :$dllsearchpath: in *":$libdir:"*) ;; ::) dllsearchpath=$libdir;; *) dllsearchpath="$dllsearchpath:$libdir";; esac case :$dllsearchpath: in *":$testbindir:"*) ;; ::) dllsearchpath=$testbindir;; *) dllsearchpath="$dllsearchpath:$testbindir";; esac ;; esac done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi compile_rpath="$rpath" rpath= hardcode_libdirs= for libdir in $finalize_rpath; do if test -n "$hardcode_libdir_flag_spec"; then if test -n "$hardcode_libdir_separator"; then if test -z "$hardcode_libdirs"; then hardcode_libdirs="$libdir" else # Just accumulate the unique libdirs. case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) ;; *) hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" ;; esac fi else eval flag=\"$hardcode_libdir_flag_spec\" rpath="$rpath $flag" fi elif test -n "$runpath_var"; then case "$finalize_perm_rpath " in *" $libdir "*) ;; *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; esac fi done # Substitute the hardcoded libdirs into the rpath. if test -n "$hardcode_libdir_separator" && test -n "$hardcode_libdirs"; then libdir="$hardcode_libdirs" eval rpath=\" $hardcode_libdir_flag_spec\" fi finalize_rpath="$rpath" if test -n "$libobjs" && test "$build_old_libs" = yes; then # Transform all the library objects into standard objects. compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` fi func_generate_dlsyms "$outputname" "@PROGRAM@" "no" # template prelinking step if test -n "$prelink_cmds"; then func_execute_cmds "$prelink_cmds" 'exit $?' fi wrappers_required=yes case $host in *cygwin* | *mingw* ) if test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; *cegcc) # Disable wrappers for cegcc, we are cross compiling anyway. wrappers_required=no ;; *) if test "$need_relink" = no || test "$build_libtool_libs" != yes; then wrappers_required=no fi ;; esac if test "$wrappers_required" = no; then # Replace the output file specification. compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` link_command="$compile_command$compile_rpath" # We have no uninstalled library dependencies, so finalize right now. exit_status=0 func_show_eval "$link_command" 'exit_status=$?' # Delete the generated files. if test -f "$output_objdir/${outputname}S.${objext}"; then func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"' fi exit $exit_status fi if test -n "$compile_shlibpath$finalize_shlibpath"; then compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" fi if test -n "$finalize_shlibpath"; then finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" fi compile_var= finalize_var= if test -n "$runpath_var"; then if test -n "$perm_rpath"; then # We should set the runpath_var. rpath= for dir in $perm_rpath; do rpath="$rpath$dir:" done compile_var="$runpath_var=\"$rpath\$$runpath_var\" " fi if test -n "$finalize_perm_rpath"; then # We should set the runpath_var. rpath= for dir in $finalize_perm_rpath; do rpath="$rpath$dir:" done finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " fi fi if test "$no_install" = yes; then # We don't need to create a wrapper script. link_command="$compile_var$compile_command$compile_rpath" # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` # Delete the old output file. $opt_dry_run || $RM $output # Link the executable and exit func_show_eval "$link_command" 'exit $?' exit $EXIT_SUCCESS fi if test "$hardcode_action" = relink; then # Fast installation is not supported link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" func_warning "this platform does not like uninstalled shared libraries" func_warning "\`$output' will be relinked during installation" else if test "$fast_install" != no; then link_command="$finalize_var$compile_command$finalize_rpath" if test "$fast_install" = yes; then relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` else # fast_install is set to needless relink_command= fi else link_command="$compile_var$compile_command$compile_rpath" relink_command="$finalize_var$finalize_command$finalize_rpath" fi fi # Replace the output file specification. link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` # Delete the old output files. $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname func_show_eval "$link_command" 'exit $?' # Now create the wrapper script. func_verbose "creating $output" # Quote the relink command for shipping. if test -n "$relink_command"; then # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done relink_command="(cd `pwd`; $relink_command)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` fi # Quote $ECHO for shipping. if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then case $progpath in [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";; *) qecho="$SHELL `pwd`/$progpath --fallback-echo";; esac qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"` else qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"` fi # Only actually do things if not in dry run mode. $opt_dry_run || { # win32 will think the script is a binary if it has # a .exe suffix, so we strip it off here. case $output in *.exe) func_stripname '' '.exe' "$output" output=$func_stripname_result ;; esac # test for cygwin because mv fails w/o .exe extensions case $host in *cygwin*) exeext=.exe func_stripname '' '.exe' "$outputname" outputname=$func_stripname_result ;; *) exeext= ;; esac case $host in *cygwin* | *mingw* ) func_dirname_and_basename "$output" "" "." output_name=$func_basename_result output_path=$func_dirname_result cwrappersource="$output_path/$objdir/lt-$output_name.c" cwrapper="$output_path/$output_name.exe" $RM $cwrappersource $cwrapper trap "$RM $cwrappersource $cwrapper; exit $EXIT_FAILURE" 1 2 15 func_emit_cwrapperexe_src > $cwrappersource # The wrapper executable is built using the $host compiler, # because it contains $host paths and files. If cross- # compiling, it, like the target executable, must be # executed on the $host or under an emulation environment. $opt_dry_run || { $LTCC $LTCFLAGS -o $cwrapper $cwrappersource $STRIP $cwrapper } # Now, create the wrapper script for func_source use: func_ltwrapper_scriptname $cwrapper $RM $func_ltwrapper_scriptname_result trap "$RM $func_ltwrapper_scriptname_result; exit $EXIT_FAILURE" 1 2 15 $opt_dry_run || { # note: this script will not be executed, so do not chmod. if test "x$build" = "x$host" ; then $cwrapper --lt-dump-script > $func_ltwrapper_scriptname_result else func_emit_wrapper no > $func_ltwrapper_scriptname_result fi } ;; * ) $RM $output trap "$RM $output; exit $EXIT_FAILURE" 1 2 15 func_emit_wrapper no > $output chmod +x $output ;; esac } exit $EXIT_SUCCESS ;; esac # See if we need to build an old-fashioned archive. for oldlib in $oldlibs; do if test "$build_libtool_libs" = convenience; then oldobjs="$libobjs_save $symfileobj" addlibs="$convenience" build_libtool_libs=no else if test "$build_libtool_libs" = module; then oldobjs="$libobjs_save" build_libtool_libs=no else oldobjs="$old_deplibs $non_pic_objects" if test "$preload" = yes && test -f "$symfileobj"; then oldobjs="$oldobjs $symfileobj" fi fi addlibs="$old_convenience" fi if test -n "$addlibs"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $addlibs oldobjs="$oldobjs $func_extract_archives_result" fi # Do each command in the archive commands. if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then cmds=$old_archive_from_new_cmds else # Add any objects from preloaded convenience libraries if test -n "$dlprefiles"; then gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_extract_archives $gentop $dlprefiles oldobjs="$oldobjs $func_extract_archives_result" fi # POSIX demands no paths to be encoded in archives. We have # to avoid creating archives with duplicate basenames if we # might have to extract them afterwards, e.g., when creating a # static archive out of a convenience library, or when linking # the entirety of a libtool archive into another (currently # not supported by libtool). if (for obj in $oldobjs do func_basename "$obj" $ECHO "$func_basename_result" done | sort | sort -uc >/dev/null 2>&1); then : else $ECHO "copying selected object files to avoid basename conflicts..." gentop="$output_objdir/${outputname}x" generated="$generated $gentop" func_mkdir_p "$gentop" save_oldobjs=$oldobjs oldobjs= counter=1 for obj in $save_oldobjs do func_basename "$obj" objbase="$func_basename_result" case " $oldobjs " in " ") oldobjs=$obj ;; *[\ /]"$objbase "*) while :; do # Make sure we don't pick an alternate name that also # overlaps. newobj=lt$counter-$objbase func_arith $counter + 1 counter=$func_arith_result case " $oldobjs " in *[\ /]"$newobj "*) ;; *) if test ! -f "$gentop/$newobj"; then break; fi ;; esac done func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj" oldobjs="$oldobjs $gentop/$newobj" ;; *) oldobjs="$oldobjs $obj" ;; esac done fi eval cmds=\"$old_archive_cmds\" func_len " $cmds" len=$func_len_result if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then cmds=$old_archive_cmds else # the command line is too long to link in one step, link in parts func_verbose "using piecewise archive linking..." save_RANLIB=$RANLIB RANLIB=: objlist= concat_cmds= save_oldobjs=$oldobjs oldobjs= # Is there a better way of finding the last object in the list? for obj in $save_oldobjs do last_oldobj=$obj done eval test_cmds=\"$old_archive_cmds\" func_len " $test_cmds" len0=$func_len_result len=$len0 for obj in $save_oldobjs do func_len " $obj" func_arith $len + $func_len_result len=$func_arith_result func_append objlist " $obj" if test "$len" -lt "$max_cmd_len"; then : else # the above command should be used before it gets too long oldobjs=$objlist if test "$obj" = "$last_oldobj" ; then RANLIB=$save_RANLIB fi test -z "$concat_cmds" || concat_cmds=$concat_cmds~ eval concat_cmds=\"\${concat_cmds}$old_archive_cmds\" objlist= len=$len0 fi done RANLIB=$save_RANLIB oldobjs=$objlist if test "X$oldobjs" = "X" ; then eval cmds=\"\$concat_cmds\" else eval cmds=\"\$concat_cmds~\$old_archive_cmds\" fi fi fi func_execute_cmds "$cmds" 'exit $?' done test -n "$generated" && \ func_show_eval "${RM}r$generated" # Now create the libtool archive. case $output in *.la) old_library= test "$build_old_libs" = yes && old_library="$libname.$libext" func_verbose "creating $output" # Preserve any variables that may affect compiler behavior for var in $variables_saved_for_relink; do if eval test -z \"\${$var+set}\"; then relink_command="{ test -z \"\${$var+set}\" || $lt_unset $var || { $var=; export $var; }; }; $relink_command" elif eval var_value=\$$var; test -z "$var_value"; then relink_command="$var=; export $var; $relink_command" else func_quote_for_eval "$var_value" relink_command="$var=$func_quote_for_eval_result; export $var; $relink_command" fi done # Quote the link command for shipping. relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)" relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"` if test "$hardcode_automatic" = yes ; then relink_command= fi # Only create the output if not a dry run. $opt_dry_run || { for installed in no yes; do if test "$installed" = yes; then if test -z "$install_libdir"; then break fi output="$output_objdir/$outputname"i # Replace all uninstalled libtool libraries with the installed ones newdependency_libs= for deplib in $dependency_libs; do case $deplib in *.la) func_basename "$deplib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` test -z "$libdir" && \ func_fatal_error "\`$deplib' is not a valid libtool archive" newdependency_libs="$newdependency_libs $libdir/$name" ;; *) newdependency_libs="$newdependency_libs $deplib" ;; esac done dependency_libs="$newdependency_libs" newdlfiles= for lib in $dlfiles; do case $lib in *.la) func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlfiles="$newdlfiles $libdir/$name" ;; *) newdlfiles="$newdlfiles $lib" ;; esac done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in *.la) # Only pass preopened files to the pseudo-archive (for # eventual linking with the app. that links it) if we # didn't already link the preopened objects directly into # the library: func_basename "$lib" name="$func_basename_result" eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib` test -z "$libdir" && \ func_fatal_error "\`$lib' is not a valid libtool archive" newdlprefiles="$newdlprefiles $libdir/$name" ;; esac done dlprefiles="$newdlprefiles" else newdlfiles= for lib in $dlfiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlfiles="$newdlfiles $abs" done dlfiles="$newdlfiles" newdlprefiles= for lib in $dlprefiles; do case $lib in [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;; *) abs=`pwd`"/$lib" ;; esac newdlprefiles="$newdlprefiles $abs" done dlprefiles="$newdlprefiles" fi $RM $output # place dlname in correct position for cygwin tdlname=$dlname case $host,$output,$installed,$module,$dlname in *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; esac $ECHO > $output "\ # $outputname - a libtool library file # Generated by $PROGRAM (GNU $PACKAGE$TIMESTAMP) $VERSION # # Please DO NOT delete this file! # It is necessary for linking the library. # The name that we can dlopen(3). dlname='$tdlname' # Names of this library. library_names='$library_names' # The name of the static archive. old_library='$old_library' # Linker flags that can not go in dependency_libs. inherited_linker_flags='$new_inherited_linker_flags' # Libraries that this one depends upon. dependency_libs='$dependency_libs' # Names of additional weak libraries provided by this library weak_library_names='$weak_libs' # Version information for $libname. current=$current age=$age revision=$revision # Is this an already installed library? installed=$installed # Should we warn about portability when linking against -modules? shouldnotlink=$module # Files to dlopen/dlpreopen dlopen='$dlfiles' dlpreopen='$dlprefiles' # Directory that this library needs to be installed in: libdir='$install_libdir'" if test "$installed" = no && test "$need_relink" = yes; then $ECHO >> $output "\ relink_command=\"$relink_command\"" fi done } # Do a symbolic link so that the libtool archive can be found in # LD_LIBRARY_PATH before the program is installed. func_show_eval '( cd "$output_objdir" && $RM "$outputname" && $LN_S "../$outputname" "$outputname" )' 'exit $?' ;; esac exit $EXIT_SUCCESS } { test "$mode" = link || test "$mode" = relink; } && func_mode_link ${1+"$@"} # func_mode_uninstall arg... func_mode_uninstall () { $opt_debug RM="$nonopt" files= rmforce= exit_status=0 # This variable tells wrapper scripts just to set variables rather # than running their programs. libtool_install_magic="$magic" for arg do case $arg in -f) RM="$RM $arg"; rmforce=yes ;; -*) RM="$RM $arg" ;; *) files="$files $arg" ;; esac done test -z "$RM" && \ func_fatal_help "you must specify an RM program" rmdirs= origobjdir="$objdir" for file in $files; do func_dirname "$file" "" "." dir="$func_dirname_result" if test "X$dir" = X.; then objdir="$origobjdir" else objdir="$dir/$origobjdir" fi func_basename "$file" name="$func_basename_result" test "$mode" = uninstall && objdir="$dir" # Remember objdir for removal later, being careful to avoid duplicates if test "$mode" = clean; then case " $rmdirs " in *" $objdir "*) ;; *) rmdirs="$rmdirs $objdir" ;; esac fi # Don't error if the file doesn't exist and rm -f was used. if { test -L "$file"; } >/dev/null 2>&1 || { test -h "$file"; } >/dev/null 2>&1 || test -f "$file"; then : elif test -d "$file"; then exit_status=1 continue elif test "$rmforce" = yes; then continue fi rmfiles="$file" case $name in *.la) # Possibly a libtool archive, so verify it. if func_lalib_p "$file"; then func_source $dir/$name # Delete the libtool libraries and symlinks. for n in $library_names; do rmfiles="$rmfiles $objdir/$n" done test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" case "$mode" in clean) case " $library_names " in # " " in the beginning catches empty $dlname *" $dlname "*) ;; *) rmfiles="$rmfiles $objdir/$dlname" ;; esac test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" ;; uninstall) if test -n "$library_names"; then # Do each command in the postuninstall commands. func_execute_cmds "$postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi if test -n "$old_library"; then # Do each command in the old_postuninstall commands. func_execute_cmds "$old_postuninstall_cmds" 'test "$rmforce" = yes || exit_status=1' fi # FIXME: should reinstall the best remaining shared library. ;; esac fi ;; *.lo) # Possibly a libtool object, so verify it. if func_lalib_p "$file"; then # Read the .lo file func_source $dir/$name # Add PIC object to the list of files to remove. if test -n "$pic_object" && test "$pic_object" != none; then rmfiles="$rmfiles $dir/$pic_object" fi # Add non-PIC object to the list of files to remove. if test -n "$non_pic_object" && test "$non_pic_object" != none; then rmfiles="$rmfiles $dir/$non_pic_object" fi fi ;; *) if test "$mode" = clean ; then noexename=$name case $file in *.exe) func_stripname '' '.exe' "$file" file=$func_stripname_result func_stripname '' '.exe' "$name" noexename=$func_stripname_result # $file with .exe has already been added to rmfiles, # add $file without .exe rmfiles="$rmfiles $file" ;; esac # Do a test to see if this is a libtool program. if func_ltwrapper_p "$file"; then if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" relink_command= func_source $func_ltwrapper_scriptname_result rmfiles="$rmfiles $func_ltwrapper_scriptname_result" else relink_command= func_source $dir/$noexename fi # note $name still contains .exe if it was in $file originally # as does the version of $file that was added into $rmfiles rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" if test "$fast_install" = yes && test -n "$relink_command"; then rmfiles="$rmfiles $objdir/lt-$name" fi if test "X$noexename" != "X$name" ; then rmfiles="$rmfiles $objdir/lt-${noexename}.c" fi fi fi ;; esac func_show_eval "$RM $rmfiles" 'exit_status=1' done objdir="$origobjdir" # Try to remove the ${objdir}s in the directories where we deleted files for dir in $rmdirs; do if test -d "$dir"; then func_show_eval "rmdir $dir >/dev/null 2>&1" fi done exit $exit_status } { test "$mode" = uninstall || test "$mode" = clean; } && func_mode_uninstall ${1+"$@"} test -z "$mode" && { help="$generic_help" func_fatal_help "you must specify a MODE" } test -z "$exec_cmd" && \ func_fatal_help "invalid operation mode \`$mode'" if test -n "$exec_cmd"; then eval exec "$exec_cmd" exit $EXIT_FAILURE fi exit $exit_status # The TAGs below are defined such that we never get into a situation # in which we disable both kinds of libraries. Given conflicting # choices, we go for a static library, that is the most portable, # since we can't tell whether shared libraries were disabled because # the user asked for that or because the platform doesn't support # them. This is particularly important on AIX, because we don't # support having both static and shared libraries enabled at the same # time on that platform, so we default to a shared-only configuration. # If a disable-shared tag is given, we'll fallback to a static-only # configuration. But we'll never go from static-only to shared-only. # ### BEGIN LIBTOOL TAG CONFIG: disable-shared build_libtool_libs=no build_old_libs=yes # ### END LIBTOOL TAG CONFIG: disable-shared # ### BEGIN LIBTOOL TAG CONFIG: disable-static build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac` # ### END LIBTOOL TAG CONFIG: disable-static # Local Variables: # mode:shell-script # sh-indentation:2 # End: # vi:sw=2 odin-1.8.5/platforms/0000755000175000017500000000000011735135552011475 500000000000000odin-1.8.5/platforms/StandAlone/0000755000175000017500000000000011735135552013525 500000000000000odin-1.8.5/platforms/StandAlone/odinseq_standalone/0000755000175000017500000000000011735135552017377 500000000000000odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqstandalone.cpp0000644000175000017500000002354111735135552022671 00000000000000#include "seqstandalone.h" #include "seqacq_standalone.h" #include "seqacqepi_standalone.h" #include "seqdec_standalone.h" #include "seqdelay_standalone.h" #include "seqfreq_standalone.h" #include "seqgradchan_standalone.h" #include "seqgradtrapez_standalone.h" #include "seqlist_standalone.h" #include "seqcounter_standalone.h" #include "seqparallel_standalone.h" #include "seqphase_standalone.h" #include "seqpuls_standalone.h" #include "seqtrigg_standalone.h" #include #include const char* SeqStandAlone::get_compName() {return "StandAlone";} LOGGROUNDWORK(SeqStandAlone) int SeqStandAlone::process(int argc, char *argv[]) { #ifndef NO_CMDLINE Log odinlog("SeqStandAlone","process"); SeqMethodProxy method; SeqPlatformProxy pfinterface; char value[ODIN_MAXCHAR]; bool valid_command=false; STD_string action(argv[1]); if(action=="plot") { if(getCommandlineOption(argc,argv,"-p",value,ODIN_MAXCHAR)) method->load_protocol(value); pfinterface.set_current_platform(standalone); // overwrite result from load_protocol dump2console=true; if(method->prepare()) { eventContext context; context.action=seqRun; method->event(context); STD_cout << STD_endl; } else ODINLOG(odinlog,errorLog) << method->get_label() << +"->prepare() failed" << STD_endl; dump2console=false; valid_command=true; } if(action=="simulate") { STD_string samplefile; if(getCommandlineOption(argc,argv,"-s",value,ODIN_MAXCHAR)) samplefile=value; else { ODINLOG(odinlog,errorLog) << "(simulate): No virtual sample file specified" << STD_endl; return -1; } if(getCommandlineOption(argc,argv,"-p",value,ODIN_MAXCHAR)) method->load_protocol(value); pfinterface.set_current_platform(standalone); // overwrite result from load_protocol while(getCommandlineOption(argc,argv,"-m",value,ODIN_MAXCHAR)) { svector toks(tokens(value,'=')); if(toks.size()!=2) ODINLOG(odinlog,errorLog) << "syntax error in " << value << STD_endl; else method->set_sequenceParameter(toks[0],toks[1]); } if(!method->prepare()) { ODINLOG(odinlog,errorLog) << "(simulate): method->prepare() failed" << STD_endl; return -1; } if(!method->prep_acquisition()) { ODINLOG(odinlog,errorLog) << "(simulate): method->prep_acquisition() failed" << STD_endl; return -1; } plotData->get_opts(true,true).parse_cmdline_options(argc,argv); ProgressDisplayConsole pdc; ProgressMeter progmeter(pdc); create_plot_events(&progmeter); STD_string fidfile=systemInfo->get_scandir()+get_rawfile(); plotData->simulate(fidfile,samplefile,&progmeter,0); method->write_meas_contex(systemInfo->get_scandir()); plotData->get_opts(true,true).write(systemInfo->get_scandir()+"simopts"); valid_command=true; } // if(!valid_command) return -1; return int(valid_command); #endif return 0; } SeqCmdlineActionList SeqStandAlone::get_actions_usage() const { SeqCmdlineActionList result; #ifndef NO_CMDLINE SeqCmdlineAction plot("plot","Print plotting events to the console."); plot.add_opt_arg("p","The file with the measurement protocol"); result.push_back(plot); SeqCmdlineAction simulate("simulate","Creates a virtual MR signal by simulating the sequence."); simulate.opt_args=plotData->get_opts(true,true).get_cmdline_options(); simulate.add_req_arg("s","The virtual sample file"); simulate.add_opt_arg("p","The file with the measurement protocol"); simulate.add_opt_arg("m","protcol_parameter=value"); result.push_back(simulate); #endif return result; } void SeqStandAlone::pre_event(eventContext& context) const { Log odinlog(this,"pre_event"); ODINLOG(odinlog,normalDebug) << "resetting plotData" << STD_endl; plotData->reset(); new_plot_frame(context); } void SeqStandAlone::post_event(eventContext& context) const { flush_plot_frame(context); if(dump2console) { double totaldur=plotData->get_total_duration(); STD_cout << "---------- Curves: ---------------------" << STD_endl; STD_list::const_iterator begin,end; plotData->get_curves(begin, end, 0.0, totaldur, totaldur); for(STD_list::const_iterator it=begin; it!=end; ++it) { if(it->size) { STD_cout << it->x[0] << "\t" << it->label; if(it->has_freq_phase) STD_cout << "\tfreq/phase=" << it->freq << "/" << it->phase; if(it->gradmatrix) STD_cout << "\tgradmatrix=" << it->gradmatrix->print(); STD_cout << STD_endl; } } STD_cout << "---------- Markers: --------------------" << STD_endl; STD_list::const_iterator markbegin,markend; plotData->get_markers(markbegin, markend, 0.0, totaldur); for(STD_list::const_iterator markit=markbegin; markit!=markend; ++markit) { STD_cout << markit->x << "\t" << markit->label << STD_endl; } } } fvector SeqStandAlone::get_acq_channel_scale_factors() const { fvector result(numof_rec_channels()); result=1.0; return result; } void SeqStandAlone::new_plot_frame(eventContext& context) const { context.elapsed=0.0; } void SeqStandAlone::flush_plot_frame(eventContext& context) const { plotData->flush_frame(context.elapsed); context.elapsed=0.0; } SeqAcqDriver* SeqStandAlone::create_driver(SeqAcqDriver*) const {return new SeqAcqStandAlone;} SeqEpiDriver* SeqStandAlone::create_driver(SeqEpiDriver*) const {return new SeqEpiDriverDefault;} SeqDecouplingDriver* SeqStandAlone::create_driver(SeqDecouplingDriver*) const {return new SeqDecouplingStandalone;} SeqDelayDriver* SeqStandAlone::create_driver(SeqDelayDriver*) const {return new SeqDelayStandAlone;} SeqDelayVecDriver* SeqStandAlone::create_driver(SeqDelayVecDriver*) const {return new SeqDelayVecStandAlone;} SeqFreqChanDriver* SeqStandAlone::create_driver(SeqFreqChanDriver*) const {return new SeqFreqChanStandAlone;} SeqGradChanDriver* SeqStandAlone::create_driver(SeqGradChanDriver*) const {return new SeqGradChanStandAlone;} SeqGradChanParallelDriver* SeqStandAlone::create_driver(SeqGradChanParallelDriver*) const {return new SeqGradChanParallelStandAlone;} SeqGradTrapezDriver* SeqStandAlone::create_driver(SeqGradTrapezDriver*) const {return new SeqGradTrapezDefault;} SeqListDriver* SeqStandAlone::create_driver(SeqListDriver*) const {return new SeqListStandAlone;} SeqCounterDriver* SeqStandAlone::create_driver(SeqCounterDriver*) const {return new SeqCounterStandAlone;} SeqParallelDriver* SeqStandAlone::create_driver(SeqParallelDriver*) const {return new SeqParallelStandAlone;} SeqPhaseDriver* SeqStandAlone::create_driver(SeqPhaseDriver*) const {return new SeqPhaseStandAlone;} SeqPulsDriver* SeqStandAlone::create_driver(SeqPulsDriver*) const {return new SeqPulsStandAlone;} SeqTriggerDriver* SeqStandAlone::create_driver(SeqTriggerDriver*) const {return new SeqTriggerStandAlone;} unsigned int SeqStandAlone::numof_rec_channels() const { return plotData->numof_rec_channels(); } void SeqStandAlone::append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr) const { plotData->append_curve(starttime,curve_ptr); } void SeqStandAlone::append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr, double freq, double phase) const { plotData->append_curve(starttime,curve_ptr,freq,phase); } void SeqStandAlone::append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr, const RotMatrix* gradrotmatrix) const { plotData->append_curve(starttime,curve_ptr,gradrotmatrix); } void SeqStandAlone::set_systemInfo_defaults() { Log odinlog(this,"set_systemInfo_defaults"); SystemInterface::systemInfo_platform[standalone]->platformstr=get_label(); // hide unused settings SystemInterface::systemInfo_platform[standalone]->reference_gain.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->transmit_coil_name.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->delay_rastertime.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->rf_rastertime.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->acq_rastertime.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->grad_rastertime.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->min_grad_rastertime.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->inter_grad_delay.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->max_rf_samples.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->max_grad_samples.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->datatype.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->grad_reson_center.set_parmode(hidden); SystemInterface::systemInfo_platform[standalone]->grad_reson_width.set_parmode(hidden); } SeqPlotDataAbstract* SeqStandAlone::get_plot_data() {return plotData.unlocked_ptr();} bool SeqStandAlone::create_plot_events(ProgressMeter* progmeter) { SeqMethodProxy method; eventContext context; // count events first if(progmeter) { context.action=countEvents; unsigned int eventscount=method->SeqMethod::event(context); context.event_progmeter=progmeter; context.event_progmeter->new_task(eventscount,"Creating sequence plot"); } context.action=seqRun; method->SeqMethod::event(context); return true; } void SeqStandAlone::init_static() { plotData.init("plotData"); } void SeqStandAlone::destroy_static() { plotData.destroy(); } template class SingletonHandler; SingletonHandler SeqStandAlone::plotData; double SeqStandAlone::current_rf_rec_freq=0.0; double SeqStandAlone::current_rf_rec_phase=0.0; const RotMatrix* SeqStandAlone::current_rotmatrix=0; bool SeqStandAlone::dump2console=false; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqacq_standalone.cpp0000644000175000017500000000352011735135552023510 00000000000000#include "seqacq_standalone.h" SeqAcqStandAlone::SeqAcqStandAlone(const SeqAcqStandAlone& sas) { set_label(sas.get_label()); } bool SeqAcqStandAlone::prep_driver(kSpaceCoord& recoindex, double sweepwidth,unsigned int nAcqPoints, double acqcenter, int freqchannel) { Log odinlog(this,"prep_driver"); adc_curve.label=get_label().c_str(); adc_curve.channel=rec_plotchan; adc_curve.spikes=true; double acqdur=secureDivision(double(nAcqPoints),sweepwidth); double dt=secureInv(sweepwidth); ODINLOG(odinlog,normalDebug) << "acqdur/dt/nAcqPoints=" << acqdur << "/" << dt << "/" << nAcqPoints << STD_endl; adc_curve.resize(nAcqPoints); for(unsigned int i=0; i=0.0 && acqcenter<=acqdur) { adc_curve.marker=acquisition_marker; adc_curve.marklabel=markLabel[acquisition_marker]; adc_curve.marker_x=acqcenter; } if(dump2console) { STD_cout << adc_curve << STD_endl; STD_cout << adc_curve_nomark << STD_endl; STD_cout << endacq_mark << STD_endl; } return true; } void SeqAcqStandAlone::event(eventContext& context, double start) const { Log odinlog(this,"event"); // plot center and end marker append_curve2plot(start,&adc_curve,current_rf_rec_freq,current_rf_rec_phase); append_curve2plot(start,&endacq_mark); } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqgradchan_standalone.cpp0000644000175000017500000001313711735135552024520 00000000000000#include "seqgradchan_standalone.h" void SeqGradChanStandAlone::common_int() { veccurve_cache=0; current_vec=-1; } void SeqGradChanStandAlone::common_prep(SeqGradPlotCurve& gradcurve) { for(int i=0; iget_max_slew_rate(); if(gradduration<0.0) gradduration=0.0; float maxstrength_dur=slewrate*gradduration; if(fabs(strength)>maxstrength_dur) { float sign=secureDivision(strength,fabs(strength)); strength=sign*maxstrength_dur; } double rampdur=secureDivision(fabs(strength),slewrate); if(rampdur>0.0 && strength!=0.0) { for(int i=0; i odinlog(this,"prep_vector"); unsigned int n=gradvec.size(); ODINLOG(odinlog,normalDebug) << "gradvec(" << n << ")=" << gradvec.printbody() << STD_endl; veccurve_cache=new SeqGradPlotCurve[n]; for(unsigned int j=0; j odinlog(this,"prep_vector_iteration"); ODINLOG(odinlog,normalDebug) << "count=" << count << STD_endl; current_vec=count; return true; } bool SeqGradChanStandAlone::prep_trapez(float strength, const fvector& strengthfactor, double ruptime, const fvector& rupshape, double consttime, double rdowntime, const fvector& rdownshape) { common_prep(curve); unsigned int n_up =rupshape.size(); unsigned int n_down=rdownshape.size(); unsigned int n_total=n_up+2+n_down; unsigned int j; for(int i=0; i odinlog(this,"event"); ODINLOG(odinlog,normalDebug) << "start=" << start << STD_endl; for(int i=0; i=0) { ODINLOG(odinlog,normalDebug) << "current_vec=" << current_vec << STD_endl; if(veccurve_cache[current_vec].grad[i].x.size()) { append_curve2plot(start,&(veccurve_cache[current_vec].grad[i]),current_rotmatrix); } } } else { if(curve.grad[i].x.size()) { append_curve2plot(start,&(curve.grad[i]),current_rotmatrix); } } } } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqacqepi_standalone.cpp0000644000175000017500000000012111735135552024200 00000000000000#include "seqacqepi_standalone.h" // empty, because SeqEpiDriverDefault is used odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqparallel_standalone.cpp0000644000175000017500000000004511735135552024537 00000000000000#include "seqparallel_standalone.h" odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqcounter_standalone.cpp0000644000175000017500000000004311735135552024420 00000000000000#include "seqcounter_standalone.h" odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqdec_standalone.h0000644000175000017500000000430211735135552023143 00000000000000/*************************************************************************** seqdec_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDEC_STANDALONE_H #define SEQDEC_STANDALONE_H #include #include "seqstandalone.h" #define ON_OFF_DELAY 1.0e-6 /** * @ingroup odinseq_internals * The Standalone driver for decoupling periods */ class SeqDecouplingStandalone : public SeqDecouplingDriver, public SeqStandAlone { public: SeqDecouplingStandalone() {} SeqDecouplingStandalone(const SeqDecouplingStandalone& sds); ~SeqDecouplingStandalone() {} // overloading virtual functions from SeqDecouplingDriver bool prep_driver(double decdur, int channel, float decpower, const STD_string& program, double pulsedur); void event(eventContext& context, double start) const; double get_preduration() const {return 0.0;} double get_postduration() const {return 0.0;} STD_string get_preprogram(programContext& context, const STD_string& iteratorcommand) const {return "";} STD_string get_postprogram(programContext& context) const {return "";} SeqDecouplingDriver* clone_driver() const {return new SeqDecouplingStandalone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: SeqPlotCurve curve; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqstandalone.h0000644000175000017500000001126011735135552022331 00000000000000/*************************************************************************** seqstandalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQSTANDALONE_H #define SEQSTANDALONE_H #include #include #include class SeqPlotCurve; // forward declaration class SeqPlotData; // forward declaration //////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Base class for all sequence objects that deal with functionality specific to the ODIN stand-alone platform */ class SeqStandAlone : public SeqPlatform, public StaticHandler { public: SeqStandAlone() {} SeqStandAlone(const PlatformRegistration&) {set_label("StandAlone");set_systemInfo_defaults();} // name of debugging component static const char* get_compName(); // overloadded functions from SeqPlatform void init() {} void reset_before_prep() {} void prepare_measurement(unsigned int) {} SeqAcqDriver* create_driver(SeqAcqDriver*) const; SeqEpiDriver* create_driver(SeqEpiDriver*) const; SeqDecouplingDriver* create_driver(SeqDecouplingDriver*) const; SeqDelayDriver* create_driver(SeqDelayDriver*) const; SeqDelayVecDriver* create_driver(SeqDelayVecDriver*) const; SeqFreqChanDriver* create_driver(SeqFreqChanDriver*) const; SeqGradChanDriver* create_driver(SeqGradChanDriver*) const; SeqGradChanParallelDriver* create_driver(SeqGradChanParallelDriver*) const; SeqGradTrapezDriver* create_driver(SeqGradTrapezDriver*) const; SeqListDriver* create_driver(SeqListDriver*) const; SeqCounterDriver* create_driver(SeqCounterDriver*) const; SeqParallelDriver* create_driver(SeqParallelDriver*) const; SeqPhaseDriver* create_driver(SeqPhaseDriver*) const; SeqPulsDriver* create_driver(SeqPulsDriver*) const; SeqTriggerDriver* create_driver(SeqTriggerDriver*) const; int process(int argc, char *argv[]); SeqCmdlineActionList get_actions_usage() const; void pre_event (eventContext& context) const; void post_event(eventContext& context) const; fvector get_acq_channel_scale_factors() const; STD_string get_program(programContext& context) const {return "";} STD_string get_rawdatatype() const {return TypeTraits::type2label(float(0));} STD_string get_rawfile() const {return "signal.float";} unsigned int get_rawheader_size() const {return 0;} STD_string get_image_proc() const {return "";} bool create_recoInfo() const {return true;} int write_rf_waveform (const STD_string& filename, const cvector& waveform) const {return -1;} int load_rf_waveform (const STD_string& filename, cvector& result) const {return -1;} int get_max_methodname_length() const {return -1;} void set_eventlogging(eventLogging loggflag) {} void set_idea_pars(void* pmp,void* psl,void* pse, bool onlineReco) {} SeqPlotDataAbstract* get_plot_data(); bool create_plot_events(ProgressMeter* progmeter); // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); unsigned int numof_rec_channels() const; protected: void append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr) const; void append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr, double freq, double phase) const; void append_curve2plot(double starttime, const SeqPlotCurve* curve_ptr, const RotMatrix* gradrotmatrix) const; void new_plot_frame(eventContext& context) const; void flush_plot_frame(eventContext& context) const; static double current_rf_rec_freq; static double current_rf_rec_phase; static const RotMatrix* current_rotmatrix; static bool dump2console; private: void set_systemInfo_defaults(); static SingletonHandler plotData; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqcounter_standalone.h0000644000175000017500000000575011735135552024077 00000000000000/*************************************************************************** seqcounter_standalone.h - description ------------------- begin : Sat Apr 17 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQCOUNTER_STANDALONE_H #define SEQCOUNTER_STANDALONE_H #include ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for counter objects */ class SeqCounterStandAlone : public SeqCounterDriver { public: SeqCounterStandAlone() {} SeqCounterStandAlone(const SeqCounterStandAlone& sls) {set_label(sls.get_label());} ~SeqCounterStandAlone() {} // overloading virtual functions from SeqCounterDriver bool prep_driver() {return true;} void update_driver(const SeqCounter* counter, const SeqObjList* seqlist, const List* vectors) const {}; double get_preduration () const {return 0.0;} double get_postduration() const {return 0.0;} double get_preduration_inloop() const {return 0.0;} double get_postduration_inloop() const {return 0.0;} bool create_program(programContext& context, const STD_string& loopkernel) const {return true;} STD_string get_program_head(programContext& context, const STD_string& loopkernel, unsigned int times) const {return "";} STD_string get_program_tail(programContext& context, const STD_string& loopkernel, unsigned int times) const {return "";} STD_string get_program_head_unrolled(programContext& context, unsigned int index) const {return "";} STD_string get_program_iterator(programContext& context) const {return "";} void pre_vecprepevent (eventContext& context) const {} void post_vecprepevent(eventContext& context, int repcounter) const {} void outdate_cache() const {} bool unroll_program(const SeqCounter* counter, const SeqObjList* seqlist, const List* vectors, programContext& context) const {return false;} SeqCounterDriver* clone_driver() const {return new SeqCounterStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqgradchan_standalone.h0000644000175000017500000001111311735135552024155 00000000000000/*************************************************************************** seqgradchan_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADCHAN_STANDALONE_H #define SEQGRADCHAN_STANDALONE_H #include #include #include "seqstandalone.h" ////////////////////////////////////////////////////////////////// struct SeqGradPlotCurve { SeqGradPlotCurve() { for(int i=0; i #include #include SeqTimecourseOpts::SeqTimecourseOpts() : JcampDxBlock("Timecourse Options") { JcampDxBlock::set_embedded(true); EddyCurrentAmpl=0.0; EddyCurrentAmpl.set_minmaxval(0.0,10.0); EddyCurrentAmpl.set_unit("%"); EddyCurrentAmpl.set_description("Amplitude of eddy currents relative to the inducing gradient."); EddyCurrentAmpl.set_cmdline_option("ecamp"); EddyCurrentTimeConst=2.0; EddyCurrentTimeConst.set_minmaxval(0.0,10.0); EddyCurrentTimeConst.set_unit(ODIN_TIME_UNIT); EddyCurrentTimeConst.set_description("Time constant of the exponentially decaying eddy currents."); EddyCurrentTimeConst.set_cmdline_option("ectime"); append_member(EddyCurrentAmpl,"EddyCurrentAmpl"); append_member(EddyCurrentTimeConst,"EddyCurrentTimeConst"); } SeqSimulationOpts::SeqSimulationOpts() : JcampDxBlock("Simulation Options"), transm_coil(0), receiv_coil(0), coil_cache_up2date(false) { JcampDxBlock::set_embedded(true); SimThreads=numof_cores(); SimThreads.set_minmaxval(1,16); SimThreads.set_description("Number of concurrent threads (parallel processing) during simulation"); SimThreads.set_cmdline_option("j"); IntraVoxelMagnGrads=true; IntraVoxelMagnGrads.set_description("Consider intra-voxel magnetization gradients during simulation"); IntraVoxelMagnGrads.set_cmdline_option("magsi"); MagnMonitor=false; MagnMonitor.set_description("Monitor magnetization vector using vtk"); MagnMonitor.set_cmdline_option("mon"); ReceiverNoise=0.0; ReceiverNoise.set_minmaxval(0.0,10.0); ReceiverNoise.set_unit("%"); ReceiverNoise.set_description("Noise generated by the receiver in percentage of the maximum available, in-phase signal of the sample."); ReceiverNoise.set_cmdline_option("noise"); TransmitterCoil.set_suffix("coi"); TransmitterCoil.set_description("RF coil used for transmission. Leave blank for homogeneous coil."); TransmitterCoil.set_cmdline_option("tcoil"); ReceiverCoil.set_suffix("coi"); ReceiverCoil.set_description("RF coil used for acquisition. Leave blank for homogeneous coil."); ReceiverCoil.set_cmdline_option("rcoil"); InitialMagnVector[0]=0.0; InitialMagnVector[1]=0.0; InitialMagnVector[2]=1.0; InitialMagnVector.set_description("Initial magnetization vector."); #ifndef NO_THREADS append_member(SimThreads,"SimThreads"); #endif append_member(IntraVoxelMagnGrads,"IntraVoxelMagnGrads"); append_member(MagnMonitor,"MagnMonitor"); append_member(ReceiverNoise,"ReceiverNoise"); append_member(TransmitterCoil,"TransmitterCoil"); append_member(ReceiverCoil,"ReceiverCoil"); append_member(InitialMagnVector,"InitialMagnVector"); } void SeqSimulationOpts::update_coil_cache() const { if(coil_cache_up2date) return; outdate_coil_cache(); if(filesize(TransmitterCoil.c_str())>0) { transm_coil=new CoilSensitivity("Transmitter Coil"); if(transm_coil->load(TransmitterCoil)<=0) { delete transm_coil; transm_coil=0; } else SeqMethodProxy()->get_systemInfo().set_transmit_coil_name(TransmitterCoil.get_basename()); // update protocol } if(filesize(ReceiverCoil.c_str())>0) { receiv_coil=new CoilSensitivity("Receiver Coil"); if(receiv_coil->load(ReceiverCoil)<=0) { delete receiv_coil; receiv_coil=0; } } coil_cache_up2date=true; } void SeqSimulationOpts::outdate_coil_cache() const { if(transm_coil) delete transm_coil; transm_coil=0; if(receiv_coil) delete receiv_coil; receiv_coil=0; coil_cache_up2date=false; } /////////////////////////////////////////////////////////////// STD_ostream& operator << (STD_ostream& os, const SeqPlotCurve& spc) { os << "---------------------------------------------" << STD_endl; os << "label=" << spc.label << " "; os << "channel=" << spc.channel << " "; os << "spikes=" << spc.spikes << " "; os << STD_endl; for(unsigned int i=0; ix.size(); if(!curvesize) return false; double curvestart=start+ptr->x[0]; double curveend =start+ptr->x[curvesize-1]; return( (curvestart<=timep) && (timep<=curveend) ); } double SeqPlotCurveRef::interpolate_timepoint(double timep) const { double result=0.0; unsigned int curvesize=ptr->x.size(); for(unsigned int i=0; i<(curvesize-1); i++) { double curr_x=start+ptr->x[i]; double next_x=start+ptr->x[i+1]; double curr_y=ptr->y[i]; double next_y=ptr->y[i+1]; if(timep==curr_x) { if(curr_x==next_x) result=STD_max(curr_y,next_y); else result=curr_y; break; } if(timep==next_x) { result=next_y; break; } if(!ptr->spikes && curr_xchannel; bool src_is_gradchan= ( (src_channel>=Gread_plotchan) && (src_channel<=Gslice_plotchan) ); if(src_is_gradchan && gradmatrix) { for(int target_channel=Gread_plotchan; target_channel<=Gslice_plotchan; target_channel++) { double rotfactor=(*gradmatrix)[target_channel-Gread_plotchan][src_channel-Gread_plotchan]; sp.val[target_channel]+=rotfactor*value; } } else { sp.val[src_channel]+=value; } if(has_freq_phase) { sp.val[freq_plotchan]=freq; sp.val[phase_plotchan]=phase; } } ///////////////////////////////////////////////////////////////////////////////////////////// struct CurvePointRef { CurvePointRef() : curveref(0), index(0) {} const SeqPlotCurveRef* curveref; int index; }; ///////////////////////////////////////////////////////////////////////////////////////////// struct FrameTimepoint { FrameTimepoint(double timep, plotChannel curvechannel, const SeqPlotCurveRef* curve, int curveindex) : t(timep), markerref(0) { curve_point[curvechannel].curveref=curve; curve_point[curvechannel].index=curveindex; } FrameTimepoint(double timep, const SeqPlotCurveRef* marker) : t(timep), markerref(marker) {} double t; CurvePointRef curve_point[numof_plotchan]; const SeqPlotCurveRef* markerref; bool contains_curve(const SeqPlotCurveRef* curve) const { for(int ichan=0; ichan& synclist, double framestart) const { STD_list::const_iterator refit; STD_list::const_iterator tpit; int ichan; STD_list timepoints_in_frame; // create a list of all timepoints and the corresponding curves for(refit=begin(); refit!=end(); ++refit) { const SeqPlotCurve& plotcurve=*(refit->ptr); unsigned int curvesize=plotcurve.x.size(); for(unsigned int i=0; istart+plotcurve.x[i]; timepoints_in_frame.push_back(FrameTimepoint(curve_timepoint_in_frame, plotcurve.channel, &(*refit),i)); } if(plotcurve.marker!=no_marker) { double marker_timepoint_in_frame=refit->start+plotcurve.marker_x; timepoints_in_frame.push_back(FrameTimepoint(marker_timepoint_in_frame, &(*refit))); } } timepoints_in_frame.sort(); STD_list merged_timepoints_in_frame; // merge timepoints with the same time tpit=timepoints_in_frame.begin(); while(tpit!=timepoints_in_frame.end()) { FrameTimepoint ft=(*tpit); ++tpit; while(tpit!=timepoints_in_frame.end() && ft.merge(*tpit)) ++tpit; merged_timepoints_in_frame.push_back(ft); } // create syncpoints from the list of timepoints for(tpit=merged_timepoints_in_frame.begin(); tpit!=merged_timepoints_in_frame.end(); ++tpit) { double syncpoint_timepoint_in_frame=tpit->t; SeqPlotSyncPoint sp(framestart+syncpoint_timepoint_in_frame); // deal with curves that are explicitely part of the TimePoint for(ichan=0; ichancurve_point[ichan].curveref; if(curveref) { int curveindex=tpit->curve_point[ichan].index; double value=curveref->ptr->y[curveindex]; curveref->copy_to_syncpoint(sp,value); } } // interpolate remaining curves for(refit=begin(); refit!=end(); ++refit) { if(!tpit->contains_curve(&(*refit))) { if(refit->contains_timepoint(syncpoint_timepoint_in_frame)) { double value=refit->interpolate_timepoint(syncpoint_timepoint_in_frame); refit->copy_to_syncpoint(sp,value); } } } // deal with marker if(tpit->markerref) { sp.marker=tpit->markerref->ptr->marker; sp.marklabel=tpit->markerref->ptr->label; } synclist.push_back(sp); } } double SeqPlotFrame::get_latest_point() const { double result=0.0; for(STD_list::const_iterator refit=begin(); refit!=end(); ++refit) { const SeqPlotCurve& plotcurve=*(refit->ptr); unsigned int curvesize=plotcurve.x.size(); if(curvesize) { double latest=refit->start+plotcurve.x[curvesize-1]; if(latest>result) result=latest; } } return result; } ///////////////////////////////////////////////////////////////// void SeqTimecourse::allocate(unsigned int allocsize) { size=allocsize; x=new double[allocsize]; for(int ichan=0; ichan& synclist, const SeqTimecourse* eddy_tcourse, ProgressMeter* progmeter) : signal_x(0), signal_y(0) { Log odinlog("SeqTimecourse",""); allocate(synclist.size()); if(eddy_tcourse) ODINLOG(odinlog,normalDebug) << "eddy_tcourse->size=" << eddy_tcourse->size << STD_endl; else ODINLOG(odinlog,normalDebug) << "no eddy_tcourse" << STD_endl; unsigned int index=0; int ichan; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { x[index]=syncit->timep; for(ichan=0; ichanval[ichan]; if(eddy_tcourse && ichan>=Gread_plotchan && ichan<=Gslice_plotchan) { y[ichan][index]+=eddy_tcourse->y[ichan][index]; } } if(syncit->val[rec_plotchan]>0.0) n_rec_points++; if(progmeter) progmeter->increase_counter(); index++; } create_marker_values(synclist,progmeter); } void SeqTimecourse::create_marker_values(const STD_list& synclist, ProgressMeter* progmeter) { markers.clear(); unsigned int index=0; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { if(syncit->marker!=no_marker) { TimecourseMarker4Qwt tm4q; tm4q.x=x[index]; for(int ichan=0; ichanmarker; markers.push_back(tm4q); } index++; if(progmeter) progmeter->refresh_display(); } markers.reset_subcache(); } SeqTimecourse::~SeqTimecourse() { if(x) delete x; for(int i=0; itimepoint) break; } if(x[result]>timepoint) { while(result!=0 && x[result]>timepoint) result--; } else { while(result odinlog("SeqTimecourse","get_subtimecourse"); static SeqTimecourseData result; if(!size) return &result; unsigned int beginindex=get_index(starttime); unsigned int endindex=get_index(endtime); if(beginindex>EXTRA_TIMECOURSE_POINTS) beginindex-=EXTRA_TIMECOURSE_POINTS; else beginindex=0; if(endindex<(size-EXTRA_TIMECOURSE_POINTS)) endindex +=EXTRA_TIMECOURSE_POINTS; else endindex=size-1; result.size=endindex-beginindex; result.x=&(x[beginindex]); for(int i=0; iget_geometry().get_gradrotmatrix(true)); Nuclei nuc; float gamma=nuc.get_gamma(method->get_main_nucleus()); unsigned int ichan,nchan=1; CoilSensitivity* rec_coil=opts.get_receiv_coil(); if(rec_coil) nchan=rec_coil->get_numof_channels(); signal_label.resize(nchan); for(ichan=0; ichan endacqindices; // create cache for simulation mag.prepare_simulation(sample,opts.get_transm_coil(),opts.get_receiv_coil(),progmeter); magplot.prepare_simulation(sampleplot); // prepare noise generator, do this after 'prepare_simulation()' RandomDist noisegen; double noisefactor=0.01*opts.ReceiverNoise; float noisedev=0.0; if(noisefactor>0.0) { float sdsum=sample.get_spinDensity().sum(); noisedev=noisefactor*sdsum; ODINLOG(odinlog,normalDebug) << "noisefactor/sdsum/noisedev=" << noisefactor << "/" << sdsum << "/" << noisedev << STD_endl; } progmeter->new_task(size,"Simulating NMR Signal"); cvector signal; Profiler* prof=new Profiler("simulate"); // iterate through list of syncpoints i=0; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { y[signal_plotchan][i]=0.0; if(i) { SeqSimInterval simvals; simvals.dt=x[i]-x[i-1]; // simvals.t=0.5*(x[i]+x[i-1]); double B1re= 0.5*(y[B1re_plotchan][i] +y[B1re_plotchan][i-1]); double B1im= 0.5*(y[B1im_plotchan][i] +y[B1im_plotchan][i-1]); simvals.B1=STD_complex(B1re,B1im); simvals.freq= 0.5*(y[freq_plotchan][i] +y[freq_plotchan][i-1]); simvals.phase=0.5*(y[phase_plotchan][i] +y[phase_plotchan][i-1]); simvals.Gx= 0.5*(y[Gread_plotchan][i] +y[Gread_plotchan][i-1]); simvals.Gy= 0.5*(y[Gphase_plotchan][i]+y[Gphase_plotchan][i-1]); simvals.Gz= 0.5*(y[Gslice_plotchan][i]+y[Gslice_plotchan][i-1]); simvals.rec=y[rec_plotchan][i]; // acquire at end of simulation interval signal=mag.simulate(simvals,gamma); if(feedback) { float Mvec[3]; float dM[3]; double max_dt_fields=0.050; if( (cabs(simvals.B1) || simvals.Gx || simvals.Gy || simvals.Gz) && (simvals.dt>max_dt_fields) ) { unsigned int n_sub_dt=(unsigned int)(simvals.dt/max_dt_fields+0.5); simvals.dt=secureDivision(simvals.dt,n_sub_dt); ODINLOG(odinlog,normalDebug) << "splitting simulation into " << n_sub_dt << " sub intervals at t=" << x[i] << STD_endl; for(unsigned int isub=0; isubplot_vector(x[i-1]+isub*simvals.dt,Mvec,dM); } else feedback->plot_vector(x[i-1]+isub*simvals.dt,Mvec,0); progmeter->refresh_display(); } } else { magplot.simulate(simvals,gamma); Mvec[0]=magplot.get_Mx()[0]; Mvec[1]=magplot.get_My()[0]; Mvec[2]=magplot.get_Mz()[0]; float timestamp=0.5*(x[i]+x[i-1]); if(opts.IntraVoxelMagnGrads) { dM[0]=magplot.dMx[0][0]; dM[1]=magplot.dMy[0][0]; dM[2]=magplot.dMz[0][0]; feedback->plot_vector(timestamp,Mvec,dM); } feedback->plot_vector(timestamp,Mvec,0); } } if(simvals.rec>0.0) { // add noise to the signal if(noisedev>0.0) { for(ichan=0; ichanmarker==endacq_marker) { endacqindices.push_back(recindex); for(ichan=0; ichanmarker==snapshot_marker) { STD_string snap_fname(syncit->marklabel); if(snap_fname!="") { unsigned int totalsize=mag.get_total_size(); ODINLOG(odinlog,normalDebug) << "dumping snapshot at " << x[i] << ODIN_TIME_UNIT << " of size " << totalsize << " to file " << syncit->marklabel << STD_endl; fvector dumpmagn(3*totalsize); fvector data; unsigned int offset=0; unsigned int i; data=mag.get_Mx(); for(i=0; imarker==reset_marker) mag.reset_magnetization(); } progmeter->increase_counter(); i++; } mag.finalize_simulation(); // transfer signal curves to plotting window unsigned int last_endof_acq=0; for(STD_list::const_iterator it=endacqindices.begin(); it!=endacqindices.end(); ++it) { unsigned int acqwindow_size=(*it)-last_endof_acq; unsigned int acqwindow_start=last_endof_acq; ODINLOG(odinlog,normalDebug) << "endof_acq n_rec_points/start/size=" << n_rec_points << "/" << acqwindow_start << "/" << acqwindow_size << STD_endl; for(ichan=0; ichanadd_signal_curve(signal_curve); } last_endof_acq=(*it); } delete prof; delete[] acqresult; return true; } ///////////////////////////////////////////////////////////////// template SeqGradMomentTimecourse::SeqGradMomentTimecourse(const STD_list& synclist, const SeqTimecourse& plain_tcourse, const STD_string& nucleus, ProgressMeter* progmeter) : SeqTimecourse(plain_tcourse) { allocate(size); // allocate new arrays int igrad,ichan; Nuclei n; double gamma=n.get_gamma(nucleus); double tau[3]; for(igrad=0; igrad<3; igrad++) tau[igrad]=0.0; double moment_integral[3]; for(igrad=0; igrad<3; igrad++) moment_integral[igrad]=0.0; unsigned int index=0; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { x[index]=plain_tcourse.x[index]; double x1=x[index]; double x0=0.0; if(index) x0=x[index-1]; double dx=x1-x0; bool active_transverse=true; for(ichan=0; ichan=Gread_plotchan && ichan<=Gslice_plotchan) { int gradchan=ichan-Gread_plotchan; if(active_transverse) { double y0=0.0; double y1=0.0; if(ConstGrad) { y0=1.0; y1=1.0; } else { y1=plain_tcourse.y[ichan][index]; if(index) y0=plain_tcourse.y[ichan][index-1]; } double dy=y1-y0; double m=secureDivision(dy,dx); double x0_tau=tau[gradchan]; double x1_tau=tau[gradchan]+dx; double moment_increment= m/double(Nth_moment+2)*(pow(x1_tau,Nth_moment+2)-pow(x0_tau,Nth_moment+2)); moment_increment+=(y0-m*x0_tau)/double(Nth_moment+1)*(pow(x1_tau,Nth_moment+1)-pow(x0_tau,Nth_moment+1)); moment_integral[gradchan]+=gamma*moment_increment; } if(syncit->marker==excitation_marker) { // reset moment_integral[gradchan]=0.0; tau[gradchan]=0.0; active_transverse=true; } if(syncit->marker==refocusing_marker || syncit->marker==recallMagn_marker) { // invert phase moment_integral[gradchan]=-moment_integral[gradchan]; active_transverse=true; } if(syncit->marker==storeMagn_marker) { // disable accumulation of integral active_transverse=false; } y[ichan][index]=moment_integral[gradchan]; tau[gradchan]+=dx; } } if(progmeter) progmeter->increase_counter(); index++; } create_marker_values(synclist,progmeter); } //////////////////////////////////////////////////////////// SeqTwoFuncIntegralTimecourse::SeqTwoFuncIntegralTimecourse(const STD_list& synclist, const SeqTimecourse& ka_tcourse, const SeqTimecourse& kb_tcourse, ProgressMeter* progmeter) : SeqTimecourse(ka_tcourse) { allocate(size); // allocate new arrays int igrad,ichan; double integral[3]; for(igrad=0; igrad<3; igrad++) integral[igrad]=0.0; unsigned int index=0; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { x[index]=ka_tcourse.x[index]; double x1=x[index]; double x0=0.0; if(index) x0=x[index-1]; double dx=x1-x0; for(ichan=0; ichan=Gread_plotchan && ichan<=Gslice_plotchan) { int gradchan=ichan-Gread_plotchan; double ka1=ka_tcourse.y[ichan][index]; double kb1=kb_tcourse.y[ichan][index]; double ka0=0.0; double kb0=0.0; if(index) { ka0=ka_tcourse.y[ichan][index-1]; kb0=kb_tcourse.y[ichan][index-1]; } double dka=ka1-ka0; double dkb=kb1-kb0; double incr = ( (6.0*dx*ka0 + 3.0*dka*dx)*kb0 + 3.0*dkb*dx*ka0 + 2.0*dka*dkb*dx) / 6.0; // integrate((ka0+x/dx*dka)*(kb0+x/dx*dkb),x,0,dx); // double incr = dx * ( k0*k0 + k0*dk + dk*dk/3.0 ); // integrate((kval_last+t/dx*dk)^2,t,0,dx); integral[gradchan]+= incr; y[ichan][index]=integral[gradchan]; if(syncit->marker==excitation_marker) { integral[gradchan]=0.0; } } } if(progmeter) progmeter->increase_counter(); index++; } create_marker_values(synclist,progmeter); } //////////////////////////////////////////////////////////// SeqSlewRateTimecourse::SeqSlewRateTimecourse(const STD_list& synclist, const SeqTimecourse& plain_tcourse, ProgressMeter* progmeter) : SeqTimecourse(plain_tcourse) { allocate(size); // allocate new arrays int ichan; double maxslewrate=SeqMethodProxy()->get_systemInfo().get_max_slew_rate(); unsigned int index=0; for(STD_list::const_iterator syncit=synclist.begin(); syncit!=synclist.end(); ++syncit) { x[index]=plain_tcourse.x[index]; double x1=x[index]; double x0=0.0; if(index) x0=x[index-1]; double dx=x1-x0; for(ichan=0; ichan=Gread_plotchan && ichan<=Gslice_plotchan) { double y1=plain_tcourse.y[ichan][index]; double y0=0.0; if(index) y0=plain_tcourse.y[ichan][index-1]; double dy=y1-y0; double sr=secureDivision(dy,dx); if(fabs(sr)>maxslewrate) { double sign=secureDivision(sr,fabs(sr)); sr=sign*maxslewrate; } y[ichan][index]=sr; } } if(progmeter) progmeter->increase_counter(); index++; } create_marker_values(synclist,progmeter); } //////////////////////////////////////////////////////////// SeqEddyCurrentTimecourse::SeqEddyCurrentTimecourse(const STD_list& synclist, const SeqTimecourse& slew_rate_tcourse, const SeqTimecourseOpts& opts, ProgressMeter* progmeter) : SeqTimecourse(slew_rate_tcourse) { Log odinlog("SeqEddyCurrentTimecourse",""); allocate(size); // allocate new arrays double ec_ampl=opts.EddyCurrentAmpl/100.0; double ec_time=opts.EddyCurrentTimeConst; ODINLOG(odinlog,normalDebug) << "ec_time/ec_ampl=" << ec_time << "/" << ec_ampl << STD_endl; int ichan; for(unsigned int index=0; index=Gread_plotchan && ichan<=Gslice_plotchan) { double x1=x[index]; double x0=0.0; if(index) x0=x[index-1]; double dx=x1-x0; // eddy currents induced by the previous interval double additional_eddy_currents = - ec_ampl * slew_rate_tcourse.y[ichan][index] * dx; double decay_factor = exp(-dx/ec_time); y[ichan][index]=0.0; if(index) y[ichan][index]=decay_factor * y[ichan][index-1] + additional_eddy_currents; } } if(progmeter) progmeter->increase_counter(); } create_marker_values(synclist,progmeter); } //////////////////////////////////////////////////////////// SeqPlotData::SeqPlotData(const STD_string& objlabel) : Labeled(objlabel.c_str()), curves4qwt_cache_done(false), markers4qwt_cache_done(false), synclist_cache_done(false) { for(int itc=0; itc odinlog("SeqPlotData","flush_frame"); double latest=current_frame.get_latest_point(); double framedur_total=framestart_offset+framedur; double diff=latest-framedur_total; ODINLOG(odinlog,normalDebug) << "latest/framedur_total/diff=" << latest << "/" << framedur_total << "/" << diff << STD_endl; if(diff>1e-6) { // check whether there are remaining points leaping into next frame framestart_offset+=framedur; } else { unsigned int framesize=current_frame.size(); ODINLOG(odinlog,normalDebug) << "appending frame with size=" << framesize << STD_endl; if(framesize || framedur_total>0.0) { current_frame.frameduration=framedur_total; push_back(current_frame); } current_frame.clear(); framestart_offset=0.0; } } void SeqPlotData::reset() { Log odinlog("SeqPlotData","reset"); ODINLOG(odinlog,normalDebug) << "mem(pre )=" << Profiler::get_memory_usage() << STD_endl; STD_list::clear(); ODINLOG(odinlog,normalDebug) << "size()=" << size() << STD_endl; current_frame.clear(); signal_curves.reset(); framestart_offset=0.0; clear_curves4qwt_cache(); curves4qwt_cache_done=false; clear_markers4qwt_cache(); markers4qwt_cache_done=false; clear_synclist_cache(); for(int itc=0; itc::iterator qwtit; for(qwtit=curves4qwt_cache.begin(); qwtit!=curves4qwt_cache.end(); ++qwtit) { if(qwtit->x) delete[] qwtit->x; if(qwtit->y) delete[] qwtit->y; } curves4qwt_cache.clear(); for(qwtit=curves4qwt_cache_lowres.begin(); qwtit!=curves4qwt_cache_lowres.end(); ++qwtit) { if(qwtit->x) delete[] qwtit->x; if(qwtit->y) delete[] qwtit->y; } curves4qwt_cache_lowres.clear(); } void SeqPlotData::clear_markers4qwt_cache() const { markers4qwt_cache.clear(); } void SeqPlotData::clear_synclist_cache() const { synclist_cache.clear(); synclist_cache_done=false; } void SeqPlotData::clear_timecourse_cache(timecourseMode type) const { Log odinlog("SeqPlotData","clear_timecourse_cache"); ODINLOG(odinlog,normalDebug) << "timecourse_cache[" << type << "]=" << timecourse_cache[type] << STD_endl; if(timecourse_cache[type]) delete timecourse_cache[type]; timecourse_cache[type]=0; } void SeqPlotData::create_curves4qwt_cache() const { if(curves4qwt_cache_done) return; clear_curves4qwt_cache(); double framestart=0.0; int i; for(int ichan=0; ichan::const_iterator frameit=begin(); frameit!=end(); ++frameit) { for(STD_list::const_iterator refit=frameit->begin(); refit!=frameit->end(); ++refit) { int curvesize=refit->ptr->x.size(); if(curvesize) { Curve4Qwt c4q; c4q.label=refit->ptr->label; c4q.channel=refit->ptr->channel; c4q.size=curvesize+2; // create points with y=0 at beginning/end of curve c4q.spikes=refit->ptr->spikes; c4q.x=new double[c4q.size]; c4q.y=new double[c4q.size]; double min_y=0.0; double max_y=0.0; for(i=0; istart+refit->ptr->x[i]; double yval=refit->ptr->y[i]; c4q.y[i+1]=yval; if(yvalmax_y) max_y=yval; } // points at beginning/end of curve c4q.x[0]=c4q.x[1]; c4q.y[0]=0.0; c4q.x[c4q.size-1]=c4q.x[c4q.size-2]; c4q.y[c4q.size-1]=0.0; c4q.has_freq_phase=refit->has_freq_phase; c4q.freq=refit->freq; c4q.phase=refit->phase; c4q.gradmatrix=refit->gradmatrix; curves4qwt_cache.push_back(c4q); STD_list lowres_x; STD_list lowres_y; lowres_x.push_back(c4q.x[0]); lowres_y.push_back(c4q.y[0]); for(i=1; i<(c4q.size-1); i++) { double last_y=c4q.y[i-1]; double curr_y=c4q.y[i]; double next_y=c4q.y[i+1]; bool significant_point=false; if(last_y<=curr_y && next_y=curr_y && next_y>curr_y) significant_point=true; if(last_ycurr_y && next_y>=curr_y) significant_point=true; if(significant_point) { lowres_x.push_back(c4q.x[i]); lowres_y.push_back(c4q.y[i]); } } lowres_x.push_back(c4q.x[c4q.size-1]); lowres_y.push_back(c4q.y[c4q.size-1]); Curve4Qwt c4q_lowres; c4q_lowres=c4q; c4q_lowres.size=lowres_x.size(); c4q_lowres.x=new double[c4q_lowres.size]; c4q_lowres.y=new double[c4q_lowres.size]; i=0; STD_list::const_iterator yit=lowres_y.begin(); for(STD_list::const_iterator xit=lowres_x.begin(); xit!=lowres_x.end(); ++xit) { c4q_lowres.x[i]=(*xit); c4q_lowres.y[i]=(*yit); i++; ++yit; } curves4qwt_cache_lowres.push_back(c4q_lowres); has_curves_on_channel_cache[c4q.channel]=true; } } framestart+=frameit->frameduration; } curves4qwt_cache.reset_subcache(); curves4qwt_cache_lowres.reset_subcache(); curves4qwt_cache_done=true; } void SeqPlotData::get_curves(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime, double max_highres_interval ) const { Log odinlog("SeqPlotData","get_curves"); create_curves4qwt_cache(); double interval=endtime-starttime; if(interval>max_highres_interval) { curves4qwt_cache_lowres.get_sublist(result_begin, result_end, starttime, endtime); } else { curves4qwt_cache.get_sublist(result_begin, result_end, starttime, endtime); } } void SeqPlotData::get_signal_curves(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const { Log odinlog("SeqPlotData","get_signal_curves"); ODINLOG(odinlog,normalDebug) << "size()=" << signal_curves.size() << STD_endl; signal_curves.get_sublist(result_begin, result_end, starttime, endtime); } void SeqPlotData::create_markers4qwt_cache() const { clear_markers4qwt_cache(); double framestart=0.0; for(STD_list::const_iterator frameit=begin(); frameit!=end(); ++frameit) { for(STD_list::const_iterator refit=frameit->begin(); refit!=frameit->end(); ++refit) { if((refit->ptr->marker)!=no_marker) { Marker4Qwt m4q; m4q.label=refit->ptr->marklabel; m4q.x=framestart+refit->start+refit->ptr->marker_x; m4q.type=refit->ptr->marker; markers4qwt_cache.push_back(m4q); } } framestart+=frameit->frameduration; } markers4qwt_cache.reset_subcache(); markers4qwt_cache_done=true; } void SeqPlotData::get_markers(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const { Log odinlog("SeqPlotData","get_markers"); if(!markers4qwt_cache_done) create_markers4qwt_cache(); markers4qwt_cache.get_sublist(result_begin, result_end, starttime, endtime); } void SeqPlotData::create_synclist_cache(ProgressMeter* progmeter) const { Log odinlog("SeqPlotData","create_synclist_cache"); clear_synclist_cache(); SeqPlotSyncPoint sp_start(0.0); synclist_cache.push_back(sp_start); SeqPlotSyncPoint sp_frameend(0.0); double framestart=0.0; for(STD_list::const_iterator frameit=begin(); frameit!=end(); ++frameit) { frameit->append_syncpoints(synclist_cache,framestart); framestart+=frameit->frameduration; sp_frameend.timep=framestart; synclist_cache.push_back(sp_frameend); if(progmeter) progmeter->increase_counter(); } SeqPlotSyncPoint sp_end(framestart); synclist_cache.push_back(sp_end); synclist_cache_done=true; } void SeqPlotData::create_timecourse_cache(timecourseMode type, const STD_string& nucleus, ProgressMeter* progmeter) const { Log odinlog("SeqPlotData","create_timecourse_cache"); clear_timecourse_cache(type); SeqTimecourse* result=0; // exception safe unsigned int tcourse_size=synclist_cache.size(); STD_string progtxt=STD_string("Creating ")+timecourseLabel[type]+" Timecourse"; if(type==tcmode_plain) { create_timecourses(tcmode_eddy_currents,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqTimecourse(synclist_cache,timecourse_cache[tcmode_eddy_currents],progmeter); } if(type==tcmode_kspace) { create_timecourses(tcmode_plain,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqGradMomentTimecourse<0>(synclist_cache,*(timecourse_cache[tcmode_plain]),nucleus,progmeter); } if(type==tcmode_M1) { create_timecourses(tcmode_plain,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqGradMomentTimecourse<1>(synclist_cache,*(timecourse_cache[tcmode_plain]),nucleus,progmeter); } if(type==tcmode_M2) { create_timecourses(tcmode_plain,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqGradMomentTimecourse<2>(synclist_cache,*(timecourse_cache[tcmode_plain]),nucleus,progmeter); } if(type==tcmode_b_trace) { create_timecourses(tcmode_kspace,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqTwoFuncIntegralTimecourse(synclist_cache,*(timecourse_cache[tcmode_kspace]),*(timecourse_cache[tcmode_kspace]),progmeter); } if(type==tcmode_backgr_kspace) { create_timecourses(tcmode_plain,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqGradMomentTimecourse<0,true>(synclist_cache,*(timecourse_cache[tcmode_plain]),nucleus,progmeter); } if(type==tcmode_backgr_crossterm) { create_timecourses(tcmode_kspace,nucleus,progmeter); create_timecourses(tcmode_backgr_kspace,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqTwoFuncIntegralTimecourse(synclist_cache,*(timecourse_cache[tcmode_kspace]),*(timecourse_cache[tcmode_backgr_kspace]),progmeter); } if(type==tcmode_slew_rate) { SeqTimecourse* plain_tc_without_eddy_currents=new SeqTimecourse(synclist_cache,0,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqSlewRateTimecourse(synclist_cache,*plain_tc_without_eddy_currents,progmeter); delete plain_tc_without_eddy_currents; } if(type==tcmode_eddy_currents) { if(timecourse_opts.EddyCurrentAmpl>0.0 && timecourse_opts.EddyCurrentTimeConst>0.0) { create_timecourses(tcmode_slew_rate,nucleus,progmeter); if(progmeter) progmeter->new_task(tcourse_size,progtxt.c_str()); result=new SeqEddyCurrentTimecourse(synclist_cache,*(timecourse_cache[tcmode_slew_rate]),timecourse_opts,progmeter); } } ODINLOG(odinlog,normalDebug) << "result[" << type << "]=" << result << STD_endl; timecourse_cache[type]=result; } bool SeqPlotData::create_timecourses(timecourseMode type, const STD_string& nucleus, ProgressMeter* progmeter) const { Log odinlog("SeqPlotData","create_timecourses"); if(!synclist_cache_done) create_synclist_cache(progmeter); if(!timecourse_cache[type]) create_timecourse_cache(type, nucleus, progmeter); return bool(timecourse_cache[type]); } const SeqTimecourseData* SeqPlotData::get_timecourse(timecourseMode type) const { return timecourse_cache[type]; } const SeqTimecourseData* SeqPlotData::get_subtimecourse(timecourseMode type, double starttime, double endtime) const { if(timecourse_cache[type]) return timecourse_cache[type]->get_subtimecourse(starttime, endtime); return 0; } void SeqPlotData::get_timecourse_markers(timecourseMode type, STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const { if(timecourse_cache[type]) timecourse_cache[type]->get_markers(result_begin,result_end,starttime,endtime); } double SeqPlotData::get_total_duration() const { double result=0.0; for(STD_list::const_iterator frameit=begin(); frameit!=end(); ++frameit) { result+=frameit->frameduration; } return result; } unsigned int SeqPlotData::numof_rec_channels() const { unsigned int result=1; CoilSensitivity* rec_coil=sim_opts.get_receiv_coil(); if(rec_coil) result=rec_coil->get_numof_channels(); return result; } JcampDxBlock& SeqPlotData::get_opts(bool include_timecourse_opts, bool include_simulation_opts) const { all_opts.clear(); all_opts.set_label("Options"); if(include_timecourse_opts) all_opts.merge(timecourse_opts); if(include_simulation_opts) { all_opts.merge(sim_opts); sim_opts.outdate_coil_cache(); // might be changed } return all_opts; } void SeqPlotData::set_coilsdir(const STD_string& coilsdir) const { sim_opts.TransmitterCoil.set_defaultdir(coilsdir); sim_opts.ReceiverCoil.set_defaultdir(coilsdir); } bool SeqPlotData::simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter, SeqSimFeedbackAbstract* feedback) const { if(!create_timecourses(tcmode_plain,"",progmeter)) return false; return timecourse_cache[tcmode_plain]->simulate(synclist_cache,fidfile,samplefile,sim_opts,progmeter,feedback,this); } bool SeqPlotData::has_curves_on_channel(plotChannel chan) const { create_curves4qwt_cache(); return has_curves_on_channel_cache[chan]; } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqtrigg_standalone.h0000644000175000017500000000422711735135552023532 00000000000000/*************************************************************************** seqtrigg_standalone.h - description ------------------- begin : Mon Apr 12 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQTRIGG_STANDALONE_H #define SEQTRIGG_STANDALONE_H #include #include "seqstandalone.h" ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for external trigger events */ class SeqTriggerStandAlone : public SeqTriggerDriver, public SeqStandAlone { public: SeqTriggerStandAlone() {} SeqTriggerStandAlone(const SeqTriggerStandAlone& sts) {set_label(sts.get_label());} ~SeqTriggerStandAlone() {} // overloading virtual functions from SeqTriggerDriver double get_postduration() const {return 0.0;} bool prep_exttrigger(double duration); bool prep_halttrigger(); bool prep_snaptrigger(const STD_string& snapshot_fname); bool prep_resettrigger(); void event(eventContext& context, double startelapsed) const; STD_string get_program(programContext& context) const {return "";} SeqTriggerDriver* clone_driver() const {return new SeqTriggerStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: SeqPlotCurve trigg_marker; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqacqepi_standalone.h0000644000175000017500000000224111735135552023652 00000000000000/*************************************************************************** seqacqepi_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQEPI_STANDALONE_H #define SEQACQEPI_STANDALONE_H #include // empty, because SeqEpiDriverDefault is used #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqlist_standalone.h0000644000175000017500000000461111735135552023366 00000000000000/*************************************************************************** seqlist_standalone.h - description ------------------- begin : Sat Apr 17 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQLIST_STANDALONE_H #define SEQLIST_STANDALONE_H #include #include "seqstandalone.h" ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for lists of sequence objects */ class SeqListStandAlone : public SeqListDriver, public SeqStandAlone { public: SeqListStandAlone() {} SeqListStandAlone(const SeqListStandAlone& sls) {set_label(sls.get_label());} ~SeqListStandAlone() {} // overloading virtual functions from SeqListDriver STD_string pre_program (programContext& context, const SeqRotMatrixVector* rotmats) const {return "";} STD_string post_program(programContext& context, const SeqRotMatrixVector* rotmats) const {return "";} STD_string get_itemprogram(const SeqTreeObj* item, programContext& context) const {return "";} void pre_event (eventContext& context, const RotMatrix* rotmatrix) const; void post_event(eventContext& context, const RotMatrix* rotmatrix) const; void pre_itemevent (const SeqTreeObj* item, eventContext& context) const; void post_itemevent(const SeqTreeObj* item, eventContext& context) const; bool prep_driver() {return true;} SeqListDriver* clone_driver() const {return new SeqListStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqpuls_standalone.h0000644000175000017500000000531411735135552023377 00000000000000/*************************************************************************** seqpuls_standalone.h - description ------------------- begin : Sat Apr 3 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPULS_STANDALONE_H #define SEQPULS_STANDALONE_H #include #include "seqstandalone.h" ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for RF pulses */ class SeqPulsStandAlone : public SeqPulsDriver, public SeqStandAlone { public: SeqPulsStandAlone() {current_pls=0;} ~SeqPulsStandAlone() {} SeqPulsStandAlone(const SeqPulsStandAlone& sps); // overloading virtual functions from SeqPulsDriver bool prep_driver(const cvector& wave, double pulsduration, double pulscenter, float b1max, float power, float flipangle, const fvector& flipscales, pulseType plstype); void event(eventContext& context, double start) const; double get_rf_energy() const {return rf_energy[current_pls];} bool prep_flipangle_iteration(unsigned int count); double get_predelay() const {return 0.0;} double get_postdelay() const {return 0.0;} STD_string get_program(programContext& context, unsigned int phaselistindex,int channel, const STD_string& iteratorcommand) const {return "";} STD_string get_instr_label() const {return "";} svector get_flipvector_commands(const STD_string& iterator) const {return svector();} void new_freq(double newfreq) const {} bool has_new_freq() const {return true;} SeqPulsDriver* clone_driver() const {return new SeqPulsStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: STD_vector B1re_curve; STD_vector B1im_curve; dvector rf_energy; unsigned int current_pls; bool has_real; bool has_imag; STD_string relabel,imlabel; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqplot_standalone.h0000644000175000017500000003613711735135552023401 00000000000000/*************************************************************************** seqplot_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPLOT_STANDALONE_H #define SEQPLOT_STANDALONE_H #include #include #include #define TIMECOURSE_HASH_INTERVAL 100 #define EXTRA_UPDOWN_ITERATIONS 5 #define EXTRA_TIMECOURSE_POINTS 2 ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Data structure to hold parameters for timecourse generation */ struct SeqTimecourseOpts : public JcampDxBlock { SeqTimecourseOpts(); JDXdouble EddyCurrentAmpl; JDXdouble EddyCurrentTimeConst; }; ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Data structure to hold parameters for simulation */ struct SeqSimulationOpts : public JcampDxBlock { SeqSimulationOpts(); ~SeqSimulationOpts() {outdate_coil_cache();} JDXint SimThreads; JDXbool IntraVoxelMagnGrads; JDXbool MagnMonitor; JDXdouble ReceiverNoise; JDXfileName TransmitterCoil; JDXfileName ReceiverCoil; JDXtriple InitialMagnVector; CoilSensitivity* get_transm_coil() const {update_coil_cache(); return transm_coil;} CoilSensitivity* get_receiv_coil() const {update_coil_cache(); return receiv_coil;} private: friend class SeqPlotData; void update_coil_cache() const; void outdate_coil_cache() const; mutable CoilSensitivity* transm_coil; mutable CoilSensitivity* receiv_coil; mutable bool coil_cache_up2date; }; ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Data structure to hold data for sequence plotting of a single 'sequence atom', e.g. an RF pulse */ struct SeqPlotCurve { SeqPlotCurve() : label(0), channel(plotChannel(0)), spikes(false), marklabel(0), marker(no_marker), marker_x(0.0) {} void resize(unsigned int newsize) {x.resize(newsize); y.resize(newsize);} bool operator == (const SeqPlotCurve& spc) const {return (channel==spc.channel) && (x==spc.x) && (y==spc.y);} friend STD_ostream& operator << (STD_ostream& os, const SeqPlotCurve& spc); const char* label; plotChannel channel; STD_vector x; STD_vector y; bool spikes; // values will not be interpolated between points const char* marklabel; markType marker; double marker_x; }; ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Data structure to hold a discrete value synchronously on all channels */ struct SeqPlotSyncPoint { SeqPlotSyncPoint(double timepoint) : timep(timepoint), marker(no_marker), marklabel(0) {for(int i=0; i { double frameduration; void append_syncpoints(STD_list& synclist, double framestart) const; double get_latest_point() const; }; ///////////////////////////////////////////////////// template class PlotList : public STD_list { public: PlotList() {reset_subcache();} void reset_subcache() { subbegin_cache=STD_list::begin(); subend_cache =STD_list::end(); } void reset() { STD_list::clear(); reset_subcache(); } typename STD_list::const_iterator& get_iterator(double timepoint, bool below ) const { Log odinlog("PlotList","get_iterator"); typename STD_list::const_iterator current_iterator; // take iterator from last call for fast scrolling through the the curves if(below) current_iterator=subbegin_cache; else current_iterator=subend_cache; // go one item back if we are already at the end if(current_iterator==STD_list::end()) --current_iterator; // maximum boundaries for the search typename STD_list::const_iterator lower_bound=STD_list::begin(); typename STD_list::const_iterator upper_bound=STD_list::end(); unsigned int niter=0; double current_timepoint=current_iterator->get_bounds(below); // iterate current_iterator while we are below the first boundary if(current_timepoint>timepoint) { while(current_iterator!=lower_bound && current_iterator->get_bounds(below)>timepoint) { --current_iterator; niter++; } } // iterate current_iterator while we are above the last boundary if(current_timepointget_bounds(below)::end(); result_end= STD_list::end(); if(starttime>=endtime) return; if(STD_list::begin() == STD_list::end()) return; result_begin=get_iterator(starttime,true); result_end =get_iterator(endtime,false); } private: mutable typename STD_list::const_iterator subbegin_cache; mutable typename STD_list::const_iterator subend_cache; }; ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Class to calculate plain timecourses */ class SeqTimecourse : public SeqTimecourseData { public: SeqTimecourse(const STD_list& synclist, const SeqTimecourse* eddy_tcourse, ProgressMeter* progmeter); ~SeqTimecourse(); const SeqTimecourseData* get_subtimecourse(double starttime, double endtime) const; void get_markers(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const; bool simulate(const STD_list& synclist, const STD_string& fidfile, const STD_string& samplefile, const SeqSimulationOpts& opts, ProgressMeter* progmeter, SeqSimFeedbackAbstract* feedback, const SeqPlotDataAbstract* plotdata) const; protected: void allocate(unsigned int allocsize); void create_marker_values(const STD_list& synclist, ProgressMeter* progmeter); private: unsigned int get_index(double timepoint) const; PlotList markers; // signal data used for for curves in Qwt mutable double* signal_x; mutable double** signal_y; // ptr2ptr for multi-channel coils mutable unsigned int signal_nchan; // cache for numof channels mutable svector signal_label; }; ////////////////////////////// /** * @ingroup odinseq_internals * Class to calculate gradient moments */ template class SeqGradMomentTimecourse : public SeqTimecourse { public: SeqGradMomentTimecourse(const STD_list& synclist, const SeqTimecourse& plain_tcourse, const STD_string& nucleus, ProgressMeter* progmeter); }; ////////////////////////////// /** * @ingroup odinseq_internals * Class to integrate the product of two functions, e.g. to calculate b-Values */ class SeqTwoFuncIntegralTimecourse : public SeqTimecourse { public: SeqTwoFuncIntegralTimecourse(const STD_list& synclist, const SeqTimecourse& ka_tcourse, const SeqTimecourse& kb_tcourse, ProgressMeter* progmeter); }; ////////////////////////////// /** * @ingroup odinseq_internals * Class to calculate gradient slew rates */ class SeqSlewRateTimecourse : public SeqTimecourse { public: SeqSlewRateTimecourse(const STD_list& synclist, const SeqTimecourse& plain_tcourse, ProgressMeter* progmeter); }; ////////////////////////////// /** * @ingroup odinseq_internals * Class to calculate gradients caused by eddy currents */ class SeqEddyCurrentTimecourse : public SeqTimecourse { public: SeqEddyCurrentTimecourse(const STD_list& synclist, const SeqTimecourse& slew_rate_tcourse, const SeqTimecourseOpts& opts, ProgressMeter* progmeter); }; ///////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Class which holds all frames of a sequence plot and which serves * as an interface to access the plotting data in various ways */ class SeqPlotData : public STD_list, public virtual SeqPlotDataAbstract, public Labeled { public: SeqPlotData(const STD_string& objlabel="unnamedSeqPlotData"); ~SeqPlotData() {reset();} void append_curve(double starttime, const SeqPlotCurve* curve_ptr) { current_frame.push_back(SeqPlotCurveRef(framestart_offset+starttime,curve_ptr)); } void append_curve(double starttime, const SeqPlotCurve* curve_ptr, double freq, double phase) { current_frame.push_back(SeqPlotCurveRef(framestart_offset+starttime,curve_ptr,freq,phase)); } void append_curve(double starttime, const SeqPlotCurve* curve_ptr, const RotMatrix* gradrotmatrix) { current_frame.push_back(SeqPlotCurveRef(framestart_offset+starttime,curve_ptr,gradrotmatrix)); } void flush_frame(double framedur); void reset(); void add_signal_curve(const Curve4Qwt& signal_curve) const; void get_curves(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime, double max_highres_interval ) const; void get_signal_curves(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const; void get_markers(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const; bool timecourse_created(timecourseMode type) const {return bool(timecourse_cache[type]);} bool create_timecourses(timecourseMode type, const STD_string& nucleus, ProgressMeter* progmeter) const; const SeqTimecourseData* get_timecourse(timecourseMode type) const; const SeqTimecourseData* get_subtimecourse(timecourseMode type, double starttime, double endtime) const; void get_timecourse_markers(timecourseMode type, STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const; double get_total_duration() const; unsigned int numof_rec_channels() const; unsigned int n_frames() const {return size();} JcampDxBlock& get_opts(bool include_timecourse_opts, bool include_simulation_opts) const; void set_coilsdir(const STD_string& coilsdir) const; bool monitor_simulation() const {return sim_opts.MagnMonitor;} bool simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter, SeqSimFeedbackAbstract* feedback) const; bool has_curves_on_channel(plotChannel chan) const; private: void clear_curves4qwt_cache() const; void clear_markers4qwt_cache() const; void clear_synclist_cache() const; void clear_timecourse_cache(timecourseMode type) const; void create_curves4qwt_cache() const; void create_markers4qwt_cache() const; void create_synclist_cache(ProgressMeter* progmeter) const; void create_timecourse_cache(timecourseMode type, const STD_string& nucleus, ProgressMeter* progmeter) const; mutable SeqTimecourseOpts timecourse_opts; mutable SeqSimulationOpts sim_opts; mutable JcampDxBlock all_opts; SeqPlotFrame current_frame; double framestart_offset; mutable PlotList curves4qwt_cache; mutable PlotList curves4qwt_cache_lowres; mutable bool curves4qwt_cache_done; mutable PlotList markers4qwt_cache; mutable bool markers4qwt_cache_done; mutable STD_list synclist_cache; mutable bool synclist_cache_done; mutable SeqTimecourse* timecourse_cache[numof_tcmodes]; mutable PlotList signal_curves; mutable bool has_curves_on_channel_cache[numof_plotchan]; }; ///////////////////////////////////////////////////////////////// #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqfreq_standalone.h0000644000175000017500000000510311735135552023345 00000000000000/*************************************************************************** seqfreq_standalone.h - description ------------------- begin : Sat Apr 3 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQFREQ_STANDALONE_H #define SEQFREQ_STANDALONE_H #include #include "seqstandalone.h" ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for transmit/receive channels */ class SeqFreqChanStandAlone : public SeqFreqChanDriver, public SeqStandAlone { public: SeqFreqChanStandAlone() {} ~SeqFreqChanStandAlone() {} SeqFreqChanStandAlone(const SeqFreqChanStandAlone& sfcs) {set_label(sfcs.get_label());} // overloading virtual functions from SeqFreqChanDriver bool prep_driver(const STD_string& nucleus, const dvector& freqlist) {return true;} void prep_iteration(double current_frequency, double current_phase, double freqchan_duration) const; int get_channel() const {return 0;} STD_string get_iteratorcommand(objCategory cat,int freqlistindex) const {return "";} svector get_freqvec_commands(const STD_string& iterator, const STD_string& instr) const {return svector();} STD_string get_pre_program(programContext& context, objCategory cat, const STD_string& instr_label, double default_frequency, double default_phase) const {return "";} void pre_event (eventContext& context,double starttime) const; void post_event(eventContext& context,double starttime) const {} SeqFreqChanDriver* clone_driver() const {return new SeqFreqChanStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: mutable double freq_cache; mutable double phase_cache; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqfreq_standalone.cpp0000644000175000017500000000106511735135552023703 00000000000000#include "seqfreq_standalone.h" void SeqFreqChanStandAlone::prep_iteration(double current_frequency, double current_phase, double freqchan_duration) const { Log odinlog(this,"prep_iteration"); ODINLOG(odinlog,normalDebug) << "current_frequency/current_phase=" << current_frequency << "/" << current_phase << STD_endl; freq_cache =current_frequency; phase_cache=current_phase; } void SeqFreqChanStandAlone::pre_event(eventContext& context,double starttime) const { current_rf_rec_freq =freq_cache; current_rf_rec_phase=phase_cache; } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqparallel_standalone.h0000644000175000017500000000414211735135552024206 00000000000000/*************************************************************************** seqparallel_standalone.h - description ------------------- begin : Fri Apr 16 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPARALLEL_STANDALONE_H #define SEQPARALLEL_STANDALONE_H #include ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for parallel RF/gradient handling */ class SeqParallelStandAlone : public SeqParallelDriver, public SeqStandAlone { public: SeqParallelStandAlone() {} SeqParallelStandAlone(const SeqParallelStandAlone& sps) {set_label(sps.get_label());} ~SeqParallelStandAlone() {} // overloading virtual functions from SeqParallelDriver STD_string get_program(programContext& context, const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const {return "";} double get_duration (const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const {return 0.0;} double get_predelay (const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const {return 0.0;} SeqParallelDriver* clone_driver() const {return new SeqParallelStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqdelay_standalone.cpp0000644000175000017500000000004111735135552024035 00000000000000#include "seqdelay_standalone.h" odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqgradtrapez_standalone.h0000644000175000017500000000223511735135552024556 00000000000000/*************************************************************************** seqgradtrapez_standalone.h - description ------------------- begin : Tue Apr 27 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADTRAPEZ_STANDALONE_H #define SEQGRADTRAPEZ_STANDALONE_H #include // using default driver #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqlist_standalone.cpp0000644000175000017500000000125211735135552023717 00000000000000#include "seqlist_standalone.h" void SeqListStandAlone::pre_event (eventContext& context, const RotMatrix* rotmatrix) const { if(rotmatrix) SeqStandAlone::current_rotmatrix=rotmatrix; } void SeqListStandAlone::post_event(eventContext& context, const RotMatrix* rotmatrix) const { if(rotmatrix) SeqStandAlone::current_rotmatrix=0; } void SeqListStandAlone::pre_itemevent (const SeqTreeObj* item, eventContext& context) const { if(context.action==seqRun && !context.noflush) new_plot_frame(context); } void SeqListStandAlone::post_itemevent(const SeqTreeObj* item, eventContext& context) const { if(context.action==seqRun && !context.noflush) flush_plot_frame(context); } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqacq_standalone.h0000644000175000017500000000451011735135552023155 00000000000000/*************************************************************************** seqacq_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQ_STANDALONE_H #define SEQACQ_STANDALONE_H #include #include "seqstandalone.h" /** * @ingroup odinseq_internals * The Standalone driver for acquisition windows */ class SeqAcqStandAlone : public SeqAcqDriver, public SeqStandAlone { public: SeqAcqStandAlone() {} ~SeqAcqStandAlone() {} SeqAcqStandAlone(const SeqAcqStandAlone& sas); // overloading virtual functions from SeqAcqDriver double adjust_sweepwidth(double desired_sweep_widht) const {return desired_sweep_widht;} bool prep_driver(kSpaceCoord& recoindex, double sweepwidth,unsigned int nAcqPoints, double acqcenter, int freqchannel); double get_predelay() const {return 0.0;} double get_postdelay(double) const {return 0.0;} void event(eventContext& context, double start) const; STD_string get_program(programContext& context, unsigned int phaselistindex) const {return "";} STD_string get_instr_label() const {return "";} unsigned int get_numof_channels() const {return SeqStandAlone::numof_rec_channels();} SeqAcqDriver* clone_driver() const {return new SeqAcqStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: SeqPlotCurve adc_curve; SeqPlotCurve adc_curve_nomark; SeqPlotCurve endacq_mark; }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqdelay_standalone.h0000644000175000017500000000523211735135552023511 00000000000000/*************************************************************************** seqdelay_standalone.h - description ------------------- begin : Fri Jul 23 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDELAY_STANDALONE_H #define SEQDELAY_STANDALONE_H #include #include ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for delays */ class SeqDelayStandAlone : public SeqDelayDriver { public: SeqDelayStandAlone() {} SeqDelayStandAlone(const SeqDelayStandAlone& sds) {set_label(sds.get_label());} ~SeqDelayStandAlone() {} // overloading virtual functions from SeqDelayDriver SeqDelayDriver* clone_driver() const {return new SeqDelayStandAlone(*this);} STD_string get_program(programContext& context, double duration, const STD_string& cmd, const STD_string& durcmd) const {return "";} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for delay vectors */ class SeqDelayVecStandAlone : public SeqDelayVecDriver { public: SeqDelayVecStandAlone() {} SeqDelayVecStandAlone(const SeqDelayVecStandAlone& sdvs) {set_label(sdvs.get_label());} ~SeqDelayVecStandAlone() {} // overloading virtual functions from SeqDelayVecDriver SeqDelayVecDriver* clone_driver() const {return new SeqDelayVecStandAlone(*this);} bool prep_driver() {return true;} STD_string get_program(programContext& context, double duration) const {return "";} bool unroll_program() const {return false;} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqphase_standalone.cpp0000644000175000017500000000004111735135552024037 00000000000000#include "seqphase_standalone.h" odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqphase_standalone.h0000644000175000017500000000400411735135552023507 00000000000000/*************************************************************************** seqphase_standalone.h - description ------------------- begin : Tue Apr 6 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPHASE_STANDALONE_H #define SEQPHASE_STANDALONE_H #include ////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Standalone driver for phase lists */ class SeqPhaseStandAlone : public SeqPhaseDriver { public: SeqPhaseStandAlone() {} ~SeqPhaseStandAlone() {} SeqPhaseStandAlone(const SeqPhaseStandAlone& sps) {set_label(sps.get_label());} // overloading virtual functions from SeqPhaseDriver void prep_driver(const dvector& phaselist) {} unsigned int get_phaselistindex(const dvector& phaselist) const {return 0;} STD_string get_loopcommand(const dvector& phaselist) const {return "";} svector get_phasevec_commands(const STD_string& iterator, const STD_string& instr) const {return svector();} SeqPhaseDriver* clone_driver() const {return new SeqPhaseStandAlone(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} }; #endif odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqpuls_standalone.cpp0000644000175000017500000000517511735135552023737 00000000000000#include "seqpuls_standalone.h" SeqPulsStandAlone::SeqPulsStandAlone(const SeqPulsStandAlone& sps) { set_label(sps.get_label()); rf_energy=sps.rf_energy; current_pls=0; } bool SeqPulsStandAlone::prep_driver(const cvector& wave, double pulsduration, double pulscenter, float b1max, float power, float flipangle, const fvector& flipscales, pulseType plstype) { Log odinlog(this,"prep_driver"); fvector b1maxvals; if(flipscales.size()) { b1maxvals=b1max*flipscales; } else { b1maxvals.resize(1); b1maxvals[0]=b1max; } unsigned int n_flips=b1maxvals.size(); ODINLOG(odinlog,normalDebug) << "n_flips=" << n_flips << STD_endl; unsigned int n=wave.size(); double dt=secureDivision(pulsduration,n); B1re_curve.resize(n_flips); B1im_curve.resize(n_flips); rf_energy.resize(n_flips); fvector amp=amplitude(wave); amp=amp*amp; float ampsum=amp.sum(); has_real=false; has_imag=false; relabel=STD_string(get_label())+"_re"; imlabel=STD_string(get_label())+"_im"; for(unsigned int iflp=0; iflp odinlog(this,"prep_driver"); curve.resize(4); curve.channel=B1re_plotchan; curve.label=get_label().c_str(); curve.x[0]=0.0; curve.y[0]=0.0; curve.x[1]=ON_OFF_DELAY; curve.y[1]=decpower; curve.x[2]=decdur-ON_OFF_DELAY; curve.y[2]=decpower; curve.x[3]=decdur; curve.y[3]=0.0; if(dump2console) STD_cout << curve << STD_endl; return true; } void SeqDecouplingStandalone::event(eventContext& context, double start) const { Log odinlog(this,"event"); ODINLOG(odinlog,normalDebug) << "start=" << start << STD_endl; append_curve2plot(start,&curve,current_rf_rec_freq,current_rf_rec_phase); } odin-1.8.5/platforms/StandAlone/odinseq_standalone/seqtrigg_standalone.cpp0000644000175000017500000000260211735135552024060 00000000000000#include "seqtrigg_standalone.h" bool SeqTriggerStandAlone::prep_exttrigger(double duration) { trigg_marker.label=get_label().c_str(); trigg_marker.marklabel=markLabel[exttrigger_marker]; trigg_marker.marker=exttrigger_marker; trigg_marker.marker_x=0.0; if(dump2console) STD_cout << trigg_marker << STD_endl; return true; } bool SeqTriggerStandAlone::prep_halttrigger() { trigg_marker.label=get_label().c_str(); trigg_marker.marklabel=markLabel[halttrigger_marker]; trigg_marker.marker=halttrigger_marker; trigg_marker.marker_x=0.0; if(dump2console) STD_cout << trigg_marker << STD_endl; return true; } bool SeqTriggerStandAlone::prep_snaptrigger(const STD_string& snapshot_fname) { trigg_marker.label=snapshot_fname.c_str(); trigg_marker.marklabel=markLabel[snapshot_marker]; trigg_marker.marker=snapshot_marker; trigg_marker.marker_x=0.0; rmfile(snapshot_fname.c_str()); if(dump2console) STD_cout << trigg_marker << STD_endl; return true; } bool SeqTriggerStandAlone::prep_resettrigger() { trigg_marker.label="Magnetization Reset"; trigg_marker.marklabel=markLabel[reset_marker]; trigg_marker.marker=reset_marker; trigg_marker.marker_x=0.0; if(dump2console) STD_cout << trigg_marker << STD_endl; return true; } void SeqTriggerStandAlone::event(eventContext& context, double startelapsed) const { append_curve2plot(startelapsed,&trigg_marker); } odin-1.8.5/configure0000755000175000017500000223472011734622600011321 00000000000000#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.67. # # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software # Foundation, Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : else exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null; then : as_have_required=yes else as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir/$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : CONFIG_SHELL=$as_shell as_have_required=yes if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : break 2 fi fi done;; esac as_found=false done $as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : CONFIG_SHELL=$SHELL as_have_required=yes fi; } IFS=$as_save_IFS if test "x$CONFIG_SHELL" != x; then : # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test x$as_have_required = xno; then : $as_echo "$0: This script requires a shell more modern than all" $as_echo "$0: the shells that I found on your system." if test x${ZSH_VERSION+set} = xset ; then $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" $as_echo "$0: be upgraded to zsh 4.3.4 or later." else $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # Check that we are running under the correct shell. SHELL=${CONFIG_SHELL-/bin/sh} case X$lt_ECHO in X*--fallback-echo) # Remove one level of quotation (which was required for Make). ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` ;; esac ECHO=${lt_ECHO-echo} if test "X$1" = X--no-reexec; then # Discard the --no-reexec flag, and continue. shift elif test "X$1" = X--fallback-echo; then # Avoid inline document here, it may be left over : elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then # Yippee, $ECHO works! : else # Restart under the correct shell. exec $SHELL "$0" --no-reexec ${1+"$@"} fi if test "X$1" = X--fallback-echo; then # used as fallback echo shift cat <<_LT_EOF $* _LT_EOF exit 0 fi # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH if test -z "$lt_ECHO"; then if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... if { echo_test_string=`eval $cmd`; } 2>/dev/null && { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null then break fi done fi if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then : else # The Solaris, AIX, and Digital Unix default echo programs unquote # backslashes. This makes it impossible to quote backslashes using # echo "$something" | sed 's/\\/\\\\/g' # # So, first we look for a working echo in the user's PATH. lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for dir in $PATH /usr/ucb; do IFS="$lt_save_ifs" if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$dir/echo" break fi done IFS="$lt_save_ifs" if test "X$ECHO" = Xecho; then # We didn't find a better echo, so look for alternatives. if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # This shell has a builtin print -r that does the trick. ECHO='print -r' elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && test "X$CONFIG_SHELL" != X/bin/ksh; then # If we have ksh, try running configure again with it. ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} export ORIGINAL_CONFIG_SHELL CONFIG_SHELL=/bin/ksh export CONFIG_SHELL exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} else # Try using printf. ECHO='printf %s\n' if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then # Cool, printf works : elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL export CONFIG_SHELL SHELL="$CONFIG_SHELL" export SHELL ECHO="$CONFIG_SHELL $0 --fallback-echo" elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && test "X$echo_testing_string" = 'X\t' && echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && test "X$echo_testing_string" = "X$echo_test_string"; then ECHO="$CONFIG_SHELL $0 --fallback-echo" else # maybe with a smaller string... prev=: for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null then break fi prev="$cmd" done if test "$prev" != 'sed 50q "$0"'; then echo_test_string=`eval $prev` export echo_test_string exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} else # Oops. We lost completely, so just stick with echo. ECHO=echo fi fi fi fi fi fi # Copy echo and quote the copy suitably for passing to libtool from # the Makefile, instead of quoting the original, which is used later. lt_ECHO=$ECHO if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" fi test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= PACKAGE_URL= ac_unique_file="tjutils/tjutils.h" ac_default_prefix=/usr/local # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS all_includes ODINSEQ_INCLUDES VTKLIBS DATALIBS GUILIBS BASELIBS MOC HELP2MAN PLATFORMS EPIC_PLUGIN_FALSE EPIC_PLUGIN_TRUE STANDALONE_PLUGIN_FALSE STANDALONE_PLUGIN_TRUE PARAVISION_PLUGIN_FALSE PARAVISION_PLUGIN_TRUE IDEA_PLUGIN_FALSE IDEA_PLUGIN_TRUE GUI_ENABLED_FALSE GUI_ENABLED_TRUE ONLY_LIBS_FALSE ONLY_LIBS_TRUE XMKMF CXXCPP CPP OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL lt_ECHO RANLIB AR OBJDUMP LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE ac_ct_CC CFLAGS CC host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIBTOOL XTERM GDB am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__quote am__include DEPDIR OBJEXT EXEEXT ac_ct_CXX CPPFLAGS LDFLAGS CXXFLAGS CXX am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL' ac_subst_files='' ac_user_opts=' enable_option_checking enable_debug enable_stdcpp_replacement enable_custom_heap enable_cmdline enable_filehandling enable_threads enable_unit_test enable_gui enable_only_corelibs enable_only_epic_plugin enable_only_idea_plugin enable_only_paravision_plugin enable_only_standalone_plugin enable_ideasupport enable_niftisupport enable_vtksupport enable_dcmtksupport enable_pngsupport with_qt_dir with_extra_include_base with_extra_build_cxxflags with_extra_build_ldflags with_extra_odinseq_include_path with_lapack_libname with_editor with_browser enable_dependency_tracking enable_shared enable_static with_pic enable_fast_install with_gnu_ld enable_libtool_lock with_x ' ac_precious_vars='build_alias host_alias target_alias CXX CXXFLAGS LDFLAGS LIBS CPPFLAGS CCC CC CFLAGS CPP CXXCPP XMKMF' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: $ac_useropt" ac_useropt_orig=$ac_useropt ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used" >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names X features: --x-includes=DIR X include files are in DIR --x-libraries=DIR X library files are in DIR System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-debug Include code for debugging/tracing --enable-stdcpp-replacement Use built-in replacement for C++ standard library (STL, strings, streams) --enable-custom-heap=SIZE Use a heap which is a static block of memory (SIZE MB large), useful for real-time systems which do not have a safe new/delete --disable-cmdline Disable code for the command line, useful for real-time systems --disable-filehandling Disable code for file handling, useful if ODIN is used on a platform without file system --disable-threads Disable multithreading --disable-unit-test Disable unit test --disable-gui Disable graphical user interface --enable-only-corelibs Compile only the essential libraries for sequence execution (tjutils/odinpara/odinseq) --enable-only-epic-plugin Compile only the plugin for Epic --enable-only-idea-plugin Compile only the plugin for IDEA(Siemens) --enable-only-paravision-plugin Compile only the plugin for Paravision(Bruker) --enable-only-standalone-plugin Compile only the plugin for stand-alone mode --enable-ideasupport Compile against IDEA(Siemens) libraries, implies --enable-only-corelibs and --enable-stdcpp-replacement --enable-niftisupport Use libniftiio to read/write NIFTI files --enable-vtksupport Use VTK for input/output and visualization --enable-dcmtksupport Use DICOMTK to read/write DICOM files --enable-pngsupport Use libpng to write PNG files --disable-dependency-tracking speeds up one-time build --enable-dependency-tracking do not reject slow dependency extractors --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=no] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-qt-dir=DIR Base directory of the Qt library --with-extra-include-base=DIR Extra base to find includes (default=/usr/include) --with-extra-build-cxxflags=FLAGS Extra compiler flags during ODIN build (but not during sequence compilation) --with-extra-build-ldflags=FLAGS Extra linker flags during ODIN build (but not during sequence compilation) --with-extra-odinseq-include-path=PATH Extra include path for odinseq during ODIN build (but not during sequence compilation) --with-lapack-libname=LIBNAME Library name of LAPACK (default=lapack) --with-editor=EDITOR Initial settings for editor (default=/usr/bin/sensible-editor) --with-browser=BROWSER Initial settings for browser (default=/usr/bin/sensible-browser) --with-pic try to use only PIC/non-PIC objects [default=use both] --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-x use the X Window System Some influential environment variables: CXX C++ compiler command CXXFLAGS C++ compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CC C compiler command CFLAGS C compiler flags CPP C preprocessor CXXCPP C++ preprocessor XMKMF Path to xmkmf, Makefile generator for X Window System Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_header_compile # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_c_try_run LINENO # ---------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. Assumes # that executables *can* be run. ac_fn_c_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then : ac_retval=0 else $as_echo "$as_me: program exited with status $ac_status" >&5 $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_c_try_run # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_c_check_func # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || $as_test_x conftest$ac_exeext }; then : ac_retval=0 else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_check_header_mongrel LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists, giving a warning if it cannot be compiled using # the include files in INCLUDES and setting the cache variable VAR # accordingly. ac_fn_cxx_check_header_mongrel () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if eval "test \"\${$3+set}\"" = set; then : { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } else # Is the header compilable? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 $as_echo_n "checking $2 usability... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_header_compiler=yes else ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 $as_echo "$ac_header_compiler" >&6; } # Is the header present? { $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 $as_echo_n "checking $2 presence... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include <$2> _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : ac_header_preproc=yes else ac_header_preproc=no fi rm -f conftest.err conftest.i conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 $as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_cxx_preproc_warn_flag in #(( yes:no: ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 $as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; no:yes:* ) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 $as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 $as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 $as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else eval "$3=\$ac_header_compiler" fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } fi eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_header_mongrel # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 $as_echo_n "checking for $2... " >&6; } if eval "test \"\${$3+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main () { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$3=yes" else eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;} } # ac_fn_cxx_check_func cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. $as_echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo $as_echo "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo $as_echo "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then $as_echo "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then $as_echo "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && $as_echo "$as_me: caught signal $ac_signal" $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h $as_echo "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_URL "$PACKAGE_URL" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. ac_site_file1=NONE ac_site_file2=NONE if test -n "$CONFIG_SITE"; then # We do not want a PATH search for config.site. case $CONFIG_SITE in #(( -*) ac_site_file1=./$CONFIG_SITE;; */*) ac_site_file1=$CONFIG_SITE;; *) ac_site_file1=./$CONFIG_SITE;; esac elif test "x$prefix" != xNONE; then ac_site_file1=$prefix/share/config.site ac_site_file2=$prefix/etc/config.site else ac_site_file1=$ac_default_prefix/share/config.site ac_site_file2=$ac_default_prefix/etc/config.site fi for ac_site_file in "$ac_site_file1" "$ac_site_file2" do test "x$ac_site_file" = xNONE && continue if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 $as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5 ; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 $as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 $as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 $as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 $as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 $as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 $as_echo "$as_me: former value: \`$ac_old_val'" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 $as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu am__api_version='1.11' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 $as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in #(( ./ | .// | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 $as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } # Just in case sleep 1 echo timestamp > conftest.file # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5 ;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: \`$srcdir'" "$LINENO" 5 ;; esac # Do `set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi rm -f conftest.file if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"` # expand $ac_aux_dir to an absolute path am_aux_dir=`cd $ac_aux_dir && pwd` if test x"${MISSING+set}" != xset; then case $am_aux_dir in *\ * | *\ *) MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;; *) MISSING="\${SHELL} $am_aux_dir/missing" ;; esac fi # Use eval to expand $SHELL if eval "$MISSING --run true"; then am_missing_run="$MISSING --run " else am_missing_run= { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5 $as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} fi if test x"${install_sh}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using `strip' when the user # run `make install-strip'. However `strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the `STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test "${ac_cv_path_mkdir+set}" = set; then : $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir (GNU coreutils) '* | \ 'mkdir (coreutils) '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test "${ac_cv_path_mkdir+set}" = set; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 $as_echo "$MKDIR_P" >&6; } mkdir_p="$MKDIR_P" case $mkdir_p in [\\/$]* | ?:[\\/]*) ;; */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;; esac for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AWK+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AWK="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 $as_echo "$AWK" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$AWK" && break done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\"" = set; then : $as_echo_n "(cached) " >&6 else cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } SET_MAKE= else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE=odin VERSION=1.8.5 cat >>confdefs.h <<_ACEOF #define PACKAGE "$PACKAGE" _ACEOF cat >>confdefs.h <<_ACEOF #define VERSION "$VERSION" _ACEOF # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # We need awk for the "check" target. The system "awk" is bad on # some platforms. # Always define AMTAR for backward compatibility. AMTAR=${AMTAR-"${am_missing_run}tar"} am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers tjutils/config.h" if test "x$prefix" = "xNONE"; then prefix=$ac_default_prefix ac_configure_args="$ac_configure_args --prefix $prefix" fi # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then : enableval=$enable_debug; enable_debug=yes fi # Check whether --enable-stdcpp-replacement was given. if test "${enable_stdcpp_replacement+set}" = set; then : enableval=$enable_stdcpp_replacement; enable_stdcpp_replacement=yes fi # Check whether --enable-custom-heap was given. if test "${enable_custom_heap+set}" = set; then : enableval=$enable_custom_heap; enable_custom_heap=yes custom_heap_size=$enableval if test "$enableval" = "yes"; then custom_heap_size=2; fi fi # Check whether --enable-cmdline was given. if test "${enable_cmdline+set}" = set; then : enableval=$enable_cmdline; enable_cmdline=no else enable_cmdline=yes fi # Check whether --enable-filehandling was given. if test "${enable_filehandling+set}" = set; then : enableval=$enable_filehandling; enable_filehandling=no else enable_filehandling=yes fi # Check whether --enable-threads was given. if test "${enable_threads+set}" = set; then : enableval=$enable_threads; enable_threads=no else enable_threads=yes fi # Check whether --enable-unit-test was given. if test "${enable_unit_test+set}" = set; then : enableval=$enable_unit_test; enable_unittest=no else enable_unittest=yes fi # Check whether --enable-gui was given. if test "${enable_gui+set}" = set; then : enableval=$enable_gui; enable_gui=no else enable_gui=yes fi # Check whether --enable-only-corelibs was given. if test "${enable_only_corelibs+set}" = set; then : enableval=$enable_only_corelibs; enable_onlylibs=yes fi srcdir_abs=$(cd "$srcdir" && pwd) have_ideaplugin=no have_paravisionplugin=no have_standaloneplugin=no have_epicplugin=no if test -d $srcdir_abs/platforms/IDEA_n4 ; then have_ideaplugin=yes ; fi if test -d $srcdir_abs/platforms/Paravision ; then have_paravisionplugin=yes ; fi if test -d $srcdir_abs/platforms/StandAlone ; then have_standaloneplugin=yes ; fi if test -d $srcdir_abs/platforms/EPIC ; then have_epicplugin=yes ; fi enable_ideaplugin=$have_ideaplugin enable_paravisionplugin=$have_paravisionplugin enable_standaloneplugin=$have_standaloneplugin enable_epicplugin=$have_epicplugin # Check whether --enable-only-epic-plugin was given. if test "${enable_only_epic_plugin+set}" = set; then : enableval=$enable_only_epic_plugin; enable_ideaplugin=no enable_paravisionplugin=no enable_standaloneplugin=no fi # Check whether --enable-only-idea-plugin was given. if test "${enable_only_idea_plugin+set}" = set; then : enableval=$enable_only_idea_plugin; enable_paravisionplugin=no enable_standaloneplugin=no enable_epicplugin=no fi # Check whether --enable-only-paravision-plugin was given. if test "${enable_only_paravision_plugin+set}" = set; then : enableval=$enable_only_paravision_plugin; enable_ideaplugin=no enable_standaloneplugin=no enable_epicplugin=no fi # Check whether --enable-only-standalone-plugin was given. if test "${enable_only_standalone_plugin+set}" = set; then : enableval=$enable_only_standalone_plugin; enable_ideaplugin=no enable_paravisionplugin=no enable_epicplugin=no fi if test "x$have_ideaplugin" = "xno" ; then enable_ideaplugin=no ; fi if test "x$have_paravisionplugin" = "xno" ; then enable_paravisionplugin=no ; fi if test "x$have_standaloneplugin" = "xno" ; then enable_standaloneplugin=no ; fi if test "x$have_epicplugin" = "xno" ; then enable_epicplugin=no ; fi # Check whether --enable-ideasupport was given. if test "${enable_ideasupport+set}" = set; then : enableval=$enable_ideasupport; enable_ideasupport=yes enable_onlylibs=yes enable_stdcpp_replacement=yes fi # Check whether --enable-niftisupport was given. if test "${enable_niftisupport+set}" = set; then : enableval=$enable_niftisupport; enable_niftisupport="$enableval" fi # Check whether --enable-vtksupport was given. if test "${enable_vtksupport+set}" = set; then : enableval=$enable_vtksupport; enable_vtksupport="$enableval" fi # Check whether --enable-dcmtksupport was given. if test "${enable_dcmtksupport+set}" = set; then : enableval=$enable_dcmtksupport; enable_dcmtksupport="$enableval" fi # Check whether --enable-pngsupport was given. if test "${enable_pngsupport+set}" = set; then : enableval=$enable_pngsupport; enable_pngsupport="$enableval" fi # Check whether --with-qt-dir was given. if test "${with_qt_dir+set}" = set; then : withval=$with_qt_dir; with_qtdir=$withval fi # Check whether --with-extra-include-base was given. if test "${with_extra_include_base+set}" = set; then : withval=$with_extra_include_base; extra_include_base=$withval else extra_include_base="/usr/include" fi # Check whether --with-extra-build-cxxflags was given. if test "${with_extra_build_cxxflags+set}" = set; then : withval=$with_extra_build_cxxflags; extra_cxxflags=$withval fi # Check whether --with-extra-build-ldflags was given. if test "${with_extra_build_ldflags+set}" = set; then : withval=$with_extra_build_ldflags; extra_ldflags=$withval fi # Check whether --with-extra-odinseq-include-path was given. if test "${with_extra_odinseq_include_path+set}" = set; then : withval=$with_extra_odinseq_include_path; extra_odinseq_includes=$withval fi # Check whether --with-lapack-libname was given. if test "${with_lapack_libname+set}" = set; then : withval=$with_lapack_libname; lapack_libname=$withval else lapack_libname="lapack" fi # Check whether --with-editor was given. if test "${with_editor+set}" = set; then : withval=$with_editor; initial_editor=$withval else initial_editor="/usr/bin/sensible-editor" fi # Check whether --with-browser was given. if test "${with_browser+set}" = set; then : withval=$with_browser; initial_browser=$withval else initial_browser="/usr/bin/sensible-browser" fi CXXFLAGS_CACHE="$CXXFLAGS" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler works" >&5 $as_echo_n "checking whether the C++ compiler works... " >&6; } ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi if test -z "$ac_file"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C++ compiler cannot create executables See \`config.log' for more details" "$LINENO" 5 ; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler default output file name" >&5 $as_echo_n "checking for C++ compiler default output file name... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 $as_echo "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 $as_echo_n "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest conftest$ac_cv_exeext { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 $as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 $as_echo_n "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot run C++ compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5 ; } fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 $as_echo "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 $as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5 ; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 $as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" am_make=${MAKE-make} cat > confinc << 'END' am__doit: @echo this is the am__doit target .PHONY: am__doit END # If we don't find an include directive, just comment out the code. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 $as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= _am_result=none # First try GNU make style include. echo "include confinc" > confmf # Ignore all kinds of additional output from `make'. case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=include am__quote= _am_result=GNU ;; esac # Now try BSD make style include. if test "$am__include" = "#"; then echo '.include "confinc"' > confmf case `$am_make -s -f confmf 2> /dev/null` in #( *the\ am__doit\ target*) am__include=.include am__quote="\"" _am_result=BSD ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 $as_echo "$_am_result" >&6; } rm -f confinc confmf # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test "x$enable_debug" = "xyes" ; then if test "x$enable_ideasupport" = "xyes" ; then CXXFLAGS="-O2" else CXXFLAGS="-O2 -g -Wall" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler accepts debug flag(s) $CXXFLAGS" >&5 $as_echo_n "checking whether compiler accepts debug flag(s) $CXXFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {return 0;} _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; EXTRA_CXXFLAGS="$CXXFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext else CXXFLAGS="-O3 -fno-tree-vectorize" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler accepts release flag(s) $CXXFLAGS" >&5 $as_echo_n "checking whether compiler accepts release flag(s) $CXXFLAGS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() {return 0;} _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; EXTRA_CXXFLAGS="$CXXFLAGS" else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi CXXFLAGS="$EXTRA_CXXFLAGS $CXXFLAGS_CACHE" for ac_prog in gdb do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_GDB+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$GDB"; then ac_cv_prog_GDB="$GDB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_GDB="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi GDB=$ac_cv_prog_GDB if test -n "$GDB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GDB" >&5 $as_echo "$GDB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$GDB" && break done for ac_prog in xterm do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_XTERM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$XTERM"; then ac_cv_prog_XTERM="$XTERM" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_XTERM="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi XTERM=$ac_cv_prog_XTERM if test -n "$XTERM"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $XTERM" >&5 $as_echo "$XTERM" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$XTERM" && break done # Check whether --enable-shared was given. if test "${enable_shared+set}" = set; then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS="$lt_save_ifs" ;; esac else enable_shared=yes fi # Check whether --enable-static was given. if test "${enable_static+set}" = set; then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS="$lt_save_ifs" ;; esac else enable_static=no fi case `pwd` in *\ * | *\ *) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 $as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.2.6b' macro_revision='1.3017' ltmain="$ac_aux_dir/ltmain.sh" # Make sure we can run config.sub. $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 $as_echo_n "checking build system type... " >&6; } if test "${ac_cv_build+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 $as_echo "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 $as_echo_n "checking host system type... " >&6; } if test "${ac_cv_host+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 $as_echo "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 $as_echo "$CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 $as_echo "$ac_ct_CC" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5 ; } # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 $as_echo "$ac_cv_c_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 $as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes else CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : else ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 $as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO"; then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 $as_echo "none needed" >&6; } ;; xno) { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 $as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 $as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac if test "x$ac_cv_prog_cc_c89" != xno; then : fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu depcc="$CC" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 $as_echo "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 $as_echo_n "checking for a sed that does not truncate output... " >&6; } if test "${ac_cv_path_SED+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 $as_echo "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 $as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 $as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 $as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 $as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 $as_echo_n "checking for fgrep... " >&6; } if test "${ac_cv_path_FGREP+set}" = set; then : $as_echo_n "(cached) " >&6 else if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in fgrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" $as_echo 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 $as_echo "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test "${lt_cv_path_NM+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM="$NM" else lt_nm_to_check="${ac_tool_prefix}nm" if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. tmp_nm="$ac_dir/$lt_tmp_nm" if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then # Check to see if the nm accepts a BSD-compat flag. # Adding the `sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in */dev/null* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS="$lt_save_ifs" done : ${lt_cv_path_NM=no} fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 $as_echo "$lt_cv_path_NM" >&6; } if test "$lt_cv_path_NM" != "no"; then NM="$lt_cv_path_NM" else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$ac_tool_prefix"; then for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 $as_echo "$DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in "dumpbin -symbols" "link -dump -symbols" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 $as_echo "$ac_ct_DUMPBIN" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi if test "$DUMPBIN" != ":"; then NM="$DUMPBIN" fi fi test -z "$NM" && NM=nm { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 $as_echo_n "checking the name lister ($NM) interface... " >&6; } if test "${lt_cv_nm_interface+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:5622: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:5625: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:5628: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 $as_echo "$lt_cv_nm_interface" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 $as_echo_n "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 $as_echo "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 $as_echo_n "checking the maximum length of command line arguments... " >&6; } if test "${lt_cv_sys_max_cmd_len+set}" = set; then : $as_echo_n "(cached) " >&6 else i=0 teststring="ABCD" case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8 ; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ = "XX$teststring$teststring"; } >/dev/null 2>&1 && test $i != 17 # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n $lt_cv_sys_max_cmd_len ; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 $as_echo "$lt_cv_sys_max_cmd_len" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 $as_echo "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 $as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } # Try some XSI features xsi_shell=no ( _lt_dummy="a/b/c" test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ = c,a/b,, \ && eval 'test $(( 1 + 1 )) -eq 2 \ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ && xsi_shell=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 $as_echo "$xsi_shell" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 $as_echo_n "checking whether the shell understands \"+=\"... " >&6; } lt_shell_append=no ( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ >/dev/null 2>&1 \ && lt_shell_append=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 $as_echo "$lt_shell_append" >&6; } if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 $as_echo_n "checking for $LD option to reload object files... " >&6; } if test "${lt_cv_ld_reload_flag+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_reload_flag='-r' fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 $as_echo "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in darwin*) if test "$GCC" = yes; then reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 $as_echo "$OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OBJDUMP="objdump" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 $as_echo "$ac_ct_OBJDUMP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 $as_echo_n "checking how to recognize dependent libraries... " >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # `unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # which responds to the $file_magic_cmd with a given extended regex. # If you have `file' or equivalent on your system and you're not sure # whether `pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='/usr/bin/file -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; gnu*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=/usr/bin/file lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; esac fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 $as_echo "$lt_cv_deplibs_check_method" >&6; } file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 $as_echo "$AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_AR"; then ac_ct_AR=$AR # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_AR+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 $as_echo "$ac_ct_AR" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi else AR="$ac_cv_prog_AR" fi test -z "$AR" && AR=ar test -z "$AR_FLAGS" && AR_FLAGS=cru if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 $as_echo "$STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 $as_echo "$ac_ct_STRIP" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 $as_echo "$RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 $as_echo "$ac_ct_RANLIB" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" fi # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then : $as_echo_n "(cached) " >&6 else # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test "$host_cpu" = ia64; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function # and D for any global variable. # Also find C++ and __fastcall symbols from MSVC++, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ " {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ " s[1]~/^[@?]/{print s[1], s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ const struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_save_LIBS="$LIBS" lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" CFLAGS="$lt_save_CFLAGS" else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 $as_echo "failed" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 $as_echo "ok" >&6; } fi # Check whether --enable-libtool-lock was given. if test "${enable_libtool_lock+set}" = set; then : enableval=$enable_libtool_lock; fi test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" ;; *ELF-64*) HPUX_IA64_MODE="64" ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out which ABI we are using. echo '#line 6834 "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `/usr/bin/file conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; ppc64-*linux*|powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; ppc*-*linux*|powerpc*-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 $as_echo_n "checking whether the C compiler needs -belf... " >&6; } if test "${lt_cv_cc_needs_belf+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_cc_needs_belf=yes else lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 $as_echo "$lt_cv_cc_needs_belf" >&6; } if test x"$lt_cv_cc_needs_belf" != x"yes"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS="$SAVE_CFLAGS" fi ;; sparc*-*solaris*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `/usr/bin/file conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) LD="${LD-ld} -m elf64_sparc" ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks="$enable_libtool_lock" case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_DSYMUTIL+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 $as_echo "$DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 $as_echo "$ac_ct_DSYMUTIL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_NMEDIT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 $as_echo "$NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_NMEDIT="nmedit" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 $as_echo "$ac_ct_NMEDIT" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 $as_echo "$LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_LIPO="lipo" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 $as_echo "$ac_ct_LIPO" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 $as_echo "$OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL="otool" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 $as_echo "$ac_ct_OTOOL" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_OTOOL64+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 $as_echo "$OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_OTOOL64="otool64" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 $as_echo "$ac_ct_OTOOL64" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 $as_echo_n "checking for -single_module linker flag... " >&6; } if test "${lt_cv_apple_cc_single_mod+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_apple_cc_single_mod=no if test -z "${LT_MULTI_MODULE}"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 $as_echo "$lt_cv_apple_cc_single_mod" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } if test "${lt_cv_ld_exported_symbols_list+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_cv_ld_exported_symbols_list=yes else lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; darwin*) # darwin 5.x on # if running on 10.5 or later, the deployment target defaults # to the OS version, if on x86, and 10.4, the deployment # target defaults to 10.4. Don't you love it? case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in 10.0,*86*-darwin8*|10.0,*-darwin[91]*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; 10.[012]*) _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; 10.*) _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test "$lt_cv_apple_cc_single_mod" = "yes"; then _lt_dar_single_mod='$single_module' fi if test "$lt_cv_ld_exported_symbols_list" = "yes"; then _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' fi if test "$DSYMUTIL" != ":"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 $as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 $as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5 ; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 $as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO"; then : ac_cv_header_stdc=yes else ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : : else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF if ac_fn_c_try_run "$LINENO"; then : else ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 $as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then $as_echo "#define STDC_HEADERS 1" >>confdefs.h fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default " if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in dlfcn.h do : ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_DLFCN_H 1 _ACEOF fi done ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 $as_echo "$CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 $as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 $as_echo "$ac_ct_CXX" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" $as_echo "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5 $as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; } if test "${ac_cv_cxx_compiler_gnu+set}" = set; then : $as_echo_n "(cached) " >&6 else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_compiler_gnu=yes else ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 $as_echo "$ac_cv_cxx_compiler_gnu" >&6; } if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+set} ac_save_CXXFLAGS=$CXXFLAGS { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 $as_echo_n "checking whether $CXX accepts -g... " >&6; } if test "${ac_cv_prog_cxx_g+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes else CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : else ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 $as_echo "$ac_cv_prog_cxx_g" >&6; } if test "$ac_test_CXXFLAGS" = set; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu depcc="$CXX" am_compiler_list= { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 $as_echo_n "checking dependency style of $depcc... " >&6; } if test "${am_cv_CXX_dependencies_compiler_type+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named `D' -- because `-MD' means `put the output # in D'. mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with # Solaris 8's {/usr,}/bin/sh. touch sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with `-c' and `-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle `-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # after this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvisualcpp | msvcmsys) # This compiler won't grok `-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 $as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 $as_echo_n "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test "${ac_cv_prog_CXXCPP+set}" = set; then : $as_echo_n "(cached) " >&6 else # Double quotes because CXXCPP needs to be expanded for CXXCPP in "$CXX -E" "/lib/cpp" do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 $as_echo "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : else # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # Broken: success on invalid input. continue else # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;} _lt_caught_CXX_error=yes; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu else _lt_caught_CXX_error=yes fi # Set options enable_dlopen=no enable_win32_dll=no # Check whether --with-pic was given. if test "${with_pic+set}" = set; then : withval=$with_pic; pic_mode="$withval" else pic_mode=default fi test -z "$pic_mode" && pic_mode=default # Check whether --enable-fast-install was given. if test "${enable_fast_install+set}" = set; then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," for pkg in $enableval; do IFS="$lt_save_ifs" if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS="$lt_save_ifs" ;; esac else enable_fast_install=yes fi # This can be used to rebuild libtool when needed LIBTOOL_DEPS="$ltmain" # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 $as_echo_n "checking for objdir... " >&6; } if test "${lt_cv_objdir+set}" = set; then : $as_echo_n "(cached) " >&6 else rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 $as_echo "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir cat >>confdefs.h <<_ACEOF #define LT_OBJDIR "$lt_cv_objdir/" _ACEOF case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Sed substitution that helps us do robust quoting. It backslashifies # metacharacters that are still active within double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a with_gnu_ld="$lt_cv_prog_gnu_ld" old_CC="$CC" old_CFLAGS="$CFLAGS" # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/${ac_tool_prefix}file; then lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 $as_echo_n "checking for file... " >&6; } if test "${lt_cv_path_MAGIC_CMD+set}" = set; then : $as_echo_n "(cached) " >&6 else case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD="$MAGIC_CMD" lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/file; then lt_cv_path_MAGIC_CMD="$ac_dir/file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS="$lt_save_ifs" MAGIC_CMD="$lt_save_MAGIC_CMD" ;; esac fi MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if test -n "$MAGIC_CMD"; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 $as_echo "$MAGIC_CMD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC="$CC" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test "$GCC" = yes; then lt_prog_compiler_no_builtin_flag=' -fno-builtin' { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:8825: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:8829: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 $as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='${wl}-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in # old Intel for x86_64 which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl*) # IBM XL C 8.0/Fortran 10.1 on PPC lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Sun\ F*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec ;then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 $as_echo "$lt_prog_compiler_pic" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test "${lt_cv_prog_compiler_pic_works+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:9164: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:9168: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 $as_echo "$lt_cv_prog_compiler_pic_works" >&6; } if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test "${lt_cv_prog_compiler_static_works+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 $as_echo "$lt_cv_prog_compiler_static_works" >&6; } if test x"$lt_cv_prog_compiler_static_works" = xyes; then : else lt_prog_compiler_static= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:9269: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:9273: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:9324: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:9328: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 $as_echo "$lt_cv_prog_compiler_c_o" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++. if test "$GCC" != yes; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++) with_gnu_ld=yes ;; openbsd*) with_gnu_ld=no ;; linux* | k*bsd*-gnu) link_all_deplibs=no ;; esac ld_shlibs=yes if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec='${wl}--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.9.1, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to modify your PATH *** so that a non-GNU linker is found, and then restart. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test "$host_os" = linux-dietlibc; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test "$tmp_diet" = no then tmp_addflag= tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; esac case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi case $cc_basename in xlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec= hardcode_libdir_flag_spec_ld='-rpath $libdir' archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test "$ld_shlibs" = no; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='${wl}-f,' if test "$GCC" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi link_all_deplibs=no else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=".dll" # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported whole_archive_flag_spec='' link_all_deplibs=yes allow_undefined_flag="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; freebsd1*) ld_shlibs=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test "$GCC" = yes; then archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='${wl}-E' ;; hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_flag_spec_ld='+b $libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='${wl}-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test "$GCC" = yes; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo(void) {} _ACEOF if ac_fn_c_try_link "$LINENO"; then : archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS="$save_LDFLAGS" else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' export_dynamic_flag_spec='${wl}-E' else case $host_os in openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-R$libdir' ;; *) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='${wl}-rpath,$libdir' ;; esac fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' ;; osf3*) if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test "$GCC" = yes; then allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test "$GCC" = yes; then wlarc='${wl}' archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='${wl}' archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. GCC discards it without `$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test "$GCC" = yes; then whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test "x$host_vendor" = xsequent; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='${wl}-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='${wl}-z,text' allow_undefined_flag='${wl}-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='${wl}-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' if test "$GCC" = yes; then archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test x$host_vendor = xsni; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='${wl}-Blargedynsym' ;; esac fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 $as_echo "$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then archive_cmds_need_lc=no else archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 $as_echo "$archive_cmds_need_lc" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } if test "$GCC" = yes; then case $host_os in darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; *) lt_awk_arg="/^libraries:/" ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` else lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary. lt_tmp_lt_search_path_spec= lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path/$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" else test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' BEGIN {RS=" "; FS="/|\n";} { lt_foo=""; lt_count=0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo="/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test "X$hardcode_automatic" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && test "$hardcode_minus_L" != no; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 $as_echo "$hardcode_action" >&6; } if test "$hardcode_action" = relink || test "$inherit_rpath" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi if test "x$enable_dlopen" != xyes; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen="load_add_on" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen="LoadLibrary" lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen="dlopen" lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else lt_cv_dlopen="dyld" lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = x""yes; then : lt_cv_dlopen="shl_load" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 $as_echo_n "checking for shl_load in -ldld... " >&6; } if test "${ac_cv_lib_dld_shl_load+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char shl_load (); int main () { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_shl_load=yes else ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 $as_echo "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = x""yes; then : lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = x""yes; then : lt_cv_dlopen="dlopen" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 $as_echo_n "checking for dlopen in -lsvld... " >&6; } if test "${ac_cv_lib_svld_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_svld_dlopen=yes else ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 $as_echo "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = x""yes; then : lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 $as_echo_n "checking for dld_link in -ldld... " >&6; } if test "${ac_cv_lib_dld_dld_link+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dld_link (); int main () { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO"; then : ac_cv_lib_dld_dld_link=yes else ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 $as_echo "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = x""yes; then : lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi fi fi fi fi fi ;; esac if test "x$lt_cv_dlopen" != xno; then enable_dlopen=yes else enable_dlopen=no fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS="$CPPFLAGS" test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 $as_echo_n "checking whether a program can dlopen itself... " >&6; } if test "${lt_cv_dlopen_self+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 11708 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 $as_echo "$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } if test "${lt_cv_dlopen_self_static+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$cross_compiling" = yes; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line 11804 "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif void fnord() { int i=42;} int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 $as_echo "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS="$save_CPPFLAGS" LDFLAGS="$save_LDFLAGS" LIBS="$save_LIBS" ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 $as_echo_n "checking whether stripping libraries is possible... " >&6; } if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else # FIXME - insert some real tests, host_os isn't really good enough case $host_os in darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" old_striplib="$STRIP -S" { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi ;; *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } ;; esac fi # Report which library types will actually be built { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 $as_echo_n "checking if libtool supports shared libraries... " >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 $as_echo "$can_build_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 $as_echo_n "checking whether to build shared libraries... " >&6; } test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 $as_echo "$enable_shared" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 $as_echo_n "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 $as_echo "$enable_static" >&6; } fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu CC="$lt_save_CC" ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test "$_lt_caught_CXX_error" != yes; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} compiler=$CC compiler_CXX=$CC for cc_temp in $compiler""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test "$GXX" = yes; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test "$GXX" = yes; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test "${with_gnu_ld+set}" = set; then : withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes else with_gnu_ld=no fi ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 $as_echo_n "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD="$ac_prog" ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test "$with_gnu_ld" = yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 $as_echo_n "checking for GNU ld... " >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 $as_echo_n "checking for non-GNU ld... " >&6; } fi if test "${lt_cv_path_LD+set}" = set; then : $as_echo_n "(cached) " >&6 else if test -z "$LD"; then lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS="$lt_save_ifs" test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 $as_echo "$LD" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then : $as_echo_n "(cached) " >&6 else # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 $as_echo "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test "$with_gnu_ld" = yes; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='${wl}' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag="" else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='${wl}-f,' if test "$GXX" = yes; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`${CC} -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then shared_flag="$shared_flag "'${wl}-G' fi else # not using gcc if test "$host_cpu" = ia64; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' fi fi fi export_dynamic_flag_spec_CXX='${wl}-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test "$aix_use_runtimelinking" = yes; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag_CXX='-berok' # Determine the default libpath from the value encoded in an empty # executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/ p } }' aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes # This is similar to how AIX traditionally builds its shared # libraries. archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes allow_undefined_flag_CXX="$_lt_dar_allow_undefined" case $cc_basename in ifort*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test "$_lt_dar_can_shared" = "yes"; then output_verbose_link_cmd=echo archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" if test "$lt_cv_apple_cc_single_mod" != "yes"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi else ld_shlibs_CXX=no fi ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd[12]*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; gnu*) ;; hpux9*) hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test "$GXX" = yes; then if test "$with_gnu_ld" = no; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' else archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5]* | *pgcpp\ [1-5]*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; *) # Version 6 will use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; xl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test "x$supports_anon_versioning" = xyes; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd2*) # C++ shared libraries are fairly broken ld_shlibs_CXX=no ;; openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='${wl}-E' whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' fi output_verbose_link_cmd=echo else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed' ;; *) if test "$GXX" = yes && test "$with_gnu_ld" = no; then allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test "$GXX" = yes && test "$with_gnu_ld" = no; then no_undefined_flag_CXX=' ${wl}-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' else # g++ 2.7 appears to require `-G' NOT `-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"' fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We can NOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='${wl}-z,text' allow_undefined_flag_CXX='${wl}-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='${wl}-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test $p = "-L" || test $p = "-R"; then prev=$p continue else prev= fi if test "$pre_test_object_deps_done" = no; then case $p in -L* | -R*) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX="${prev}${p}" else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX="${prev}${p}" else postdeps_CXX="${postdeps_CXX} ${prev}${p}" fi fi ;; *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test "$pre_test_object_deps_done" = no; then if test -z "$predep_objects_CXX"; then predep_objects_CXX="$p" else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX="$p" else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; linux*) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; solaris*) case $cc_basename in CC*) # The more standards-conforming stlport4 library is # incompatible with the Cstd library. Avoid specifying # it if it's in CXXFLAGS. Ignore libCrun as # -library=stlport4 depends on it. case " $CXX $CXXFLAGS " in *" -library=stlport4 "*) solaris_use_stlport4=yes ;; esac # Adding this requires a known-good setup of shared libraries for # Sun compiler versions before 5.6, else PIC objects from an old # archive will be linked into the output, leading to subtle bugs. if test "$solaris_use_stlport4" != yes; then postdeps_CXX='-library=Cstd -library=Crun' fi ;; esac ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 $as_echo_n "checking for $compiler option to produce PIC... " >&6; } # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the `-m68020' flag to GCC prevents building anything better, # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64 which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC*) # IBM XL 8.0 on PPC lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | sed 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5 $as_echo "$lt_prog_compiler_pic_CXX" >&6; } # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13760: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:13764: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS="$save_LDFLAGS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 $as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then : else lt_prog_compiler_static_CXX= fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13859: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:13863: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then : $as_echo_n "(cached) " >&6 else lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:13911: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:13915: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 $as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 $as_echo_n "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 $as_echo "$hard_links" >&6; } if test "$hard_links" = no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 $as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 $as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw* | cegcc*) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' ;; linux* | k*bsd*-gnu) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 $as_echo "$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test "$enable_shared" = yes && test "$GCC" = yes; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then archive_cmds_need_lc_CXX=no else archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc_CXX" >&5 $as_echo "$archive_cmds_need_lc_CXX" >&6; } ;; esac fi ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 $as_echo_n "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=".so" postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='${libname}${release}${shared_ext}$major' ;; aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no hardcode_into_libs=yes if test "$host_cpu" = ia64; then # AIX 5 supports IA64 library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line `#! .'. This would cause the generated library to # depend on `.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # AIX (on Power*) has no versioning support, so currently we can not hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. if test "$aix_use_runtimelinking" = yes; then # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' else # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='${libname}${release}.a $libname.a' soname_spec='${libname}${release}${shared_ext}$major' fi shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='${libname}${shared_ext}' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=".dll" need_version=no need_lib_prefix=no case $GCC,$host_os in yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \${file}`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH printed by # mingw gcc, but we are running on Cygwin. Gcc prints its search # path with ; separators, and with drive letters. We can handle the # drive letters (cygwin fileutils understands them), so leave them, # especially as we might pass files found there to a mingw objdump, # which wouldn't understand a cygwinified path. Ahh. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' ;; esac ;; *) library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' ;; esac dynamic_linker='Win32 ld.exe' # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd1*) dynamic_linker=no ;; freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[123]*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; gnu*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' if test "X$HPUX_IA64_MODE" = X32; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" fi sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555. postinstall_cmds='chmod 555 $lib' ;; interix[3-9]*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test "$lt_cv_prog_gnu_ld" = yes; then version_type=linux else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; # This must be Linux ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd*) version_type=sunos sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in openbsd3.3 | openbsd3.3.*) need_version=yes ;; *) need_version=no ;; esac library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then case $host_os in openbsd2.[89] | openbsd2.[89].*) shlibpath_overrides_runpath=no ;; *) shlibpath_overrides_runpath=yes ;; esac else shlibpath_overrides_runpath=yes fi ;; os2*) libname_spec='$name' shrext_cmds=".dll" need_lib_prefix=no library_names_spec='$libname${shared_ext} $libname.a' dynamic_linker='OS/2 ld.exe' shlibpath_var=LIBPATH ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='${libname}${release}${shared_ext}$major' library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test "$with_gnu_ld" = yes; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec ;then version_type=linux library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' soname_spec='$libname${shared_ext}.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=freebsd-elf need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test "$with_gnu_ld" = yes; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 $as_echo "$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test "$GCC" = yes; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" fi if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 $as_echo_n "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test "X$hardcode_automatic_CXX" = "Xyes" ; then # We can hardcode non-existent directories. if test "$hardcode_direct_CXX" != no && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no && test "$hardcode_minus_L_CXX" != no; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 $as_echo "$hardcode_action_CXX" >&6; } if test "$hardcode_action_CXX" = relink || test "$inherit_rpath_CXX" = yes; then # Fast installation is not supported enable_fast_install=no elif test "$shlibpath_overrides_runpath" = yes || test "$enable_shared" = no; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test "$_lt_caught_CXX_error" != yes ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_config_commands="$ac_config_commands libtool" # Only expand once: CXXFLAGS_EXPORT="$CXXFLAGS" CPPFLAGS_EXPORT="$CPPFLAGS" LDFLAGS_EXPORT="$LDFLAGS" CXXFLAGS="$extra_cxxflags $CXXFLAGS" CPPFLAGS="$extra_cxxflags $CPPFLAGS" LDFLAGS="$extra_ldflags $LDFLAGS" case $host in *apple*) macos=yes ;; esac if test "x$enable_onlylibs" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Discarding library linking due to --enable-only-corelibs" >&5 $as_echo "$as_me: Discarding library linking due to --enable-only-corelibs" >&6;} else LIBS_RETAIN="$LIBS" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sin in -lm" >&5 $as_echo_n "checking for sin in -lm... " >&6; } if test "${ac_cv_lib_m_sin+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lm $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char sin (); int main () { return sin (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_m_sin=yes else ac_cv_lib_m_sin=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_sin" >&5 $as_echo "$ac_cv_lib_m_sin" >&6; } if test "x$ac_cv_lib_m_sin" = x""yes; then : LIBS="-lm $LIBS"; BASELIBS="-lm $BASELIBS" fi valid_dl=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 $as_echo_n "checking for dlopen in -ldl... " >&6; } if test "${ac_cv_lib_dl_dlopen+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char dlopen (); int main () { return dlopen (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dl_dlopen=yes else ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 $as_echo "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = x""yes; then : LIBS="-ldl $LIBS"; BASELIBS="-ldl $BASELIBS" else valid_dl=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default" if test "x$ac_cv_header_dlfcn_h" = x""yes; then : else valid_dl=no fi valid_pthread=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_create in -lpthread" >&5 $as_echo_n "checking for pthread_create in -lpthread... " >&6; } if test "${ac_cv_lib_pthread_pthread_create+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpthread $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char pthread_create (); int main () { return pthread_create (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_pthread_pthread_create=yes else ac_cv_lib_pthread_pthread_create=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_create" >&5 $as_echo "$ac_cv_lib_pthread_pthread_create" >&6; } if test "x$ac_cv_lib_pthread_pthread_create" = x""yes; then : LIBS="-lpthread $LIBS"; BASELIBS="-lpthread $BASELIBS" else valid_pthread=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "pthread.h" "ac_cv_header_pthread_h" "$ac_includes_default" if test "x$ac_cv_header_pthread_h" = x""yes; then : else valid_pthread=no fi valid_libz=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lz" >&5 $as_echo_n "checking for main in -lz... " >&6; } if test "${ac_cv_lib_z_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_z_main=yes else ac_cv_lib_z_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_main" >&5 $as_echo "$ac_cv_lib_z_main" >&6; } if test "x$ac_cv_lib_z_main" = x""yes; then : LIBS="-lz $LIBS"; DATALIBS="-lz $DATALIBS" else valid_libz=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" if test "x$ac_cv_header_zlib_h" = x""yes; then : else valid_libz=no fi valid_gsl=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgslcblas" >&5 $as_echo_n "checking for main in -lgslcblas... " >&6; } if test "${ac_cv_lib_gslcblas_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgslcblas $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gslcblas_main=yes else ac_cv_lib_gslcblas_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gslcblas_main" >&5 $as_echo "$ac_cv_lib_gslcblas_main" >&6; } if test "x$ac_cv_lib_gslcblas_main" = x""yes; then : LIBS="-lgslcblas $LIBS"; BASELIBS="-lgslcblas $BASELIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gsl_multifit_fdfsolver_iterate in -lgsl" >&5 $as_echo_n "checking for gsl_multifit_fdfsolver_iterate in -lgsl... " >&6; } if test "${ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgsl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char gsl_multifit_fdfsolver_iterate (); int main () { return gsl_multifit_fdfsolver_iterate (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate=yes else ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate" >&5 $as_echo "$ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate" >&6; } if test "x$ac_cv_lib_gsl_gsl_multifit_fdfsolver_iterate" = x""yes; then : BASELIBS="-lgsl $BASELIBS" else valid_gsl=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "gsl/gsl_multifit_nlin.h" "ac_cv_header_gsl_gsl_multifit_nlin_h" "$ac_includes_default" if test "x$ac_cv_header_gsl_gsl_multifit_nlin_h" = x""yes; then : else valid_gsl=no fi if test "x$valid_gsl" = "xno" ; then as_fn_error $? "Please install the GNU Scientific Library (There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://www.gnu.org/software/gsl)" "$LINENO" 5 fi if test "x$macos" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using vecLib for lapack support" >&5 $as_echo "$as_me: Using vecLib for lapack support" >&6;} valid_lapack=yes lapack_libname="vecLib" else if test "$lapack_libname" = "lapack" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for i_indx in -lg2c" >&5 $as_echo_n "checking for i_indx in -lg2c... " >&6; } if test "${ac_cv_lib_g2c_i_indx+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lg2c $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char i_indx (); int main () { return i_indx (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_g2c_i_indx=yes else ac_cv_lib_g2c_i_indx=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_g2c_i_indx" >&5 $as_echo "$ac_cv_lib_g2c_i_indx" >&6; } if test "x$ac_cv_lib_g2c_i_indx" = x""yes; then : DATALIBS="-lg2c $DATALIBS"; LIBS="-lg2c $LIBS" fi fi if test "$lapack_libname" = "acml" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lacml_mv" >&5 $as_echo_n "checking for main in -lacml_mv... " >&6; } if test "${ac_cv_lib_acml_mv_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lacml_mv $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_acml_mv_main=yes else ac_cv_lib_acml_mv_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_acml_mv_main" >&5 $as_echo "$ac_cv_lib_acml_mv_main" >&6; } if test "x$ac_cv_lib_acml_mv_main" = x""yes; then : DATALIBS="-lacml_mv $DATALIBS"; LIBS="-lacml_mv $LIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lgfortran" >&5 $as_echo_n "checking for main in -lgfortran... " >&6; } if test "${ac_cv_lib_gfortran_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgfortran $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_gfortran_main=yes else ac_cv_lib_gfortran_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_gfortran_main" >&5 $as_echo "$ac_cv_lib_gfortran_main" >&6; } if test "x$ac_cv_lib_gfortran_main" = x""yes; then : DATALIBS="-lgfortran $DATALIBS"; LIBS="-lgfortran $LIBS" fi thread_safe_lapack=yes fi valid_lapack=no as_ac_Lib=`$as_echo "ac_cv_lib_$lapack_libname''_cgelss_" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cgelss_ in -l$lapack_libname" >&5 $as_echo_n "checking for cgelss_ in -l$lapack_libname... " >&6; } if eval "test \"\${$as_ac_Lib+set}\"" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-l$lapack_libname $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char cgelss_ (); int main () { return cgelss_ (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : DATALIBS="-l${lapack_libname} $DATALIBS"; valid_lapack=yes fi if test "x$valid_lapack" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: LAPACK not found (using slower GSL linear algebra instead)" >&5 $as_echo "$as_me: WARNING: LAPACK not found (using slower GSL linear algebra instead)" >&2;} fi fi valid_blitz=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lblitz" >&5 $as_echo_n "checking for main in -lblitz... " >&6; } if test "${ac_cv_lib_blitz_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lblitz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_blitz_main=yes else ac_cv_lib_blitz_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blitz_main" >&5 $as_echo "$ac_cv_lib_blitz_main" >&6; } if test "x$ac_cv_lib_blitz_main" = x""yes; then : DATALIBS="-lblitz $DATALIBS" else valid_blitz=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "blitz/array.h" "ac_cv_header_blitz_array_h" "$ac_includes_default" if test "x$ac_cv_header_blitz_array_h" = x""yes; then : else valid_blitz=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "blitz/tinyvec-et.h" "ac_cv_header_blitz_tinyvec_et_h" "$ac_includes_default" if test "x$ac_cv_header_blitz_tinyvec_et_h" = x""yes; then : else valid_blitz=no fi if test "x$valid_blitz" = "xno" ; then as_fn_error $? "Please install Blitz++ (Version 0.8 or higher) in order to use the reconstruction library (There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://www.oonumerics.org/blitz)" "$LINENO" 5 fi if test ! "x$enable_niftisupport" = "xno" ; then lib_nifti=yes if test -d ${extra_include_base}/nifti ; then all_includes="-I${extra_include_base}/nifti $all_includes" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lznz" >&5 $as_echo_n "checking for main in -lznz... " >&6; } if test "${ac_cv_lib_znz_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lznz $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_znz_main=yes else ac_cv_lib_znz_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_znz_main" >&5 $as_echo "$ac_cv_lib_znz_main" >&6; } if test "x$ac_cv_lib_znz_main" = x""yes; then : LIBS="-lznz $LIBS"; DATALIBS="-lznz $DATALIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for nifti_image_read in -lniftiio" >&5 $as_echo_n "checking for nifti_image_read in -lniftiio... " >&6; } if test "${ac_cv_lib_niftiio_nifti_image_read+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lniftiio $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char nifti_image_read (); int main () { return nifti_image_read (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_niftiio_nifti_image_read=yes else ac_cv_lib_niftiio_nifti_image_read=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_niftiio_nifti_image_read" >&5 $as_echo "$ac_cv_lib_niftiio_nifti_image_read" >&6; } if test "x$ac_cv_lib_niftiio_nifti_image_read" = x""yes; then : DATALIBS="-lniftiio $DATALIBS" else lib_nifti=no fi CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "nifti1_io.h" "ac_cv_header_nifti1_io_h" "$ac_includes_default" if test "x$ac_cv_header_nifti1_io_h" = x""yes; then : else lib_nifti=no fi CPPFLAGS="$CPPFLAGS_CACHE" if test "x$lib_nifti" = "xno" ; then if test "x$enable_niftisupport" = "xyes" ; then as_fn_error $? "libniftiio missing" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: NIFTI I/O library not found, NIFTI support will be disabled" >&5 $as_echo "$as_me: WARNING: NIFTI I/O library not found, NIFTI support will be disabled" >&2;} fi fi fi if test ! "x$enable_vtksupport" = "xno" ; then lib_vtk=yes { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lvtkIO" >&5 $as_echo_n "checking for main in -lvtkIO... " >&6; } if test "${ac_cv_lib_vtkIO_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lvtkIO $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_vtkIO_main=yes else ac_cv_lib_vtkIO_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_vtkIO_main" >&5 $as_echo "$ac_cv_lib_vtkIO_main" >&6; } if test "x$ac_cv_lib_vtkIO_main" = x""yes; then : DATALIBS="-lvtkIO $DATALIBS" else lib_vtk=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lvtkRendering" >&5 $as_echo_n "checking for main in -lvtkRendering... " >&6; } if test "${ac_cv_lib_vtkRendering_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lvtkRendering $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_vtkRendering_main=yes else ac_cv_lib_vtkRendering_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_vtkRendering_main" >&5 $as_echo "$ac_cv_lib_vtkRendering_main" >&6; } if test "x$ac_cv_lib_vtkRendering_main" = x""yes; then : VTKLIBS="-lvtkRendering $VTKLIBS" else lib_vtk=no fi for vtk_header_dir in vtk vtk-5.0 vtk-5.2 vtk-5.4 ; do if test -d ${extra_include_base}/${vtk_header_dir} ; then all_includes="-I${extra_include_base}/${vtk_header_dir} $all_includes" fi done CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" for ac_header in vtkStructuredPoints.h vtkArrowSource.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else lib_vtk=no fi done CPPFLAGS="$CPPFLAGS_CACHE" if test "x$lib_vtk" = "xno" ; then if test "x$enable_vtksupport" = "xyes" ; then as_fn_error $? "VTK library missing" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: VTK library (Version 4.4 or higher) not found, VTK support will be disabled" >&5 $as_echo "$as_me: WARNING: VTK library (Version 4.4 or higher) not found, VTK support will be disabled" >&2;} fi fi fi if test ! "x$enable_dcmtksupport" = "xno" ; then lib_dcmtk=yes if test -d ${extra_include_base}/dcmtk ; then all_includes="-I${extra_include_base}/dcmtk -I${extra_include_base}/dcmtk/dcmdata -I${extra_include_base}/dcmtk/ofstd $all_includes" fi CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" ac_fn_cxx_check_header_mongrel "$LINENO" "dcmtk/dcmdata/dcdatset.h" "ac_cv_header_dcmtk_dcmdata_dcdatset_h" "$ac_includes_default" if test "x$ac_cv_header_dcmtk_dcmdata_dcdatset_h" = x""yes; then : else lib_dcmtk=no fi ac_fn_cxx_check_header_mongrel "$LINENO" "dcmtk/dcmimgle/dcmimage.h" "ac_cv_header_dcmtk_dcmimgle_dcmimage_h" "$ac_includes_default" if test "x$ac_cv_header_dcmtk_dcmimgle_dcmimage_h" = x""yes; then : else lib_dcmtk=no fi CPPFLAGS="$CPPFLAGS_CACHE" { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lwsock32" >&5 $as_echo_n "checking for main in -lwsock32... " >&6; } if test "${ac_cv_lib_wsock32_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lwsock32 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_wsock32_main=yes else ac_cv_lib_wsock32_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_wsock32_main" >&5 $as_echo "$ac_cv_lib_wsock32_main" >&6; } if test "x$ac_cv_lib_wsock32_main" = x""yes; then : LIBS="-lwsock32 $LIBS"; DATALIBS="-lwsock32 $DATALIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lofstd" >&5 $as_echo_n "checking for main in -lofstd... " >&6; } if test "${ac_cv_lib_ofstd_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lofstd $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_ofstd_main=yes else ac_cv_lib_ofstd_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ofstd_main" >&5 $as_echo "$ac_cv_lib_ofstd_main" >&6; } if test "x$ac_cv_lib_ofstd_main" = x""yes; then : LIBS="-lofstd $LIBS"; DATALIBS="-lofstd $DATALIBS" else lib_dcmtk=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -loflog" >&5 $as_echo_n "checking for main in -loflog... " >&6; } if test "${ac_cv_lib_oflog_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-loflog $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_oflog_main=yes else ac_cv_lib_oflog_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_oflog_main" >&5 $as_echo "$ac_cv_lib_oflog_main" >&6; } if test "x$ac_cv_lib_oflog_main" = x""yes; then : LIBS="-loflog $LIBS"; DATALIBS="-loflog $DATALIBS" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldcmdata" >&5 $as_echo_n "checking for main in -ldcmdata... " >&6; } if test "${ac_cv_lib_dcmdata_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldcmdata $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dcmdata_main=yes else ac_cv_lib_dcmdata_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dcmdata_main" >&5 $as_echo "$ac_cv_lib_dcmdata_main" >&6; } if test "x$ac_cv_lib_dcmdata_main" = x""yes; then : LIBS="-ldcmdata $LIBS"; DATALIBS="-ldcmdata $DATALIBS" else lib_dcmtk=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -ldcmimgle" >&5 $as_echo_n "checking for main in -ldcmimgle... " >&6; } if test "${ac_cv_lib_dcmimgle_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ldcmimgle $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_dcmimgle_main=yes else ac_cv_lib_dcmimgle_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dcmimgle_main" >&5 $as_echo "$ac_cv_lib_dcmimgle_main" >&6; } if test "x$ac_cv_lib_dcmimgle_main" = x""yes; then : LIBS="-ldcmimgle $LIBS"; DATALIBS="-ldcmimgle $DATALIBS" else lib_dcmtk=no fi if test "x$lib_dcmtk" = "xno" ; then if test "x$enable_dcmtksupport" = "xyes" ; then as_fn_error $? "DICOMTK library missing" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: DICOMTK library not found, DICOM support will be disabled" >&5 $as_echo "$as_me: WARNING: DICOMTK library not found, DICOM support will be disabled" >&2;} fi fi fi if test ! "x$enable_pngsupport" = "xno" ; then lib_png=yes ac_fn_cxx_check_header_mongrel "$LINENO" "png.h" "ac_cv_header_png_h" "$ac_includes_default" if test "x$ac_cv_header_png_h" = x""yes; then : else lib_png=no fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for png_create_write_struct in -lpng" >&5 $as_echo_n "checking for png_create_write_struct in -lpng... " >&6; } if test "${ac_cv_lib_png_png_create_write_struct+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpng $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char png_create_write_struct (); int main () { return png_create_write_struct (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_png_png_create_write_struct=yes else ac_cv_lib_png_png_create_write_struct=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_png_png_create_write_struct" >&5 $as_echo "$ac_cv_lib_png_png_create_write_struct" >&6; } if test "x$ac_cv_lib_png_png_create_write_struct" = x""yes; then : DATALIBS="-lpng $DATALIBS" else lib_png=no fi if test "x$lib_png" = "xno" ; then if test "x$enable_pngsupport" = "xyes" ; then as_fn_error $? "libpng missing" "$LINENO" 5 else { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: PNG library not found, PNG support will be disabled" >&5 $as_echo "$as_me: WARNING: PNG library not found, PNG support will be disabled" >&2;} fi fi fi LIBS="$LIBS_RETAIN" fi for ac_header in dirent.h unistd.h time.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in sys/stat.h sys/types.h sys/wait.h sys/time.h sys/mman.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in locale.h ctype.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in signal.h setjmp.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done for ac_header in typeinfo do : ac_fn_cxx_check_header_mongrel "$LINENO" "typeinfo" "ac_cv_header_typeinfo" "$ac_includes_default" if test "x$ac_cv_header_typeinfo" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_TYPEINFO 1 _ACEOF fi done have_win32_api=yes for ac_header in windows.h direct.h io.h do : as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else have_win32_api=no fi done { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of char" >&5 $as_echo_n "checking size of char... " >&6; } if test "${ac_cv_sizeof_char+set}" = set; then : $as_echo_n "(cached) " >&6 else for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "confdefs.h" #include int main () { switch (0) case 0: case (sizeof (char) == $ac_size):; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_sizeof_char=$ac_size fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$ac_cv_sizeof_char != x ; then break; fi done fi if test x$ac_cv_sizeof_char = x ; then as_fn_error $? "cannot determine a size for char" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_char" >&5 $as_echo "$ac_cv_sizeof_char" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_CHAR $ac_cv_sizeof_char _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 $as_echo_n "checking size of short... " >&6; } if test "${ac_cv_sizeof_short+set}" = set; then : $as_echo_n "(cached) " >&6 else for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "confdefs.h" #include int main () { switch (0) case 0: case (sizeof (short) == $ac_size):; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_sizeof_short=$ac_size fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$ac_cv_sizeof_short != x ; then break; fi done fi if test x$ac_cv_sizeof_short = x ; then as_fn_error $? "cannot determine a size for short" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 $as_echo "$ac_cv_sizeof_short" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_SHORT $ac_cv_sizeof_short _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 $as_echo_n "checking size of int... " >&6; } if test "${ac_cv_sizeof_int+set}" = set; then : $as_echo_n "(cached) " >&6 else for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "confdefs.h" #include int main () { switch (0) case 0: case (sizeof (int) == $ac_size):; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_sizeof_int=$ac_size fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$ac_cv_sizeof_int != x ; then break; fi done fi if test x$ac_cv_sizeof_int = x ; then as_fn_error $? "cannot determine a size for int" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 $as_echo "$ac_cv_sizeof_int" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_INT $ac_cv_sizeof_int _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long" >&5 $as_echo_n "checking size of long... " >&6; } if test "${ac_cv_sizeof_long+set}" = set; then : $as_echo_n "(cached) " >&6 else for ac_size in 4 8 1 2 16 ; do # List sizes in rough order of prevalence. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include "confdefs.h" #include int main () { switch (0) case 0: case (sizeof (long) == $ac_size):; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_sizeof_long=$ac_size fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test x$ac_cv_sizeof_long != x ; then break; fi done fi if test x$ac_cv_sizeof_long = x ; then as_fn_error $? "cannot determine a size for long" "$LINENO" 5 fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long" >&5 $as_echo "$ac_cv_sizeof_long" >&6; } cat >>confdefs.h <<_ACEOF #define SIZEOF_LONG $ac_cv_sizeof_long _ACEOF { $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5 $as_echo_n "checking for long long int... " >&6; } if test "${ac_cv_c_long_long+set}" = set; then : $as_echo_n "(cached) " >&6 else if test "$GCC" = yes; then ac_cv_c_long_long=yes else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { long long int i; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : ac_cv_c_long_long=yes else ac_cv_c_long_long=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_long_long" >&5 $as_echo "$ac_cv_c_long_long" >&6; } if test $ac_cv_c_long_long = yes; then $as_echo "#define HAVE_LONG_LONG 1" >>confdefs.h fi for ac_func in j1 snprintf erfc acosh gettimeofday nanosleep srand read stat sysconf stat64 fopen64 open64 fseeko fseeko64 ftello ftello64 mmap64 strftime strptime do : as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ac_fn_cxx_check_func "$LINENO" "$ac_func" "$as_ac_var" if eval test \"x\$"$as_ac_var"\" = x"yes"; then : cat >>confdefs.h <<_ACEOF #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done CXXFLAGS_EXPORT="$CXXFLAGS_EXPORT $all_includes" CPPFLAGS_EXPORT="$CPPFLAGS_EXPORT $all_includes" LDFLAGS_EXPORT="$LDFLAGS_EXPORT $LIBS" if test "x$enable_onlylibs" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Discarding Qt linking due to --enable-only-corelibs" >&5 $as_echo "$as_me: Discarding Qt linking due to --enable-only-corelibs" >&6;} enable_gui=no fi if test "x$enable_gui" = "xyes" ; then if test -z $with_qtdir ; then CONF_QTDIR="$QTDIR" else CONF_QTDIR="$with_qtdir" fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking for X" >&5 $as_echo_n "checking for X... " >&6; } # Check whether --with-x was given. if test "${with_x+set}" = set; then : withval=$with_x; fi # $have_x is `yes', `no', `disabled', or empty when we do not yet know. if test "x$with_x" = xno; then # The user explicitly disabled X. have_x=disabled else case $x_includes,$x_libraries in #( *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #( *,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then : $as_echo_n "(cached) " >&6 else # One or both of the vars are not set, and there is no cached value. ac_x_includes=no ac_x_libraries=no rm -f -r conftest.dir if mkdir conftest.dir; then cd conftest.dir cat >Imakefile <<'_ACEOF' incroot: @echo incroot='${INCROOT}' usrlibdir: @echo usrlibdir='${USRLIBDIR}' libdir: @echo libdir='${LIBDIR}' _ACEOF if (export CC; ${XMKMF-xmkmf}) >/dev/null 2>/dev/null && test -f Makefile; then # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. for ac_var in incroot usrlibdir libdir; do eval "ac_im_$ac_var=\`\${MAKE-make} $ac_var 2>/dev/null | sed -n 's/^$ac_var=//p'\`" done # Open Windows xmkmf reportedly sets LIBDIR instead of USRLIBDIR. for ac_extension in a so sl dylib la dll; do if test ! -f "$ac_im_usrlibdir/libX11.$ac_extension" && test -f "$ac_im_libdir/libX11.$ac_extension"; then ac_im_usrlibdir=$ac_im_libdir; break fi done # Screen out bogus values from the imake configuration. They are # bogus both because they are the default anyway, and because # using them would break gcc on systems where it needs fixed includes. case $ac_im_incroot in /usr/include) ac_x_includes= ;; *) test -f "$ac_im_incroot/X11/Xos.h" && ac_x_includes=$ac_im_incroot;; esac case $ac_im_usrlibdir in /usr/lib | /usr/lib64 | /lib | /lib64) ;; *) test -d "$ac_im_usrlibdir" && ac_x_libraries=$ac_im_usrlibdir ;; esac fi cd .. rm -f -r conftest.dir fi # Standard set of common directories for X headers. # Check X11 before X11Rn because it is often a symlink to the current release. ac_x_header_dirs=' /usr/X11/include /usr/X11R7/include /usr/X11R6/include /usr/X11R5/include /usr/X11R4/include /usr/include/X11 /usr/include/X11R7 /usr/include/X11R6 /usr/include/X11R5 /usr/include/X11R4 /usr/local/X11/include /usr/local/X11R7/include /usr/local/X11R6/include /usr/local/X11R5/include /usr/local/X11R4/include /usr/local/include/X11 /usr/local/include/X11R7 /usr/local/include/X11R6 /usr/local/include/X11R5 /usr/local/include/X11R4 /usr/X386/include /usr/x386/include /usr/XFree86/include/X11 /usr/include /usr/local/include /usr/unsupported/include /usr/athena/include /usr/local/x11r5/include /usr/lpp/Xamples/include /usr/openwin/include /usr/openwin/share/include' if test "$ac_x_includes" = no; then # Guess where to find include files, by looking for Xlib.h. # First, try using that file with no special directory specified. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO"; then : # We can compile using X headers with no special include directory. ac_x_includes= else for ac_dir in $ac_x_header_dirs; do if test -r "$ac_dir/X11/Xlib.h"; then ac_x_includes=$ac_dir break fi done fi rm -f conftest.err conftest.i conftest.$ac_ext fi # $ac_x_includes = no if test "$ac_x_libraries" = no; then # Check for the libraries. # See if we find them without any special options. # Don't add to $LIBS permanently. ac_save_LIBS=$LIBS LIBS="-lX11 $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main () { XrmInitialize () ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : LIBS=$ac_save_LIBS # We can link X programs with no special library path. ac_x_libraries= else LIBS=$ac_save_LIBS for ac_dir in `$as_echo "$ac_x_includes $ac_x_header_dirs" | sed s/include/lib/g` do # Don't even attempt the hair of trying to link an X program! for ac_extension in a so sl dylib la dll; do if test -r "$ac_dir/libX11.$ac_extension"; then ac_x_libraries=$ac_dir break 2 fi done done fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi # $ac_x_libraries = no case $ac_x_includes,$ac_x_libraries in #( no,* | *,no | *\'*) # Didn't find X, or a directory has "'" in its name. ac_cv_have_x="have_x=no";; #( *) # Record where we found X for the cache. ac_cv_have_x="have_x=yes\ ac_x_includes='$ac_x_includes'\ ac_x_libraries='$ac_x_libraries'" esac fi ;; #( *) have_x=yes;; esac eval "$ac_cv_have_x" fi # $with_x != no if test "$have_x" != yes; then { $as_echo "$as_me:${as_lineno-$LINENO}: result: $have_x" >&5 $as_echo "$have_x" >&6; } no_x=yes else # If each of the values was on the command line, it overrides each guess. test "x$x_includes" = xNONE && x_includes=$ac_x_includes test "x$x_libraries" = xNONE && x_libraries=$ac_x_libraries # Update the cache value to reflect the command line values. ac_cv_have_x="have_x=yes\ ac_x_includes='$x_includes'\ ac_x_libraries='$x_libraries'" { $as_echo "$as_me:${as_lineno-$LINENO}: result: libraries $x_libraries, headers $x_includes" >&5 $as_echo "libraries $x_libraries, headers $x_includes" >&6; } fi if test "$x_includes" = "" ; then x_includes="." fi if test "$x_libraries" = "" ; then x_libraries="." fi if ! test "$x_includes" = "NONE" ; then all_includes="-I$x_includes $all_includes" fi if test -z $CONF_QTDIR ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Environment variable QTDIR not specified, searching for Qt:" >&5 $as_echo "$as_me: Environment variable QTDIR not specified, searching for Qt:" >&6;} qtdir_found=no for qtdir in /usr/share/qt3 /usr/share/qt4 ; do for subdir in "" "QtCore/" ; do if test "x$qtdir_found" = "xno" ; then as_ac_File=`$as_echo "ac_cv_file_$qtdir/include/${subdir}qglobal.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $qtdir/include/${subdir}qglobal.h" >&5 $as_echo_n "checking for $qtdir/include/${subdir}qglobal.h... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$qtdir/include/${subdir}qglobal.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : qtdir_found=yes; CONF_QTDIR=$qtdir fi fi done done if test "x$qtdir_found" = "xno" ; then as_fn_error $? "Qt headers not found" "$LINENO" 5 ; exit -1 fi fi as_ac_File=`$as_echo "ac_cv_file_$CONF_QTDIR/include/qglobal.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CONF_QTDIR/include/qglobal.h" >&5 $as_echo_n "checking for $CONF_QTDIR/include/qglobal.h... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$CONF_QTDIR/include/qglobal.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : QTVERSION="3" fi as_ac_File=`$as_echo "ac_cv_file_$CONF_QTDIR/include/QtCore/qglobal.h" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CONF_QTDIR/include/QtCore/qglobal.h" >&5 $as_echo_n "checking for $CONF_QTDIR/include/QtCore/qglobal.h... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$CONF_QTDIR/include/QtCore/qglobal.h"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : QTVERSION="4" fi if test -z $QTVERSION ; then as_fn_error $? "Cannot detect Qt version" "$LINENO" 5 ; exit -1 fi all_includes="-I$CONF_QTDIR/include $all_includes" if test ! -z $CONF_QTDIR ; then for extra_qt_libdir in lib lib64 ; do if test -d $CONF_QTDIR/$extra_qt_libdir ; then LDFLAGS="-L$CONF_QTDIR/$extra_qt_libdir $LDFLAGS" fi done fi lib_qt=no if test "$QTVERSION" = "3" ; then if test "x$lib_qt" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lqt-mt" >&5 $as_echo_n "checking for main in -lqt-mt... " >&6; } if test "${ac_cv_lib_qt_mt_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lqt-mt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_qt_mt_main=yes else ac_cv_lib_qt_mt_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qt_mt_main" >&5 $as_echo "$ac_cv_lib_qt_mt_main" >&6; } if test "x$ac_cv_lib_qt_mt_main" = x""yes; then : GUILIBS="-lqt-mt $GUILIBS"; lib_qt=yes; CXXFLAGS="-DQT_THREAD_SUPPORT $CXXFLAGS" fi fi if test "x$lib_qt" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lqt" >&5 $as_echo_n "checking for main in -lqt... " >&6; } if test "${ac_cv_lib_qt_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lqt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_qt_main=yes else ac_cv_lib_qt_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qt_main" >&5 $as_echo "$ac_cv_lib_qt_main" >&6; } if test "x$ac_cv_lib_qt_main" = x""yes; then : GUILIBS="-lqt $GUILIBS"; lib_qt=yes fi fi fi if test "$QTVERSION" = "4" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Qt4 subdirs:" >&5 $as_echo "$as_me: Searching for Qt4 subdirs:" >&6;} as_ac_File=`$as_echo "ac_cv_file_$CONF_QTDIR/include/QtCore/QPointF" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CONF_QTDIR/include/QtCore/QPointF" >&5 $as_echo_n "checking for $CONF_QTDIR/include/QtCore/QPointF... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$CONF_QTDIR/include/QtCore/QPointF"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : all_includes="-I$CONF_QTDIR/include/QtCore $all_includes" fi as_ac_File=`$as_echo "ac_cv_file_$CONF_QTDIR/include/QtGui/QPolygonF" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CONF_QTDIR/include/QtGui/QPolygonF" >&5 $as_echo_n "checking for $CONF_QTDIR/include/QtGui/QPolygonF... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$CONF_QTDIR/include/QtGui/QPolygonF"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : all_includes="-I$CONF_QTDIR/include/QtGui $all_includes" fi for qt4_extension in "" "4" ; do if test "x$lib_qt" = "xno" ; then as_ac_Lib=`$as_echo "ac_cv_lib_QtCore${qt4_extension}''_main" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lQtCore${qt4_extension}" >&5 $as_echo_n "checking for main in -lQtCore${qt4_extension}... " >&6; } if eval "test \"\${$as_ac_Lib+set}\"" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lQtCore${qt4_extension} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : GUILIBS="-lQtCore${qt4_extension} $GUILIBS"; lib_qtcore=yes fi if test "x$lib_qtcore" = "xyes" ; then as_ac_Lib=`$as_echo "ac_cv_lib_QtGui${qt4_extension}''_main" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lQtGui${qt4_extension}" >&5 $as_echo_n "checking for main in -lQtGui${qt4_extension}... " >&6; } if eval "test \"\${$as_ac_Lib+set}\"" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lQtGui${qt4_extension} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : GUILIBS="-lQtGui${qt4_extension} $GUILIBS"; lib_qt=yes fi fi fi done fi if test "x$lib_qt" = "xno" ; then if test -z "$extra_ldflags"; then as_fn_error $? "Qt library not found" "$LINENO" 5 ; exit -1 else { $as_echo "$as_me:${as_lineno-$LINENO}: Assuming that Qt library was specified by --extra-build-ldflags=$extra_ldflags" >&5 $as_echo "$as_me: Assuming that Qt library was specified by --extra-build-ldflags=$extra_ldflags" >&6;} fi fi as_ac_File=`$as_echo "ac_cv_file_$CONF_QTDIR/bin/moc" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CONF_QTDIR/bin/moc" >&5 $as_echo_n "checking for $CONF_QTDIR/bin/moc... " >&6; } if eval "test \"\${$as_ac_File+set}\"" = set; then : $as_echo_n "(cached) " >&6 else test "$cross_compiling" = yes && as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 if test -r "$CONF_QTDIR/bin/moc"; then eval "$as_ac_File=yes" else eval "$as_ac_File=no" fi fi eval ac_res=\$$as_ac_File { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_File"\" = x"yes"; then : QTMOC=$CONF_QTDIR/bin/moc fi if test -z $QTMOC ; then as_fn_error $? "Qt moc not found" "$LINENO" 5 ; exit -1 fi QWT_ERROR_STR="Qwt Widget Library not found. There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://qwt.sourceforge.net" qwt_lib=no if test "$QTVERSION" = "3" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lqwt" >&5 $as_echo_n "checking for main in -lqwt... " >&6; } if test "${ac_cv_lib_qwt_main+set}" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lqwt $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : ac_cv_lib_qwt_main=yes else ac_cv_lib_qwt_main=no fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_qwt_main" >&5 $as_echo "$ac_cv_lib_qwt_main" >&6; } if test "x$ac_cv_lib_qwt_main" = x""yes; then : GUILIBS="-lqwt $GUILIBS"; qwt_lib=yes fi fi if test "$QTVERSION" = "4" ; then for qwt_extension in "-qt4" "" ; do if test "x$qwt_lib" = "xno" ; then as_ac_Lib=`$as_echo "ac_cv_lib_qwt${qwt_extension}''_main" | $as_tr_sh` { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lqwt${qwt_extension}" >&5 $as_echo_n "checking for main in -lqwt${qwt_extension}... " >&6; } if eval "test \"\${$as_ac_Lib+set}\"" = set; then : $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lqwt${qwt_extension} $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO"; then : eval "$as_ac_Lib=yes" else eval "$as_ac_Lib=no" fi rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi eval ac_res=\$$as_ac_Lib { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 $as_echo "$ac_res" >&6; } if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : GUILIBS="-lqwt${qwt_extension} $GUILIBS"; qwt_lib=yes fi fi done fi if test "x$qwt_lib" = "xno" ; then as_fn_error $? "$QWT_ERROR_STR" "$LINENO" 5 ; exit -1 fi CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="$all_includes $CPPFLAGS" qwt_headers=no if test "$QTVERSION" = "4" ; then if test "x$qwt_headers" = "xno" ; then for ac_header in qwt-qt4/qwt_global.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "qwt-qt4/qwt_global.h" "ac_cv_header_qwt_qt4_qwt_global_h" "$ac_includes_default" if test "x$ac_cv_header_qwt_qt4_qwt_global_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_QWT_QT4_QWT_GLOBAL_H 1 _ACEOF qwt_headers=yes fi done fi fi if test "x$qwt_headers" = "xno" ; then for ac_header in qwt/qwt_global.h do : ac_fn_cxx_check_header_mongrel "$LINENO" "qwt/qwt_global.h" "ac_cv_header_qwt_qwt_global_h" "$ac_includes_default" if test "x$ac_cv_header_qwt_qwt_global_h" = x""yes; then : cat >>confdefs.h <<_ACEOF #define HAVE_QWT_QWT_GLOBAL_H 1 _ACEOF qwt_headers=yes fi done fi CPPFLAGS="$CPPFLAGS_CACHE" if test "x$qwt_headers" = "xno" ; then as_fn_error $? "$QWT_ERROR_STR" "$LINENO" 5 ; exit -1 fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler accepts empty template list" >&5 $as_echo_n "checking whether compiler accepts empty template list... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ template class TC{static int s;}; template<> int TC::s; int main() {return 0;} _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; empty_templ_list=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; empty_templ_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler accepts/needs self-friend classes" >&5 $as_echo_n "checking whether compiler accepts/needs self-friend classes... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ class C{friend class C;}; int main() {return 0;} _ACEOF if ac_fn_cxx_try_compile "$LINENO"; then : { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; }; self_friend_class=yes else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; }; self_friend_class=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { $as_echo "$as_me:${as_lineno-$LINENO}: ------------ Custom ODIN Configuration ------------" >&5 $as_echo "$as_me: ------------ Custom ODIN Configuration ------------" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: host=$host" >&5 $as_echo "$as_me: host=$host" >&6;} if test "x$macos" = "xyes" ; then $as_echo "#define MACOS /**/" >>confdefs.h fi if test "x$GXX" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using the GNU compiler collection" >&5 $as_echo "$as_me: Using the GNU compiler collection" >&6;} $as_echo "#define USING_GCC /**/" >>confdefs.h fi if test "x$enable_debug" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Debug compilation" >&5 $as_echo "$as_me: Debug compilation" >&6;} $as_echo "#define ODIN_DEBUG /**/" >>confdefs.h fi if test "x$enable_stdcpp_replacement" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using built-in C++ standard library" >&5 $as_echo "$as_me: Using built-in C++ standard library" >&6;} $as_echo "#define STL_REPLACEMENT /**/" >>confdefs.h $as_echo "#define STRING_REPLACEMENT /**/" >>confdefs.h $as_echo "#define STREAM_REPLACEMENT /**/" >>confdefs.h fi if test "x$enable_custom_heap" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using custom heap of size $custom_heap_size MB" >&5 $as_echo "$as_me: Using custom heap of size $custom_heap_size MB" >&6;} $as_echo "#define CUSTOM_HEAP /**/" >>confdefs.h cat >>confdefs.h <<_ACEOF #define CUSTOM_HEAP_SIZE $custom_heap_size _ACEOF fi if test "x$enable_cmdline" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Not using command line" >&5 $as_echo "$as_me: Not using command line" >&6;} $as_echo "#define NO_CMDLINE /**/" >>confdefs.h fi if test "x$enable_filehandling" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: No file handling" >&5 $as_echo "$as_me: No file handling" >&6;} $as_echo "#define NO_FILEHANDLING /**/" >>confdefs.h fi if test "x$enable_ideasupport" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: IDEA support" >&5 $as_echo "$as_me: IDEA support" >&6;} $as_echo "#define ODIN4IDEA /**/" >>confdefs.h fi if test "x$have_win32_api" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using Win32-API" >&5 $as_echo "$as_me: Using Win32-API" >&6;} $as_echo "#define USING_WIN32 /**/" >>confdefs.h fi if test "x$enable_onlylibs" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Only essential libraries" >&5 $as_echo "$as_me: Only essential libraries" >&6;} fi if test "x$enable_onlylibs" = "xyes"; then ONLY_LIBS_TRUE= ONLY_LIBS_FALSE='#' else ONLY_LIBS_TRUE='#' ONLY_LIBS_FALSE= fi if test "x$enable_gui" = "xyes" ; then $as_echo "#define GUISUPPORT /**/" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: Graphical User Interface enabled" >&5 $as_echo "$as_me: Graphical User Interface enabled" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: QTDIR:QTVERSION=${CONF_QTDIR}:${QTVERSION}" >&5 $as_echo "$as_me: QTDIR:QTVERSION=${CONF_QTDIR}:${QTVERSION}" >&6;} fi if test "x$enable_gui" = "xyes"; then GUI_ENABLED_TRUE= GUI_ENABLED_FALSE='#' else GUI_ENABLED_TRUE='#' GUI_ENABLED_FALSE= fi if test "x$enable_ideaplugin" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling IDEA drivers" >&5 $as_echo "$as_me: Compiling IDEA drivers" >&6;} PLUGIN_LIBS="$PLUGIN_LIBS odinseq_idea" $as_echo "#define IDEA_PLUGIN /**/" >>confdefs.h PLATFORMS="$PLATFORMS IDEA_n4" fi if test "x$enable_ideaplugin" = "xyes"; then IDEA_PLUGIN_TRUE= IDEA_PLUGIN_FALSE='#' else IDEA_PLUGIN_TRUE='#' IDEA_PLUGIN_FALSE= fi if test "x$enable_paravisionplugin" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling Paravision drivers" >&5 $as_echo "$as_me: Compiling Paravision drivers" >&6;} PLUGIN_LIBS="$PLUGIN_LIBS odinseq_paravision" $as_echo "#define PARAVISION_PLUGIN /**/" >>confdefs.h PLATFORMS="$PLATFORMS Paravision" fi if test "x$enable_paravisionplugin" = "xyes"; then PARAVISION_PLUGIN_TRUE= PARAVISION_PLUGIN_FALSE='#' else PARAVISION_PLUGIN_TRUE='#' PARAVISION_PLUGIN_FALSE= fi if test "x$enable_standaloneplugin" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling Standalone drivers" >&5 $as_echo "$as_me: Compiling Standalone drivers" >&6;} PLUGIN_LIBS="$PLUGIN_LIBS odinseq_standalone" $as_echo "#define STANDALONE_PLUGIN /**/" >>confdefs.h PLATFORMS="$PLATFORMS StandAlone" fi if test "x$enable_standaloneplugin" = "xyes"; then STANDALONE_PLUGIN_TRUE= STANDALONE_PLUGIN_FALSE='#' else STANDALONE_PLUGIN_TRUE='#' STANDALONE_PLUGIN_FALSE= fi if test "x$enable_epicplugin" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Compiling EPIC drivers" >&5 $as_echo "$as_me: Compiling EPIC drivers" >&6;} PLUGIN_LIBS="$PLUGIN_LIBS odinseq_epic" $as_echo "#define EPIC_PLUGIN /**/" >>confdefs.h PLATFORMS="$PLATFORMS EPIC" fi if test "x$enable_epicplugin" = "xyes"; then EPIC_PLUGIN_TRUE= EPIC_PLUGIN_FALSE='#' else EPIC_PLUGIN_TRUE='#' EPIC_PLUGIN_FALSE= fi if test "x$enable_unittest" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Unit test disabled" >&5 $as_echo "$as_me: Unit test disabled" >&6;} $as_echo "#define NO_UNIT_TEST /**/" >>confdefs.h fi if test "x$enable_threads" = "xno" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Multithreading disabled" >&5 $as_echo "$as_me: Multithreading disabled" >&6;} $as_echo "#define NO_THREADS /**/" >>confdefs.h fi if test "x$valid_dl" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using dynamic linking loader" >&5 $as_echo "$as_me: Using dynamic linking loader" >&6;} $as_echo "#define HAVE_DL /**/" >>confdefs.h fi if test "x$valid_pthread" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using POSIX threads" >&5 $as_echo "$as_me: Using POSIX threads" >&6;} $as_echo "#define HAVE_PTHREAD /**/" >>confdefs.h fi if test "x$valid_lapack" = "xyes" ; then if test "x$thread_safe_lapack" = "xyes" ; then $as_echo "#define HAVE_THREADSAFE_LAPACK /**/" >>confdefs.h tsmessage=" thread-safe" fi { $as_echo "$as_me:${as_lineno-$LINENO}: Using${tsmessage} LAPACK($lapack_libname)" >&5 $as_echo "$as_me: Using${tsmessage} LAPACK($lapack_libname)" >&6;} $as_echo "#define HAVE_LAPACK /**/" >>confdefs.h fi if test "x$valid_libz" = "xyes" ; then $as_echo "#define HAVE_LIBZ /**/" >>confdefs.h fi if test "x$valid_gsl" = "xyes" ; then $as_echo "#define HAVE_LIBGSL /**/" >>confdefs.h fi if test "x$lib_vista" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Vista support" >&5 $as_echo "$as_me: Vista support" >&6;} $as_echo "#define VISTASUPPORT /**/" >>confdefs.h fi if test "x$lib_nifti" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: NIFTI support" >&5 $as_echo "$as_me: NIFTI support" >&6;} $as_echo "#define NIFTISUPPORT /**/" >>confdefs.h fi if test "x$lib_vtk" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: VTK support" >&5 $as_echo "$as_me: VTK support" >&6;} $as_echo "#define VTKSUPPORT /**/" >>confdefs.h fi if test "x$lib_dcmtk" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: DICOM support" >&5 $as_echo "$as_me: DICOM support" >&6;} $as_echo "#define DICOMSUPPORT /**/" >>confdefs.h fi if test "x$lib_png" = "xyes" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: PNG support" >&5 $as_echo "$as_me: PNG support" >&6;} $as_echo "#define PNGSUPPORT /**/" >>confdefs.h fi if test "x$empty_templ_list" = "xyes" ; then $as_echo "#define EMPTY_TEMPL_LIST template<>" >>confdefs.h else $as_echo "#define EMPTY_TEMPL_LIST /**/" >>confdefs.h fi if test "x$self_friend_class" = "xyes" ; then $as_echo "#define SELF_FRIEND_CLASS /**/" >>confdefs.h fi if test ! -z "$GDB" -a ! -z "$XTERM" ; then { $as_echo "$as_me:${as_lineno-$LINENO}: Using gdb/xterm to attach debugger" >&5 $as_echo "$as_me: Using gdb/xterm to attach debugger" >&6;} $as_echo "#define HAVE_GDB_XTERM /**/" >>confdefs.h fi { $as_echo "$as_me:${as_lineno-$LINENO}: INSTALL_PREFIX=$prefix" >&5 $as_echo "$as_me: INSTALL_PREFIX=$prefix" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: ---------------------------------------------------" >&5 $as_echo "$as_me: ---------------------------------------------------" >&6;} PLATFORMS=$PLATFORMS HELP2MAN="help2man -N" MOC=$QTMOC ODINSEQ_INCLUDES=$extra_odinseq_includes all_includes="-I.. -I$srcdir_abs $all_includes" cat >>confdefs.h <<_ACEOF #define BASELIBS "$BASELIBS" _ACEOF cat >>confdefs.h <<_ACEOF #define CXXFLAGS "$CXXFLAGS_EXPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define CPPFLAGS "$CPPFLAGS_EXPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define LDFLAGS "$LDFLAGS_EXPORT" _ACEOF cat >>confdefs.h <<_ACEOF #define CXX "$CXX" _ACEOF cat >>confdefs.h <<_ACEOF #define LD "$LD" _ACEOF cat >>confdefs.h <<_ACEOF #define PLUGIN_LIBS "$PLUGIN_LIBS" _ACEOF cat >>confdefs.h <<_ACEOF #define DEFAULT_EDITOR "$initial_editor" _ACEOF cat >>confdefs.h <<_ACEOF #define DEFAULT_BROWSER "$initial_browser" _ACEOF cat >>confdefs.h <<_ACEOF #define INSTALL_PREFIX "$prefix" _ACEOF if test ! "$libdir" = '${exec_prefix}/lib' ; then libdir_export="$libdir" fi cat >>confdefs.h <<_ACEOF #define LIBDIR_CONFIGURE "$libdir_export" _ACEOF ac_config_files="$ac_config_files Makefile tjutils/Makefile odinpara/Makefile odinseq/Makefile odinqt/Makefile odindata/Makefile odin/Makefile pulsar/Makefile geoedit/Makefile miview/Makefile odinreco/Makefile cmdline-utils/Makefile sequences/Makefile samples/Makefile coils/Makefile docs/Makefile docs/homepage/Makefile docs/tutorials/Makefile replacements/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 $as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ONLY_LIBS_TRUE}" && test -z "${ONLY_LIBS_FALSE}"; then as_fn_error $? "conditional \"ONLY_LIBS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${GUI_ENABLED_TRUE}" && test -z "${GUI_ENABLED_FALSE}"; then as_fn_error $? "conditional \"GUI_ENABLED\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${IDEA_PLUGIN_TRUE}" && test -z "${IDEA_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"IDEA_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${PARAVISION_PLUGIN_TRUE}" && test -z "${PARAVISION_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"PARAVISION_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${STANDALONE_PLUGIN_TRUE}" && test -z "${STANDALONE_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"STANDALONE_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${EPIC_PLUGIN_TRUE}" && test -z "${EPIC_PLUGIN_FALSE}"; then as_fn_error $? "conditional \"EPIC_PLUGIN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : ${CONFIG_STATUS=./config.status} ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 $as_echo "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi as_nl=' ' export as_nl # Printing a long string crashes Solaris 7 /usr/bin/printf. as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo # Prefer a ksh shell builtin over an external printf program on Solaris, # but without wasting forks for bash or zsh. if test -z "$BASH_VERSION$ZSH_VERSION" \ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='print -r --' as_echo_n='print -rn --' elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then as_echo='printf %s\n' as_echo_n='printf %s' else if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' as_echo_n='/usr/ucb/echo -n' else as_echo_body='eval expr "X$1" : "X\\(.*\\)"' as_echo_n_body='eval arg=$1; case $arg in #( *"$as_nl"*) expr "X$arg" : "X\\(.*\\)$as_nl"; arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; esac; expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" ' export as_echo_n_body as_echo_n='sh -c $as_echo_n_body as_echo' fi export as_echo_body as_echo='sh -c $as_echo_body as_echo' fi # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Unset variables that we do not need and which cause bugs (e.g. in # pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" # suppresses any "Segmentation fault" message there. '((' could # trigger a bug in pdksh 5.2.14. for as_var in BASH_ENV ENV MAIL MAILPATH do eval test x\${$as_var+set} = xset \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # CDPATH. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi $as_echo "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : eval 'as_fn_append () { eval $1+=\$2 }' else as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : eval 'as_fn_arith () { as_val=$(( $* )) }' else as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || $as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in #( -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" Copyright (C) 2010 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) $as_echo "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) $as_echo "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX $as_echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "X$compiler_lib_search_dirs" | $Xsed -e "$delay_single_quote_subst"`' predep_objects='`$ECHO "X$predep_objects" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects='`$ECHO "X$postdep_objects" | $Xsed -e "$delay_single_quote_subst"`' predeps='`$ECHO "X$predeps" | $Xsed -e "$delay_single_quote_subst"`' postdeps='`$ECHO "X$postdeps" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "X$compiler_lib_search_path" | $Xsed -e "$delay_single_quote_subst"`' LD_CXX='`$ECHO "X$LD_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "X$old_archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "X$compiler_CXX" | $Xsed -e "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "X$GCC_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "X$lt_prog_compiler_no_builtin_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "X$lt_prog_compiler_wl_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "X$lt_prog_compiler_pic_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "X$lt_prog_compiler_static_CXX" | $Xsed -e "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "X$lt_cv_prog_compiler_c_o_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "X$archive_cmds_need_lc_CXX" | $Xsed -e "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "X$enable_shared_with_static_runtimes_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "X$export_dynamic_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "X$whole_archive_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "X$compiler_needs_object_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "X$old_archive_from_new_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "X$old_archive_from_expsyms_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "X$archive_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "X$archive_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "X$module_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "X$module_expsym_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "X$with_gnu_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "X$allow_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "X$no_undefined_flag_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "X$hardcode_libdir_flag_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_ld_CXX='`$ECHO "X$hardcode_libdir_flag_spec_ld_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "X$hardcode_libdir_separator_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "X$hardcode_direct_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "X$hardcode_direct_absolute_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "X$hardcode_minus_L_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "X$hardcode_shlibpath_var_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "X$hardcode_automatic_CXX" | $Xsed -e "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "X$inherit_rpath_CXX" | $Xsed -e "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "X$link_all_deplibs_CXX" | $Xsed -e "$delay_single_quote_subst"`' fix_srcfile_path_CXX='`$ECHO "X$fix_srcfile_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "X$always_export_symbols_CXX" | $Xsed -e "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "X$export_symbols_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "X$exclude_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "X$include_expsyms_CXX" | $Xsed -e "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "X$prelink_cmds_CXX" | $Xsed -e "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "X$file_list_spec_CXX" | $Xsed -e "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "X$hardcode_action_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "X$compiler_lib_search_dirs_CXX" | $Xsed -e "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "X$predep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "X$postdep_objects_CXX" | $Xsed -e "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "X$predeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "X$postdeps_CXX" | $Xsed -e "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "X$compiler_lib_search_path_CXX" | $Xsed -e "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # Quote evaled strings. for var in SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ AR \ AR_FLAGS \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ SHELL \ ECHO \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_wl \ lt_prog_compiler_pic \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_flag_spec_ld \ hardcode_libdir_separator \ fix_srcfile_path \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_flag_spec_ld_CXX \ hardcode_libdir_separator_CXX \ fix_srcfile_path_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ sys_lib_dlsearch_path_spec \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX; do case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Fix-up fallback echo if it was mangled by the above quoting rules. case \$lt_ECHO in *'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` ;; esac ac_aux_dir='$ac_aux_dir' xsi_shell='$xsi_shell' lt_shell_append='$lt_shell_append' # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' TIMESTAMP='$TIMESTAMP' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "tjutils/config.h") CONFIG_HEADERS="$CONFIG_HEADERS tjutils/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "tjutils/Makefile") CONFIG_FILES="$CONFIG_FILES tjutils/Makefile" ;; "odinpara/Makefile") CONFIG_FILES="$CONFIG_FILES odinpara/Makefile" ;; "odinseq/Makefile") CONFIG_FILES="$CONFIG_FILES odinseq/Makefile" ;; "odinqt/Makefile") CONFIG_FILES="$CONFIG_FILES odinqt/Makefile" ;; "odindata/Makefile") CONFIG_FILES="$CONFIG_FILES odindata/Makefile" ;; "odin/Makefile") CONFIG_FILES="$CONFIG_FILES odin/Makefile" ;; "pulsar/Makefile") CONFIG_FILES="$CONFIG_FILES pulsar/Makefile" ;; "geoedit/Makefile") CONFIG_FILES="$CONFIG_FILES geoedit/Makefile" ;; "miview/Makefile") CONFIG_FILES="$CONFIG_FILES miview/Makefile" ;; "odinreco/Makefile") CONFIG_FILES="$CONFIG_FILES odinreco/Makefile" ;; "cmdline-utils/Makefile") CONFIG_FILES="$CONFIG_FILES cmdline-utils/Makefile" ;; "sequences/Makefile") CONFIG_FILES="$CONFIG_FILES sequences/Makefile" ;; "samples/Makefile") CONFIG_FILES="$CONFIG_FILES samples/Makefile" ;; "coils/Makefile") CONFIG_FILES="$CONFIG_FILES coils/Makefile" ;; "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "docs/homepage/Makefile") CONFIG_FILES="$CONFIG_FILES docs/homepage/Makefile" ;; "docs/tutorials/Makefile") CONFIG_FILES="$CONFIG_FILES docs/tutorials/Makefile" ;; "replacements/Makefile") CONFIG_FILES="$CONFIG_FILES replacements/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_t=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_t"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;; esac case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 $as_echo "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`$as_echo "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 $as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out" && rm -f "$tmp/out";; *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" } >"$tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 $as_echo "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else $as_echo "/* $configure_input */" \ && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Autoconf 2.62 quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. case $CONFIG_FILES in *\'*) eval set x "$CONFIG_FILES" ;; *) set x $CONFIG_FILES ;; esac shift for mf do # Strip MF so we end up with the name of the file. mf=`echo "$mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile or not. # We used to match only the files named `Makefile.in', but # some people rename them; so instead we look at the file content. # Grep'ing the first line is not enough: some people post-process # each Makefile.in and add a new line on top of each file to say so. # Grep'ing the whole file is not good either: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then dirpart=`$as_dirname -- "$mf" || $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$mf" : 'X\(//\)[^/]' \| \ X"$mf" : 'X\(//\)$' \| \ X"$mf" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` else continue fi # Extract the definition of DEPDIR, am__include, and am__quote # from the Makefile without running `make'. DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` test -z "$DEPDIR" && continue am__include=`sed -n 's/^am__include = //p' < "$mf"` test -z "am__include" && continue am__quote=`sed -n 's/^am__quote = //p' < "$mf"` # When using ansi2knr, U may be empty or an underscore; expand it U=`sed -n 's/^U = //p' < "$mf"` # Find all dependency output files, they are included files with # $(DEPDIR) in their names. We invoke sed twice because it is the # simplest approach to changing $(DEPDIR) to its actual value in the # expansion. for file in `sed -n " s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do # Make sure the directory exists. test -f "$dirpart/$file" && continue fdir=`$as_dirname -- "$file" || $as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$file" : 'X\(//\)[^/]' \| \ X"$file" : 'X\(//\)$' \| \ X"$file" : 'X\(/\)' \| . 2>/dev/null || $as_echo X"$file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir=$dirpart/$fdir; as_fn_mkdir_p # echo "creating $dirpart/$file" echo '# dummy' > "$dirpart/$file" done done } ;; "libtool":C) # See if we are running on zsh, and set the options which allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}" ; then setopt NO_GLOB_SUBST fi cfgfile="${ofile}T" trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. # Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION # Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, # 2006, 2007, 2008 Free Software Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is part of GNU Libtool. # # GNU Libtool is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # # As a special exception to the GNU General Public License, # if you distribute this file as part of a program or library that # is built using GNU Libtool, you may include this file under the # same distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Libtool; see the file COPYING. If not, a copy # can be downloaded from http://www.gnu.org/licenses/gpl.html, or # obtained by writing to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # The names of the tagged configurations supported by this script. available_tags="CXX " # ### BEGIN LIBTOOL CONFIG # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # An object symbol dumper. OBJDUMP=$lt_OBJDUMP # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method == "file_magic". file_magic_cmd=$lt_file_magic_cmd # The archiver. AR=$lt_AR AR_FLAGS=$lt_AR_FLAGS # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name of the directory that contains temporary libtool files. objdir=$objdir # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that does not interpret backslashes. ECHO=$lt_ECHO # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test "X${COLLECT_NAMES+set}" != Xset; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain="$ac_aux_dir/ltmain.sh" # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) case $xsi_shell in yes) cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac } # func_basename file func_basename () { func_basename_result="${1##*/}" } # func_dirname_and_basename file append nondir_replacement # perform func_basename and func_dirname in a single function # call: # dirname: Compute the dirname of FILE. If nonempty, # add APPEND to the result, otherwise set result # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. # value retuned in "$func_basename_result" # Implementation must be kept synchronized with func_dirname # and func_basename. For efficiency, we do not delegate to # those functions but instead duplicate the functionality here. func_dirname_and_basename () { case ${1} in */*) func_dirname_result="${1%/*}${2}" ;; * ) func_dirname_result="${3}" ;; esac func_basename_result="${1##*/}" } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). func_stripname () { # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are # positional parameters, so assign one to ordinary parameter first. func_stripname_result=${3} func_stripname_result=${func_stripname_result#"${1}"} func_stripname_result=${func_stripname_result%"${2}"} } # func_opt_split func_opt_split () { func_opt_split_opt=${1%%=*} func_opt_split_arg=${1#*=} } # func_lo2o object func_lo2o () { case ${1} in *.lo) func_lo2o_result=${1%.lo}.${objext} ;; *) func_lo2o_result=${1} ;; esac } # func_xform libobj-or-source func_xform () { func_xform_result=${1%.*}.lo } # func_arith arithmetic-term... func_arith () { func_arith_result=$(( $* )) } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=${#1} } _LT_EOF ;; *) # Bourne compatible functions. cat << \_LT_EOF >> "$cfgfile" # func_dirname file append nondir_replacement # Compute the dirname of FILE. If nonempty, add APPEND to the result, # otherwise set result to NONDIR_REPLACEMENT. func_dirname () { # Extract subdirectory from the argument. func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` if test "X$func_dirname_result" = "X${1}"; then func_dirname_result="${3}" else func_dirname_result="$func_dirname_result${2}" fi } # func_basename file func_basename () { func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` } # func_stripname prefix suffix name # strip PREFIX and SUFFIX off of NAME. # PREFIX and SUFFIX must not contain globbing or regex special # characters, hashes, percent signs, but SUFFIX may contain a leading # dot (in which case that matches only a dot). # func_strip_suffix prefix name func_stripname () { case ${2} in .*) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; *) func_stripname_result=`$ECHO "X${3}" \ | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; esac } # sed scripts: my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' my_sed_long_arg='1s/^-[^=]*=//' # func_opt_split func_opt_split () { func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` } # func_lo2o object func_lo2o () { func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` } # func_xform libobj-or-source func_xform () { func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` } # func_arith arithmetic-term... func_arith () { func_arith_result=`expr "$@"` } # func_len string # STRING may not start with a hyphen. func_len () { func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` } _LT_EOF esac case $lt_shell_append in yes) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1+=\$2" } _LT_EOF ;; *) cat << \_LT_EOF >> "$cfgfile" # func_append var value # Append VALUE to the end of shell variable VAR. func_append () { eval "$1=\$$1\$2" } _LT_EOF ;; esac sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # If ld is used when linking, flag to hardcode \$libdir into a binary # during linking. This must work even if \$libdir does not exist. hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \${shlibpath_var} if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Fix the shell variable \$srcfile for the compiler. fix_srcfile_path=$lt_fix_srcfile_path_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi odin-1.8.5/cmdline-utils/0000755000175000017500000000000011735135552012237 500000000000000odin-1.8.5/cmdline-utils/swab.cpp0000644000175000017500000000562011322062353013610 00000000000000#include #include #include /** * \page swab Swap adjacent bytes * \verbinclude cmdline-utils/swab.usage */ int main(int argc, char* argv[]) { if(argc < 4 || argc > 5){ std::cout << "swab: Mirrors bytes, in the case of 2, it swaps adjacent bytes" << std::endl; std::cout << "Usage: swab " << std::endl; exit(0); } char *temp1,*temp2; unsigned long n_bytes; unsigned long block_size,i,k,n_data,j; std::ofstream out_data; n_bytes = atoi(argv[1]); std::ifstream in_data(argv[2],std::ios::in|std::ios::binary); if(in_data == NULL){ std::cerr << "swab: ERROR: can't open file " << argv[2] << std::endl; exit(1); } in_data.seekg(0,std::ios::end); if(argc == 5) block_size = (unsigned)atol(argv[4])*1000000; else block_size = in_data.tellg(); block_size-= block_size%n_bytes; n_data=in_data.tellg(); if(block_size > n_data){ // std::cerr << "swab: block size exceeding file size !" << std::endl // << "setting block size to file size (=" << n_data/1000000. << "MB)" << std::endl; block_size = n_data; } in_data.seekg(0,std::ios::beg); if((float)n_data/(float)n_bytes-n_data/n_bytes){ std::cerr << "swab: ERROR: swab: size of \n" << argv[2] << "not a multiple of no. of swap bytes (" << n_bytes << ")" << std::endl; exit(1); } temp1=new char[block_size]; temp2=new char[block_size]; for(k=0;k #include #include #include #include /** * \page gencoil Generate a coil file * \verbinclude cmdline-utils/gencoil.usage */ void usage() { STD_cout << STD_endl; STD_cout << "gencoil: Generates a virtual coil suitable for sequence simulation in ODIN" << STD_endl; STD_cout << STD_endl; STD_cout << "Usage and options:" << STD_endl; STD_cout << " Generate a radially inhomogenous coil:" << STD_endl; STD_cout << " gencoil -rad -n -fov -R -o " << STD_endl; STD_cout << " Generate an array coil by rotating pre-existing image file:" << STD_endl; STD_cout << " gencoil -rot -n -fov -nc -i -sl -o " << STD_endl; STD_cout << " Generate an array coil consisting of simple loops:" << STD_endl; STD_cout << " gencoil -arr -n -nc -fov -R -o " << STD_endl; STD_cout << " Generate coil with a B1 gradient:" << STD_endl; STD_cout << " gencoil -grad -n -fov -g -o " << STD_endl; STD_cout << "Other options:" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } int main(int argc, char* argv[]) { LogBase::set_log_levels(argc,argv); Log odinlog("gencoil","main"); if(hasHelpOption(argc,argv)) {usage(); return 0;} Range all=Range::all(); char optval[ODIN_MAXCHAR]; STD_string coil_fname; if(getCommandlineOption(argc,argv,"-o",optval,ODIN_MAXCHAR)) coil_fname=optval; else {usage();exit(0);} CoilSensitivity sens("Coil Sensitivity"); bool valid_mode=false; ///////////////////////////////////////////////////////////////////////////// if(isCommandlineOption(argc,argv,"-rad")) { int n; float R,fov; if(getCommandlineOption(argc,argv,"-n",optval,ODIN_MAXCHAR)) n=atoi(optval); else {usage();exit(0);} if(getCommandlineOption(argc,argv,"-R",optval,ODIN_MAXCHAR)) R=0.01*atof(optval); else {usage();exit(0);} if(getCommandlineOption(argc,argv,"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval); else {usage();exit(0);} carray sens_map(1,1,n,n); int nx_center=n/2; int ny_center=n/2; double a=-4.0*R; double c=1.0+R; STD_complex b1factor; ndim nn=sens_map.get_extent(); ndim indexvec; for(int i=0; i rotation; TinyVector offset; offset=0.0; carray sens_map(nc,1,n,n); Data imgdata(img.get_magnitude()); TinyVector newshape(n,n); ODINLOG(odinlog,infoLog) << "Congridding map ... " << STD_endl; Data onecoil=imgdata(0,sl,all,all); onecoil.congrid(newshape); float maxmap=max(onecoil); float sum=0.0; float nvals=0.0; for(int i=0; i0.1*maxmap) { sum+=val; nvals+=1.0; } } float mean=sum/nvals; onecoil/=(2.0*mean); // factor to account for overlapping adjacent coils ODINLOG(odinlog,infoLog) << "Polynomial fit ... " << STD_endl; onecoil=polyniomial_fit(onecoil,onecoil,2,6.0); Data onecoil_transform(newshape); for(int ic=0; ic rotate(onecoil_transform.shape(), rotation, offset, 2.0); onecoil_transform=rotate(onecoil); for(int iy=0; iy rotmat[nc]; Array offset[nc]; ODINLOG(odinlog,infoLog) << "Preparing rotmat/offset ... " << STD_endl; for(int icoil=0; icoil x(3); x(0)=fov*secureDivision(double(ix-nx_center),nx_center); x(1)=fov*secureDivision(double(iy-ny_center),ny_center); x(2)=0.0; int nloopsegments=100; float dphi=2.0*PII/nloopsegments; Array dl(3); Array r(3); Array r0(3); Array dB(3); STD_complex B1(0.0); for(int iseg=0; iseg0.0) { B1+=STD_complex(dB(0),dB(1))/r2; } } sens_map(indexvec)=B1/float(2.0*PII); // will be normalized to ~ 1 at center of loop } sens.set_sensitivity_map(sens_map,fov,fov,fov); valid_mode=true; } ///////////////////////////////////////////////////////////////////////////// if(isCommandlineOption(argc,argv,"-grad")) { int n; float fov,grad; if(getCommandlineOption(argc,argv,"-n",optval,ODIN_MAXCHAR)) n=atoi(optval); else {usage();exit(0);} if(getCommandlineOption(argc,argv,"-g",optval,ODIN_MAXCHAR)) grad=atof(optval); else {usage();exit(0);} if(getCommandlineOption(argc,argv,"-fov",optval,ODIN_MAXCHAR)) fov=atof(optval); else {usage();exit(0);} carray sens_map(1,1,n,n); int nx_center=n/2; ndim nn=sens_map.get_extent(); ndim indexvec; for(int i=0; i #include #include #include #include #include /** * \page micalc Basic calculations with medical image data * \verbinclude cmdline-utils/micalc.usage * * \section micalc_examples Some examples how to use micalc: * * Calculate the difference between two DICOM files 'image1.dcm' 'and image2.dcm' and store it in * float-type raw data file 'diff.float': * \verbatim micalc -if1 image1.dcm -op '-' -if2 image2.dcm -of diff.float \endverbatim * * * Multiply image magnitude of Nifti file 'image.nii' by a factor 10: * \verbatim micalc -if1 image.nii -op '*' -in2 10 -of image.nii \endverbatim * * * Accumulate all values in file 'image.float' and write result to console: * \verbatim micalc -if image.float -op '+' \endverbatim * * * Negate values (invert sign) of file image.hdr and write result to neg.hdr * \verbatim micalc -if image.hdr -op '-' neg.hdr \endverbatim * * * Print statistics about file 'data.asc' to console: * \verbatim micalc -if data.asc \endverbatim * * * Write time-course mean and fluctuation (relative standard deviation over time) of * file 'tcourse.v' to file 'mean.v' and 'stdev.v', respectively: * \verbatim micalc -if tcourse.v -mean mean.v -fluct stdev.v \endverbatim * * * Calculate histogram in interval (0.0,100.0) with 64 steps of DICOMs in directory cbv: * \verbatim micalc -if cbv -hist histogram.asc -histmin 0.0 -histmax 100.0 -histslots 64 \endverbatim * * * Please note that it might be necessary to quote the operation argument (as shown above) * in order to prevent the shell from expanding it. */ void usage(const Protocol& prot) { FileReadOpts ropts; FileWriteOpts wopts; FilterFactory filter; STD_cout << "micalc: Performs basic mathematics with data sets" << STD_endl; STD_cout << " File formats are automatically identified by their file extension." << STD_endl; STD_cout << "micalc can be used in one of the following modes:" << STD_endl; STD_cout << " Binary operation with data sets and/or scalar numbers:" << STD_endl; STD_cout << " micalc [-if1 | -in1 ] -op [-if2 | -in2 ] -of " << STD_endl; STD_cout << " Accumulation of one data set:" << STD_endl; STD_cout << " micalc -if -op " << STD_endl; STD_cout << " Transformation (magnitude, logarithm, negation, inversion, or acos) of one data set:" << STD_endl; STD_cout << " micalc -if -op -of " << STD_endl; STD_cout << " Statistics of one data set:" << STD_endl; STD_cout << " micalc -if [-mean ] [-stdev ] [-fluct ] [-tcourse ] [-hist -histmin -histmax -histslots -rightstairs -histfract]" << STD_endl; STD_cout << "Extra options:" << STD_endl; STD_cout << "\t-mask " << STD_endl; STD_cout << "\t-weightmask " << STD_endl; STD_cout << "File read options:" << STD_endl; STD_cout << prot.get_cmdline_usage("\t"); STD_cout << ropts.get_cmdline_usage("\t"); STD_cout << "File write options:" << STD_endl; STD_cout << wopts.get_cmdline_usage("\t"); STD_cout << "Filters applied to input file(s):" << STD_endl; STD_cout << filter.get_cmdline_usage("\t"); STD_cout << "Other options:" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; STD_cout << "Supported file extensions(formats):" << STD_endl; STD_cout << FileIO::autoformats_str("\t") << STD_endl; } bool read_infile(const STD_string& filename, Data& data, const FileReadOpts& ropts, Protocol& prot, const FilterChain& filterchain, const Data& weightmaskdata) { Log odinlog("micalc","read_infile"); Range all=Range::all(); Data datain; if(datain.autoread(filename,ropts,&prot)<0) return false; if(!filterchain.apply(prot,datain)) return false; data.resize(datain.shape()); if(weightmaskdata.size()) { if( weightmaskdata.extent(0) && same_shape(data, weightmaskdata, TinyVector(0,1,1,1) ) ) { for(int irep=0; irep odinlog("micalc","main"); Range all=Range::all(); FileReadOpts ropts; FileWriteOpts wopts; Protocol prot; if(hasHelpOption(argc,argv)) {usage(prot); return 0;} // set defaults prot.seqpars.set_MatrixSize(readDirection,1); prot.seqpars.set_MatrixSize(phaseDirection,1); prot.seqpars.set_MatrixSize(sliceDirection,1); char optval[ODIN_MAXCHAR]; STD_string operation; STD_string infile1; STD_string infile2; STD_string outfile; STD_string maskfile; STD_string weightmaskfile; float innumber1=0.0; float innumber2=0.0; bool i1flag=false; bool i2flag=false; bool offlag=false; bool ifflag=false; bool opflag=false; bool binaryop=false; bool accumulate=false; bool transform=false; bool stateval=false; // command line parsing, parse before filters to remove options if(getCommandlineOption(argc,argv,"-op",optval,ODIN_MAXCHAR)) {operation=optval; opflag=true;} if(getCommandlineOption(argc,argv,"-if1",optval,ODIN_MAXCHAR)) {infile1=optval; i1flag=true;} if(getCommandlineOption(argc,argv,"-if2",optval,ODIN_MAXCHAR)) {infile2=optval; i2flag=true;} if(getCommandlineOption(argc,argv,"-if",optval,ODIN_MAXCHAR)) {infile1=optval; ifflag=true;} if(getCommandlineOption(argc,argv,"-in1",optval,ODIN_MAXCHAR)) {innumber1=atof(optval); i1flag=true;} if(getCommandlineOption(argc,argv,"-in2",optval,ODIN_MAXCHAR)) {innumber2=atof(optval); i2flag=true;} if(getCommandlineOption(argc,argv,"-of",optval,ODIN_MAXCHAR)) {outfile=optval; offlag=true;} if(getCommandlineOption(argc,argv,"-mask",optval,ODIN_MAXCHAR)) {maskfile=optval;} if(getCommandlineOption(argc,argv,"-weightmask",optval,ODIN_MAXCHAR)) {weightmaskfile=optval;} STD_string histfile; if(getCommandlineOption(argc,argv,"-hist",optval,ODIN_MAXCHAR)) histfile=optval; STD_string meanfile; STD_string fluctfile; STD_string stdevfile; STD_string tcoursefile; STD_string histslots; STD_string histmin; STD_string histmax; if(getCommandlineOption(argc,argv,"-mean",optval,ODIN_MAXCHAR)) meanfile=optval; if(getCommandlineOption(argc,argv,"-fluct",optval,ODIN_MAXCHAR)) fluctfile=optval; if(getCommandlineOption(argc,argv,"-stdev",optval,ODIN_MAXCHAR)) stdevfile=optval; if(getCommandlineOption(argc,argv,"-tcourse",optval,ODIN_MAXCHAR)) tcoursefile=optval; if(getCommandlineOption(argc,argv,"-histslots",optval,ODIN_MAXCHAR)) histslots=optval; if(getCommandlineOption(argc,argv,"-histmin",optval,ODIN_MAXCHAR)) histmin=optval; if(getCommandlineOption(argc,argv,"-histmax",optval,ODIN_MAXCHAR)) histmax=optval; bool rightstairs=isCommandlineOption(argc,argv,"-rightstairs"); bool histfract=isCommandlineOption(argc,argv,"-histfract"); // Parse before filters to remove options ropts.parse_cmdline_options(argc,argv); wopts.parse_cmdline_options(argc,argv); prot.parse_cmdline_options(argc,argv); FilterChain filterchain(argc,argv); if(i1flag && i2flag && opflag) binaryop=true; if(ifflag && opflag) { if(offlag) transform=true; else accumulate=true; } if(ifflag && (!opflag)) stateval=true; if( !( binaryop || accumulate || transform || stateval ) ) {usage(prot); return 0;} if(accumulate || stateval) FileIO::set_trace_status(false); if(binaryop && infile1=="" && infile2=="") { ODINLOG(odinlog,errorLog) << "Specifiy at least one file" << STD_endl; return -1; } Data data1; Data data2; Data weightmaskdata; if(weightmaskfile!="") { if(weightmaskdata.autoread(weightmaskfile,ropts)<0) return -1; } if(infile1!="") { if(!read_infile(infile1, data1, ropts, prot, filterchain, weightmaskdata)) return -1; } if(binaryop && infile2!="") { if(!read_infile(infile2, data2, ropts, prot, filterchain, weightmaskdata)) return -1; } TinyVector outshape; if(binaryop || transform) { bool has_shape1=sum(data1.shape()); bool has_shape2=sum(data2.shape()); if( has_shape1 && has_shape2 && !same_shape(data1,data2) ) { ODINLOG(odinlog,errorLog) << "Shape mismatch: data1shape/data2shape=" << data1.shape() << "/" << data2.shape() << STD_endl; return -1; } else outshape=data1.shape(); if(has_shape1 && !has_shape2) { outshape=data1.shape(); data2.resize(outshape); data2=innumber2; } if(!has_shape1 && has_shape2) { outshape=data2.shape(); data1.resize(outshape); data1=innumber1; } if(!has_shape1 && !has_shape2) { ODINLOG(odinlog,errorLog) << "Specifiy at least one valid file" << STD_endl; return -1; } } Data* maskptr=0; Data maskdata; Data inmaskdata; if(maskfile!="") { if(inmaskdata.autoread(maskfile,ropts)<0) return -1; if( inmaskdata.extent(0) && same_shape(data1, inmaskdata, TinyVector(0,1,1,1) ) ) { maskdata.resize(data1.shape()); maskdata=0.0; for(int i=0; i index=data1.create_index(i); TinyVector maskindex=index; maskindex(0)=0; if(inmaskdata(maskindex)>0.0) maskdata(index)=1.0; } maskptr=&maskdata; } else { ODINLOG(odinlog,errorLog) << "Shape mismatch: datashape/maskshape=" << data1.shape() << "/" << inmaskdata.shape() << STD_endl; return -1; } } prot.system.set_data_type(TypeTraits::type2label(float(0))); // Store results in float if(binaryop) { if(maskptr) { ODINLOG(odinlog,normalDebug) << "data1/data2/maskdata" << data1.shape() << "/" << data2.shape() << "/" << maskdata.shape() << STD_endl; data1=data1*maskdata; data2=data2*maskdata; } if(operation=="lcorr" || operation=="kcorr") { int npts=data1.size(); if(maskptr) npts=int(sum(*maskptr)+0.5); Array vec1(npts); Array vec2(npts); int vecindex=0; for(int i=0; i index=data1.create_index(i); bool include=true; if( maskptr && (*maskptr)(index)<=0.0 ) include=false; if(include) { vec1(vecindex)=data1(index); vec2(vecindex)=data2(index); vecindex++; } } correlationResult coresult; if(operation=="lcorr") coresult=correlation(vec1, vec2); if(operation=="kcorr") coresult=kendall(vec1, vec2); STD_cout << "r/p/z(" << npts << ")=" << coresult.r << "/" << coresult.p << "/" << coresult.z << STD_endl; } else { Data result(outshape); ODINLOG(odinlog,infoLog) << "calculating " << data1.shape() << " " << operation << " " << data2.shape() << " ..." << STD_endl; bool validop=false; if(operation=="+") {validop=true; result=data1+data2;} if(operation=="-") {validop=true; result=data1-data2;} if(operation=="*") {validop=true; result=data1*data2;} if(operation=="/") {validop=true; result=secureDivision(data1,data2);} if(!validop) { ODINLOG(odinlog,errorLog) << "invalid binary operation: " << operation << STD_endl; return -1; } if(result.autowrite(outfile,wopts,&prot)<0) return -1; } return 0; } if(accumulate) { if(maskptr) { data1=data1*maskdata; } double accuresult=0.0; bool validop=false; if(operation=="+") {validop=true; accuresult=sum(data1);} if(operation=="*") {validop=true; accuresult=product(data1);} if(!validop) { ODINLOG(odinlog,errorLog) << "invalid accumulation operator: " << operation << STD_endl; return -1; } STD_cout << accuresult << STD_endl; } if(transform) { if(maskptr) { data1=data1*maskdata; } Data result(outshape); ODINLOG(odinlog,infoLog) << "Calculating " << operation << " " << data1.shape() << " ..." << STD_endl; bool validop=false; if(operation=="abs") {validop=true; result=fabs(data1);} if(operation=="log") {validop=true; result=where(Array(data1)>0.0, Array(log(data1)), float(0.0));} if(operation=="-") {validop=true; result=-data1;} if(operation=="/") {validop=true; result=where(Array(data1)!=0.0, Array(1.0/data1), float(0.0));} if(operation=="acos") {validop=true; result=where(Array(data1)>=-1.0 && Array(data1)<=1.0, Array(acos(data1)), float(0.0));} if(!validop) { ODINLOG(odinlog,errorLog) << "invalid unary operation: " << operation << STD_endl; return -1; } if(result.autowrite(outfile,wopts,&prot)<0) return -1; return 0; } if(stateval) { if(histfile!="") { int nvals=data1.numElements(); if(maskptr) { nvals=0; for(int i=0; inumElements(); i++) { TinyVector index=maskptr->create_index(i); if( (*maskptr)(index)>0.0 ) { nvals++; } } } if(histslots=="") {usage(prot); return -1;} int nslots=atoi(histslots.c_str()); if(histmin=="") {usage(prot); return -1;} float minval=atof(histmin.c_str()); if(histmax=="") {usage(prot); return -1;} float maxval=atof(histmax.c_str()); ODINLOG(odinlog,infoLog) << "calculating histogram with nslots/minval/maxval=" << nslots << "/" << minval << "/" << maxval << STD_endl; if(minval>=maxval) { ODINLOG(odinlog,errorLog) << "histmax must be larger than histmin" << STD_endl; return -1; } float stairoffset=0.5; // centered stairs if(rightstairs) stairoffset=0.0; // assume rightstairs when plotting (xmgrace) Data xvals(nslots); Data yvals(nslots); yvals=0.0; if(minval>0.0 && maxval>0.0) { // Use log histogram float minpow=log10(minval); float maxpow=log10(maxval); float powrange=maxpow-minpow; float step=secureDivision(powrange,nslots); ODINLOG(odinlog,normalDebug) << "minpow/maxpow/powrange/step=" << minpow << "/" << maxpow << "/" << powrange << "/" << step << STD_endl; for(int i=0; i index=data1.create_index(i); if( !(maskptr && (*maskptr)(index)==0.0) ) { float pow=log10(data1(index)); int slot=int(secureDivision(pow-minpow,powrange)*nslots); ODINLOG(odinlog,normalDebug) << "pow/slot=" << pow << "/" << slot << STD_endl; if(slot>=0 && slot index=data1.create_index(i); if( !(maskptr && (*maskptr)(index)==0.0) ) { float val=data1(index); int slot=int(secureDivision(val-minval,range)*nslots); ODINLOG(odinlog,normalDebug) << "val/slot=" << val << "/" << slot << STD_endl; if(slot>=0 && slot meanresult(outshape); meanresult=0.0; Data fluctresult(outshape); fluctresult=0.0; Data stdevresult(outshape); stdevresult=0.0; Data tcourseresult(data1.extent(0)); tcourseresult=0.0; int tcoursepts=0; for(int i=0; i index=meanresult.create_index(i); if(!index(0)) { // only once for all repetitions if( !(maskptr && (*maskptr)(index)==0.0) ) { statisticResult stats=statistics(data1(all,index(1),index(2),index(3))); meanresult(index)= stats.mean; fluctresult(index)=secureDivision(stats.stdev,stats.mean); stdevresult(index)=stats.stdev; tcourseresult(all)+=data1(all,index(1),index(2),index(3)); tcoursepts++; ODINLOG(odinlog,normalDebug) << "mean/stdev(" << index << ")=" << stats.mean << "/" << stats.stdev << STD_endl; } } } if(weightmaskdata.size()) { tcourseresult/=sum(weightmaskdata(0,all,all,all)); } else { tcourseresult/=float(tcoursepts); } if(meanfile!="") if(meanresult.autowrite(meanfile,wopts,&prot)<0) return -1; if(fluctfile!="") if(fluctresult.autowrite(fluctfile,wopts,&prot)<0) return -1; if(stdevfile!="") if(stdevresult.autowrite(stdevfile,wopts,&prot)<0) return -1; if(tcoursefile!="") if(tcourseresult.autowrite(tcoursefile,wopts,&prot)<0) return -1; } else { STD_cout << statistics(data1,maskptr) << STD_endl; } // STD_cout << "median = " << median(data1) << STD_endl; } return 0; } odin-1.8.5/cmdline-utils/miconv.cpp0000644000175000017500000001441411725203123014147 00000000000000#include #include #include /** * \page miconv Conversion utility for medical images * \verbinclude cmdline-utils/miconv.usage * * \section miconv_examples Some examples how to use miconv: * * Read a bunch of DICOM files (format 'dcm'), produced by Siemens, from directory 'mosaic' and convert it to NIFTI file 'mosaic.nii' * with a dialect suitable for FSL: * \verbatim miconv -rf dcm -rdialect siemens -wdialect fsl mosaic mosaic.nii \endverbatim * * Converting a short (16 bit) raw data file '2dseq' of size 256x256 to a DICOM file 'image.dcm': * \verbatim miconv -nx 256 -ny 256 -rf short 2dseq image.dcm \endverbatim */ struct MiConvOpts : JcampDxBlock { JDXstring protfile; JDXstring parlist; MiConvOpts() { protfile.set_cmdline_option("p").set_description("Load this protcol for defaults"); append_member(protfile,"protfile"); parlist.set_cmdline_option("l").set_description("Lists space-separated set of protocol parameters and exits. Use '-l help' to get a list of possible parameters and '-l all' to list all parameters. The parameter 'output-file' must be omitted when using this option."); append_member(parlist,"parlist"); } }; //////////////////////////////////////// void usage(const Protocol& prot) { FileReadOpts ropts; FileWriteOpts wopts; MiConvOpts mopts; FilterFactory filter; STD_cout << "miconv: Converts medical image data between formats." << STD_endl; STD_cout << " File formats are automatically identified by their file extension." << STD_endl; STD_cout << " It expects at least two filenames/directories (for the input and output file) at the end of the command line." << STD_endl; STD_cout << " An exception is the option '-l' which requires only one filename/directory to list its content." << STD_endl; STD_cout << "Usage: miconv [options] []" << STD_endl; STD_cout << "General options:" << STD_endl; STD_cout << mopts.get_cmdline_usage("\t"); STD_cout << "Protocol options:" << STD_endl; STD_cout << prot.get_cmdline_usage("\t"); STD_cout << "File read options:" << STD_endl; STD_cout << ropts.get_cmdline_usage("\t"); STD_cout << "File write options:" << STD_endl; STD_cout << wopts.get_cmdline_usage("\t"); STD_cout << "Filters:" << STD_endl; STD_cout << filter.get_cmdline_usage("\t"); STD_cout << "Other options:" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; STD_cout << "Supported file extensions(formats):" << STD_endl; STD_cout << FileIO::autoformats_str("\t") << STD_endl; } //////////////////////////////////////// int main(int argc, char* argv[]) { if(LogBase::set_log_levels(argc,argv)) return 0; Log odinlog("miconv","main"); char optval[ODIN_MAXCHAR]; Protocol prot_template; FileReadOpts ropts; FileWriteOpts wopts; MiConvOpts mopts; if(hasHelpOption(argc,argv)) {usage(prot_template); return 0;} if(argc<3) {usage(prot_template); return 0;} // set defaults prot_template.seqpars.set_MatrixSize(readDirection,1); prot_template.seqpars.set_MatrixSize(phaseDirection,1); prot_template.seqpars.set_MatrixSize(sliceDirection,1); mopts.parse_cmdline_options(argc,argv); STD_string infile; STD_string outfile; if(mopts.parlist!="") { infile=argv[argc-1]; } else { infile=argv[argc-2]; outfile=argv[argc-1]; } if(mopts.parlist=="help") { STD_cout << "Possible protocol parameters:" << STD_endl; for(unsigned int i=0; ifirst.printval(pars[ipar]), "\n", ""); // truncate after first newline } STD_ostringstream oss; oss << pdit->second.shape(); table(npars,imap)=oss.str(); imap++; } STD_cout << print_table(table); return 0; } ODINLOG(odinlog,normalDebug) << "mem(in ): " << Profiler::get_memory_usage() << STD_endl; // Create copy of protocol-data map, thereby modify protocol FileIO::ProtocolDataMap pdmap_out; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap_in.begin(); pdit!=pdmap_in.end(); ++pdit) { Protocol prot(pdit->first); prot.parse_cmdline_options(argc,argv); // override parameters of infile pdmap_out[prot].reference(pdit->second); } ODINLOG(odinlog,normalDebug) << "mem(out): " << Profiler::get_memory_usage() << STD_endl; // Parse before filters to remove options wopts.parse_cmdline_options(argc,argv); FilterChain filterchain(argc,argv); //apply filters on pdmap_out if(!filterchain.apply(pdmap_out)) return -1; // Write data int result=FileIO::autowrite(pdmap_out, outfile, wopts); if(result>0) result=0; return result; } odin-1.8.5/cmdline-utils/micalc.10000644000175000017500000002173211734623251013473 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH MICALC "1" "March 2012" "micalc 1.8.5" "User Commands" .SH NAME micalc \- Performs basic mathematics with data sets .SH DESCRIPTION micalc: Performs basic mathematics with data sets .IP File formats are automatically identified by their file extension. .SS "micalc can be used in one of the following modes:" .IP Binary operation with data sets and/or scalar numbers: .IP micalc [\-if1 | \fB\-in1\fR ] \fB\-op\fR [\-if2 | \fB\-in2\fR ] \fB\-of\fR .IP Accumulation of one data set: .IP micalc \fB\-if\fR \fB\-op\fR .IP Transformation (magnitude, logarithm, negation, inversion, or acos) of one data set: .IP micalc \fB\-if\fR \fB\-op\fR \fB\-of\fR .IP Statistics of one data set: .IP micalc \fB\-if\fR [\-mean ] [\-stdev ] [\-fluct ] [\-tcourse ] [\-hist \fB\-histmin\fR \fB\-histmax\fR \fB\-histslots\fR \fB\-rightstairs\fR \fB\-histfract]\fR .SS "Extra options:" .HP \fB\-mask\fR .HP \fB\-weightmask\fR .SS "File read options:" .HP \fB\-date\fR: Date of scan [yyyymmdd] (default=20120328yyyymmdd) .HP \fB\-fp\fR: FOV in phase direction [mm] (default=220.0mm) .HP \fB\-fr\fR: FOV in read direction [mm] (default=220.0mm) .HP \fB\-fs\fR: FOV in slice direction [mm] (default=5.0mm) .HP \fB\-nr\fR: Number of consecutive measurements (default=1) .HP \fB\-nx\fR: Number of points in read direction (default=128) .HP \fB\-ny\fR: Number of points in phase direction (default=128) .HP \fB\-nz\fR: Number of points in slice direction (default=1) .HP \fB\-pbirth\fR: Patients date of birth [yyyymmdd] (default=00000000yyyymmdd) .HP \fB\-pid\fR: Unique patient identifier (default=Unknown) .HP \fB\-pname\fR: Full patient name (default=Unknown) .HP \fB\-psex\fR: Patients sex (options=M F O , default=O) .HP \fB\-pweight\fR: Patients weight [kg] (default=50.0kg) .HP \fB\-scient\fR: Scientist Name (default=Unknown) .HP \fB\-sd\fR: Inter\-slice distance (from center to center) [mm] (default=10.0mm) .HP \fB\-serd\fR: Series Description (default=Unknown) .HP \fB\-serno\fR: Series Number (default=1) .HP \fB\-st\fR: Slice thickness [mm] (default=5.0mm) .HP \fB\-stud\fR: Study Description (default=Unknown) .HP \fB\-tcname\fR: Name of transmit coil (default=Unknown) .HP \fB\-te\fR: Time\-to\-echo of the sequence [ms] (default=80.0ms) .HP \fB\-time\fR: Time of scan [hhmmss] (default=165641hhmmss) .HP \fB\-tr\fR: Time between consecutive excitations [ms] (default=1000.0ms) .HP \fB\-cplx\fR: Treat data as complex and extract the given component (options=none abs pha real imag , default=none) .HP \fB\-ds\fR: Dataset index to extract if multiple datasets are read .HP \fB\-filter\fR: Read only those datasets which protocol parameter 'key' contains the string 'value' (given in the format 'key=value') .HP \fB\-fmap\fR: For reduced memory usage, keep filemapping after reading (raw) data, but writing into the array will result in a crash .HP \fB\-jdx\fR: If multiple JDX arrays are present, select this .HP \fB\-rdialect\fR: Read data using given dialect of the format. (default is no dialect) .HP \fB\-rf\fR: Read format, use it to override file extension (options=autodetect 3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk , default=autodetect) .HP \fB\-skip\fR: Skip this amount of bytes before reading the raw data (default=0) .SS "File write options:" .HP \fB\-append\fR: Append to existing file, only for raw data .HP \fB\-fnamepar\fR: Space\-separated list of protocol parameters to include when creating unique file names .HP \fB\-split\fR: Force splitting of protocol\-data pairs into separate files. .HP \fB\-type\fR: Image representation type (options=automatic float double s32bit u32bit s16bit u16bit s8bit u8bit , default=automatic) .HP \fB\-wdialect\fR: Write data using given dialect of the format. (default is no dialect) .HP \fB\-wf\fR: Write format, use it to override file extension (options=autodetect 3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk , default=autodetect) .HP \fB\-wp\fR: Store the protocol separately to this file. .SS "Filters applied to input file(s):" .HP \fB\-align\fR : Align data to the geometry (voxel locations) of an external file .HP \fB\-automask\fR : Create mask using automatic histogram\-based threshold .HP \fB\-detrend\fR : Remove slow drift over time .HP \fB\-genmask\fR : Create mask including all voxels with value in given range .HP \fB\-isotrop\fR : make image voxels isotrop through interpolation (image geometry will not change) .HP \fB\-lowpass\fR : Lowpass filtering .HP \fB\-max\fR : Clip all values above maximum value .HP \fB\-maxip\fR : Perform maximum intensity projection over given direction .HP \fB\-merge\fR : Merge datasets into a single dataset by expanding the time dimension .HP \fB\-min\fR : Clip all values below mininum value .HP \fB\-minip\fR : Perform minimum intensity projection over given direction .HP \fB\-noNaN\fR : Replaces every NaN by the given value .HP \fB\-pflip\fR : Flip data in phase direction .HP \fB\-prange\fR : Select range in phase direction .HP \fB\-proj\fR : Perform projection over given direction .HP \fB\-quantilmask\fR : Create mask including all voxels above the given fractional threshold .HP \fB\-resample\fR : Temporal resize of image data .HP \fB\-resize\fR : Spatial resize of image data .HP \fB\-reslice\fR : reslices the image to a given orientation .HP \fB\-rflip\fR : Flip data in read direction .HP \fB\-rot\fR : In\-plane rotation .HP \fB\-rrange\fR : Select range in read direction .HP \fB\-scale\fR : Rescale image values .HP \fB\-sflip\fR : Flip data in slice direction .HP \fB\-shift\fR : Shift data spatially .HP \fB\-splice\fR : splices the image in the given direction .HP \fB\-srange\fR : Select range in slice direction .HP \fB\-swapdim\fR <[rps][\-],[rps][\-],[rps][\-]> : swap/reflect dimensions by specifying a direction triple with optional reflection sign appended .HP \fB\-tile\fR : Combine slices into a square 2D image .HP \fB\-trange\fR : Select range in time direction .HP \fB\-typemax\fR : Clip all values above maximum of a specific datatype .HP \fB\-typemin\fR : Clip all values below mininum of a specific datatype .HP \fB\-usemask\fR : Create 1D dataset including all values within mask from file .SS "Other options:" .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information .SS "Supported file extensions(formats):" .TP 3db (Iris3D binary data) .TP asc (ASCII, dialects: tcourse ) .TP coi (JCAMP\-DX data sets) .TP dat (Matlab ascii 2D data matrix) .TP dcm (DICOM, dialects: siemens ) .TP double (double raw data) .TP float (float raw data) .TP gz (GNU\-Zip container for other formats) .TP hdr (NIFTI/ANALYZE, dialects: fsl ) .TP idx (3D\-indices of non\-zeroes in ASCII) .TP ima (DICOM, dialects: siemens ) .TP jdx (JCAMP\-DX image format) .TP mag (DICOM, dialects: siemens ) .TP mhd (MetaImage) .TP nii (NIFTI/ANALYZE, dialects: fsl ) .TP ph (DICOM, dialects: siemens ) .TP png (Portable Network Graphics) .TP pos (x\-y positions of non\-zeroes in ASCII) .TP pro (ODIN measurement protocols) .TP reg (Ansoft HFSS ASCII) .TP s16bit (signed 16 bit raw data) .TP s32bit (signed 32 bit raw data) .TP s8bit (signed 8 bit raw data) .TP smp (JCAMP\-DX data sets) .TP u16bit (unsigned 16 bit raw data) .TP u32bit (unsigned 32 bit raw data) .TP u8bit (unsigned 8 bit raw data) .TP vtk (Visualization Toolkit) odin-1.8.5/cmdline-utils/genmakefile.10000644000175000017500000000121511734623244014506 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH GENMAKEFILE "1" "March 2012" "genmakefile 1.8.5" "User Commands" .SH NAME genmakefile \- Generates a Makefile for ODIN methods .SH SYNOPSIS .B genmakefile [\fIoptions\fR] \fI\fR .SH DESCRIPTION genmakefile: Generates a Makefile for ODIN methods .SH OPTIONS .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/cmdline-utils/miconv.10000644000175000017500000002073611734623245013544 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH MICONV "1" "March 2012" "miconv 1.8.5" "User Commands" .SH NAME miconv \- Converts medical image data between formats. .SH SYNOPSIS .B miconv [\fIoptions\fR] \fI \fR[\fI\fR] .SH DESCRIPTION miconv: Converts medical image data between formats. .IP File formats are automatically identified by their file extension. It expects at least two filenames/directories (for the input and output file) at the end of the command line. An exception is the option '\-l' which requires only one filename/directory to list its content. .SS "General options:" .HP \fB\-l\fR: Lists space\-separated set of protocol parameters and exits. Use '\-l help' to get a list of possible parameters and '\-l all' to list all parameters. The parameter 'output\-file' must be omitted when using this option. .HP \fB\-p\fR: Load this protcol for defaults .SS "Protocol options:" .HP \fB\-date\fR: Date of scan [yyyymmdd] (default=20120328yyyymmdd) .HP \fB\-fp\fR: FOV in phase direction [mm] (default=220.0mm) .HP \fB\-fr\fR: FOV in read direction [mm] (default=220.0mm) .HP \fB\-fs\fR: FOV in slice direction [mm] (default=5.0mm) .HP \fB\-nr\fR: Number of consecutive measurements (default=1) .HP \fB\-nx\fR: Number of points in read direction (default=128) .HP \fB\-ny\fR: Number of points in phase direction (default=128) .HP \fB\-nz\fR: Number of points in slice direction (default=1) .HP \fB\-pbirth\fR: Patients date of birth [yyyymmdd] (default=00000000yyyymmdd) .HP \fB\-pid\fR: Unique patient identifier (default=Unknown) .HP \fB\-pname\fR: Full patient name (default=Unknown) .HP \fB\-psex\fR: Patients sex (options=M F O , default=O) .HP \fB\-pweight\fR: Patients weight [kg] (default=50.0kg) .HP \fB\-scient\fR: Scientist Name (default=Unknown) .HP \fB\-sd\fR: Inter\-slice distance (from center to center) [mm] (default=10.0mm) .HP \fB\-serd\fR: Series Description (default=Unknown) .HP \fB\-serno\fR: Series Number (default=1) .HP \fB\-st\fR: Slice thickness [mm] (default=5.0mm) .HP \fB\-stud\fR: Study Description (default=Unknown) .HP \fB\-tcname\fR: Name of transmit coil (default=Unknown) .HP \fB\-te\fR: Time\-to\-echo of the sequence [ms] (default=80.0ms) .HP \fB\-time\fR: Time of scan [hhmmss] (default=165637hhmmss) .HP \fB\-tr\fR: Time between consecutive excitations [ms] (default=1000.0ms) .SS "File read options:" .HP \fB\-cplx\fR: Treat data as complex and extract the given component (options=none abs pha real imag , default=none) .HP \fB\-ds\fR: Dataset index to extract if multiple datasets are read .HP \fB\-filter\fR: Read only those datasets which protocol parameter 'key' contains the string 'value' (given in the format 'key=value') .HP \fB\-fmap\fR: For reduced memory usage, keep filemapping after reading (raw) data, but writing into the array will result in a crash .HP \fB\-jdx\fR: If multiple JDX arrays are present, select this .HP \fB\-rdialect\fR: Read data using given dialect of the format. (default is no dialect) .HP \fB\-rf\fR: Read format, use it to override file extension (options=autodetect 3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk , default=autodetect) .HP \fB\-skip\fR: Skip this amount of bytes before reading the raw data (default=0) .SS "File write options:" .HP \fB\-append\fR: Append to existing file, only for raw data .HP \fB\-fnamepar\fR: Space\-separated list of protocol parameters to include when creating unique file names .HP \fB\-split\fR: Force splitting of protocol\-data pairs into separate files. .HP \fB\-type\fR: Image representation type (options=automatic float double s32bit u32bit s16bit u16bit s8bit u8bit , default=automatic) .HP \fB\-wdialect\fR: Write data using given dialect of the format. (default is no dialect) .HP \fB\-wf\fR: Write format, use it to override file extension (options=autodetect 3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk , default=autodetect) .HP \fB\-wp\fR: Store the protocol separately to this file. .SS "Filters:" .HP \fB\-align\fR : Align data to the geometry (voxel locations) of an external file .HP \fB\-automask\fR : Create mask using automatic histogram\-based threshold .HP \fB\-detrend\fR : Remove slow drift over time .HP \fB\-genmask\fR : Create mask including all voxels with value in given range .HP \fB\-isotrop\fR : make image voxels isotrop through interpolation (image geometry will not change) .HP \fB\-lowpass\fR : Lowpass filtering .HP \fB\-max\fR : Clip all values above maximum value .HP \fB\-maxip\fR : Perform maximum intensity projection over given direction .HP \fB\-merge\fR : Merge datasets into a single dataset by expanding the time dimension .HP \fB\-min\fR : Clip all values below mininum value .HP \fB\-minip\fR : Perform minimum intensity projection over given direction .HP \fB\-noNaN\fR : Replaces every NaN by the given value .HP \fB\-pflip\fR : Flip data in phase direction .HP \fB\-prange\fR : Select range in phase direction .HP \fB\-proj\fR : Perform projection over given direction .HP \fB\-quantilmask\fR : Create mask including all voxels above the given fractional threshold .HP \fB\-resample\fR : Temporal resize of image data .HP \fB\-resize\fR : Spatial resize of image data .HP \fB\-reslice\fR : reslices the image to a given orientation .HP \fB\-rflip\fR : Flip data in read direction .HP \fB\-rot\fR : In\-plane rotation .HP \fB\-rrange\fR : Select range in read direction .HP \fB\-scale\fR : Rescale image values .HP \fB\-sflip\fR : Flip data in slice direction .HP \fB\-shift\fR : Shift data spatially .HP \fB\-splice\fR : splices the image in the given direction .HP \fB\-srange\fR : Select range in slice direction .HP \fB\-swapdim\fR <[rps][\-],[rps][\-],[rps][\-]> : swap/reflect dimensions by specifying a direction triple with optional reflection sign appended .HP \fB\-tile\fR : Combine slices into a square 2D image .HP \fB\-trange\fR : Select range in time direction .HP \fB\-typemax\fR : Clip all values above maximum of a specific datatype .HP \fB\-typemin\fR : Clip all values below mininum of a specific datatype .HP \fB\-usemask\fR : Create 1D dataset including all values within mask from file .SS "Other options:" .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information .SS "Supported file extensions(formats):" .TP 3db (Iris3D binary data) .TP asc (ASCII, dialects: tcourse ) .TP coi (JCAMP\-DX data sets) .TP dat (Matlab ascii 2D data matrix) .TP dcm (DICOM, dialects: siemens ) .TP double (double raw data) .TP float (float raw data) .TP gz (GNU\-Zip container for other formats) .TP hdr (NIFTI/ANALYZE, dialects: fsl ) .TP idx (3D\-indices of non\-zeroes in ASCII) .TP ima (DICOM, dialects: siemens ) .TP jdx (JCAMP\-DX image format) .TP mag (DICOM, dialects: siemens ) .TP mhd (MetaImage) .TP nii (NIFTI/ANALYZE, dialects: fsl ) .TP ph (DICOM, dialects: siemens ) .TP png (Portable Network Graphics) .TP pos (x\-y positions of non\-zeroes in ASCII) .TP pro (ODIN measurement protocols) .TP reg (Ansoft HFSS ASCII) .TP s16bit (signed 16 bit raw data) .TP s32bit (signed 32 bit raw data) .TP s8bit (signed 8 bit raw data) .TP smp (JCAMP\-DX data sets) .TP u16bit (unsigned 16 bit raw data) .TP u32bit (unsigned 32 bit raw data) .TP u8bit (unsigned 8 bit raw data) .TP vtk (Visualization Toolkit) odin-1.8.5/cmdline-utils/gencoil.10000644000175000017500000000265511734623247013673 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH GENCOIL "1" "March 2012" "gencoil 1.8.5" "User Commands" .SH NAME gencoil \- Generates a virtual coil suitable for sequence simulation in ODIN .SH DESCRIPTION gencoil: Generates a virtual coil suitable for sequence simulation in ODIN .SS "Usage and options:" .IP Generate a radially inhomogenous coil: .IP gencoil \fB\-rad\fR \fB\-n\fR \fB\-fov\fR \fB\-R\fR \fB\-o\fR .IP Generate an array coil by rotating pre\-existing image file: .IP gencoil \fB\-rot\fR \fB\-n\fR \fB\-fov\fR \fB\-nc\fR \fB\-i\fR \fB\-sl\fR \fB\-o\fR .IP Generate an array coil consisting of simple loops: .TP gencoil \fB\-arr\fR \fB\-n\fR \fB\-nc\fR \fB\-fov\fR \fB\-R\fR \fB\-o\fR .IP Generate coil with a B1 gradient: .IP gencoil \fB\-grad\fR \fB\-n\fR \fB\-fov\fR \fB\-g\fR \fB\-o\fR .SS "Other options:" .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/cmdline-utils/Makefile.am0000644000175000017500000000273411322062353014207 00000000000000if ONLY_LIBS else INCLUDES = $(all_includes) bin_PROGRAMS = odintestsuite gencoil gensample genmakefile miconv micalc swab odintestsuite_SOURCES = odintestsuite.cpp gencoil_SOURCES = gencoil.cpp gensample_SOURCES = gensample.cpp genmakefile_SOURCES = genmakefile.cpp miconv_SOURCES = miconv.cpp micalc_SOURCES = micalc.cpp swab_SOURCES = swab.cpp odintestsuite_LDADD = ../odindata/libodindata.la ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la gencoil_LDADD = ../odindata/libodindata.la ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la gensample_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la genmakefile_LDADD = ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la miconv_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la micalc_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la swab_LDADD = # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = gencoil.1 gensample.1 genmakefile.1 miconv.1 micalc.1 swab.1 manual: $(bin_PROGRAMS) for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done endif clean-local: -rm -rf *.usage odin-1.8.5/cmdline-utils/Makefile.in0000644000175000017500000006071011734622602014224 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ONLY_LIBS_FALSE@bin_PROGRAMS = odintestsuite$(EXEEXT) \ @ONLY_LIBS_FALSE@ gencoil$(EXEEXT) gensample$(EXEEXT) \ @ONLY_LIBS_FALSE@ genmakefile$(EXEEXT) miconv$(EXEEXT) \ @ONLY_LIBS_FALSE@ micalc$(EXEEXT) swab$(EXEEXT) subdir = cmdline-utils DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__gencoil_SOURCES_DIST = gencoil.cpp @ONLY_LIBS_FALSE@am_gencoil_OBJECTS = gencoil.$(OBJEXT) gencoil_OBJECTS = $(am_gencoil_OBJECTS) @ONLY_LIBS_FALSE@gencoil_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinseq/libodinseq.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__genmakefile_SOURCES_DIST = genmakefile.cpp @ONLY_LIBS_FALSE@am_genmakefile_OBJECTS = genmakefile.$(OBJEXT) genmakefile_OBJECTS = $(am_genmakefile_OBJECTS) @ONLY_LIBS_FALSE@genmakefile_DEPENDENCIES = ../odinseq/libodinseq.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__gensample_SOURCES_DIST = gensample.cpp @ONLY_LIBS_FALSE@am_gensample_OBJECTS = gensample.$(OBJEXT) gensample_OBJECTS = $(am_gensample_OBJECTS) @ONLY_LIBS_FALSE@gensample_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__micalc_SOURCES_DIST = micalc.cpp @ONLY_LIBS_FALSE@am_micalc_OBJECTS = micalc.$(OBJEXT) micalc_OBJECTS = $(am_micalc_OBJECTS) @ONLY_LIBS_FALSE@micalc_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__miconv_SOURCES_DIST = miconv.cpp @ONLY_LIBS_FALSE@am_miconv_OBJECTS = miconv.$(OBJEXT) miconv_OBJECTS = $(am_miconv_OBJECTS) @ONLY_LIBS_FALSE@miconv_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__odintestsuite_SOURCES_DIST = odintestsuite.cpp @ONLY_LIBS_FALSE@am_odintestsuite_OBJECTS = odintestsuite.$(OBJEXT) odintestsuite_OBJECTS = $(am_odintestsuite_OBJECTS) @ONLY_LIBS_FALSE@odintestsuite_DEPENDENCIES = \ @ONLY_LIBS_FALSE@ ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinseq/libodinseq.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la am__swab_SOURCES_DIST = swab.cpp @ONLY_LIBS_FALSE@am_swab_OBJECTS = swab.$(OBJEXT) swab_OBJECTS = $(am_swab_OBJECTS) swab_DEPENDENCIES = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(gencoil_SOURCES) $(genmakefile_SOURCES) \ $(gensample_SOURCES) $(micalc_SOURCES) $(miconv_SOURCES) \ $(odintestsuite_SOURCES) $(swab_SOURCES) DIST_SOURCES = $(am__gencoil_SOURCES_DIST) \ $(am__genmakefile_SOURCES_DIST) $(am__gensample_SOURCES_DIST) \ $(am__micalc_SOURCES_DIST) $(am__miconv_SOURCES_DIST) \ $(am__odintestsuite_SOURCES_DIST) $(am__swab_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @ONLY_LIBS_FALSE@INCLUDES = $(all_includes) @ONLY_LIBS_FALSE@odintestsuite_SOURCES = odintestsuite.cpp @ONLY_LIBS_FALSE@gencoil_SOURCES = gencoil.cpp @ONLY_LIBS_FALSE@gensample_SOURCES = gensample.cpp @ONLY_LIBS_FALSE@genmakefile_SOURCES = genmakefile.cpp @ONLY_LIBS_FALSE@miconv_SOURCES = miconv.cpp @ONLY_LIBS_FALSE@micalc_SOURCES = micalc.cpp @ONLY_LIBS_FALSE@swab_SOURCES = swab.cpp @ONLY_LIBS_FALSE@odintestsuite_LDADD = ../odindata/libodindata.la ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@gencoil_LDADD = ../odindata/libodindata.la ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@gensample_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@genmakefile_LDADD = ../odinseq/libodinseq.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@miconv_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@micalc_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la @ONLY_LIBS_FALSE@swab_LDADD = # Manual pages for distribution @ONLY_LIBS_FALSE@dist_man_MANS = gencoil.1 gensample.1 genmakefile.1 miconv.1 micalc.1 swab.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu cmdline-utils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu cmdline-utils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list gencoil$(EXEEXT): $(gencoil_OBJECTS) $(gencoil_DEPENDENCIES) @rm -f gencoil$(EXEEXT) $(CXXLINK) $(gencoil_OBJECTS) $(gencoil_LDADD) $(LIBS) genmakefile$(EXEEXT): $(genmakefile_OBJECTS) $(genmakefile_DEPENDENCIES) @rm -f genmakefile$(EXEEXT) $(CXXLINK) $(genmakefile_OBJECTS) $(genmakefile_LDADD) $(LIBS) gensample$(EXEEXT): $(gensample_OBJECTS) $(gensample_DEPENDENCIES) @rm -f gensample$(EXEEXT) $(CXXLINK) $(gensample_OBJECTS) $(gensample_LDADD) $(LIBS) micalc$(EXEEXT): $(micalc_OBJECTS) $(micalc_DEPENDENCIES) @rm -f micalc$(EXEEXT) $(CXXLINK) $(micalc_OBJECTS) $(micalc_LDADD) $(LIBS) miconv$(EXEEXT): $(miconv_OBJECTS) $(miconv_DEPENDENCIES) @rm -f miconv$(EXEEXT) $(CXXLINK) $(miconv_OBJECTS) $(miconv_LDADD) $(LIBS) odintestsuite$(EXEEXT): $(odintestsuite_OBJECTS) $(odintestsuite_DEPENDENCIES) @rm -f odintestsuite$(EXEEXT) $(CXXLINK) $(odintestsuite_OBJECTS) $(odintestsuite_LDADD) $(LIBS) swab$(EXEEXT): $(swab_OBJECTS) $(swab_DEPENDENCIES) @rm -f swab$(EXEEXT) $(CXXLINK) $(swab_OBJECTS) $(swab_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gencoil.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/genmakefile.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gensample.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/micalc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miconv.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odintestsuite.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swab.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-man uninstall-man1 # Auto-generate manual pages, only if not in srcdir @ONLY_LIBS_FALSE@%.1: % @ONLY_LIBS_FALSE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @ONLY_LIBS_FALSE@manual: $(bin_PROGRAMS) @ONLY_LIBS_FALSE@ for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done clean-local: -rm -rf *.usage # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/cmdline-utils/odintestsuite.cpp0000644000175000017500000000450711735132611015565 00000000000000//program to preform a unit test on crucial ODIN components #include #include // Avoid including lots of header void alloc_TjToolsTest(); void alloc_ComplexTest(); void alloc_VectorTest(); void alloc_ValListTest(); void alloc_ListTest(); void alloc_StringTest(); void alloc_NumericsTest(); void alloc_StlTest(); void alloc_NdimTest(); void alloc_ArrayTest(); void alloc_IndexTest(); void alloc_ProcessTest(); void alloc_ThreadTest(); void alloc_DownhillSimplexTest(); void alloc_JDXstringArrTest(); void alloc_JDXintArrTest(); void alloc_JDXcomplexArrTest(); void alloc_GeometryTest(); void alloc_JDXintTest(); void alloc_JDXstringTest(); void alloc_JDXcomplexTest(); void alloc_JDXboolTest(); void alloc_JDXenumTest(); void alloc_JDXfileNameTest(); void alloc_CoilSensitivityTest(); void alloc_ProtocolTest(); void alloc_DataUtilsTest(); void alloc_DataTest(); void alloc_ComplexDataTest(); void alloc_FileIOTest(); #ifndef FILEIO_ONLY void alloc_FunctionFitTest(); void alloc_LinAlgTest(); void alloc_FunctionIntegralTest(); void alloc_StatisticsTest(); void alloc_GriddingTest(); #endif //FILEIO_ONLY int main(int argc, char* argv[]) { if(LogBase::set_log_levels(argc,argv)) return 0; if(hasHelpOption(argc,argv)) {STD_cout << "UnitTest of ODIN" << STD_endl; return 0;} #ifdef NO_UNIT_TEST STD_cout << "UnitTest disabled" << STD_endl; return 0; #else alloc_TjToolsTest(); alloc_ComplexTest(); alloc_VectorTest(); alloc_ValListTest(); alloc_ListTest(); alloc_StringTest(); alloc_NumericsTest(); alloc_StlTest(); alloc_NdimTest(); alloc_ArrayTest(); alloc_IndexTest(); alloc_ProcessTest(); alloc_ThreadTest(); alloc_JDXintTest(); alloc_JDXstringTest(); alloc_JDXcomplexTest(); alloc_JDXboolTest(); alloc_JDXenumTest(); alloc_JDXfileNameTest(); alloc_JDXstringArrTest(); alloc_JDXintArrTest(); alloc_JDXcomplexArrTest(); alloc_GeometryTest(); alloc_CoilSensitivityTest(); alloc_ProtocolTest(); alloc_DataUtilsTest(); alloc_DataTest(); alloc_ComplexDataTest(); alloc_FileIOTest(); #ifndef FILEIO_ONLY alloc_FunctionFitTest(); alloc_LinAlgTest(); alloc_FunctionIntegralTest(); alloc_StatisticsTest(); alloc_GriddingTest(); #endif //FILEIO_ONLY int result=UnitTest::check_all(); Static::destroy_all(); // testing StaticHandler return result; #endif } odin-1.8.5/cmdline-utils/genmakefile.cpp0000644000175000017500000000154011322062353015120 00000000000000#include /** * \page genmakefile Generate a Makefile for ODIN sequences * \verbinclude cmdline-utils/genmakefile.usage */ void usage() { STD_cout << "genmakefile: Generates a Makefile for ODIN methods" << STD_endl; STD_cout << "Usage: genmakefile [options] " << STD_endl; STD_cout << "Options:" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } int main(int argc, char* argv[]) { LogBase::set_log_levels(argc,argv); if(hasHelpOption(argc,argv)) {usage(); return 0;} char buff[ODIN_MAXCHAR]; if(argc<=1) {usage(); exit(0);} STD_string methlabel; if(getLastArgument(argc,argv,buff,ODIN_MAXCHAR)) { methlabel=buff; } SeqMakefile mf(methlabel,INSTALL_PREFIX); STD_cout << mf.get_Makefile(".") << STD_endl; return 0; } odin-1.8.5/cmdline-utils/swab.10000644000175000017500000000102711734623244013174 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH SWAB: "1" "March 2012" "swab: Mirrors bytes, in the case of 2, it swaps adjacent bytes" "User Commands" .SH NAME swab: \- Mirrors bytes, in the case of 2, it swaps adjacent bytes .SH SYNOPSIS .B swab \fI \fR .SH DESCRIPTION swab: Mirrors bytes, in the case of 2, it swaps adjacent bytes .PP Usage: swab odin-1.8.5/cmdline-utils/gensample.cpp0000644000175000017500000003771111363773560014653 00000000000000#include #include /** * \page gensample Generate a sample file * \verbinclude cmdline-utils/gensample.usage */ void inplane_reduction(Data& map, int factor) { if(factor>1) { TinyVector newshape=map.shape(); newshape(3)/=factor; newshape(2)/=factor; map.congrid(newshape); } } farray create_map(const Data& inmap) { Range all=Range::all(); TinyVector inshape=inmap.shape(); Data outmap(inshape(0),1,inshape(1),inshape(2),inshape(3)); outmap(all,0,all,all,all)=inmap; return outmap; } ///////////////////////////////////////////////////////////////////////////////////////////////// void usage(const STD_string& missing_arg="") { STD_cout << STD_endl; STD_cout << "gensample: Generates a virtual sample suitable for sequence simulation in ODIN" << STD_endl; STD_cout << STD_endl; STD_cout << "Usage and options:" << STD_endl; STD_cout << " Create a sample from external maps:" << STD_endl; STD_cout << " gensample -fr -fp -fs -s0 [-t1 ] [-t2 ] [-pm ] [-ir ] [-ss ] [-fr ] -o " << STD_endl; STD_cout << " Create a point-spread function:" << STD_endl; STD_cout << " gensample -psf -t1 -t2 [-dc ] -o " << STD_endl; STD_cout << " Create rectangle of uniform spin distribution about origin in all 3 spatial dimensions:" << STD_endl; STD_cout << " gensample -uni -n -f [-t1 ] [-t2 ] -o " << STD_endl; STD_cout << " Create an isochromat distribution:" << STD_endl; STD_cout << " gensample -iso -n -df -t1 -t2 [-dc ] -o " << STD_endl; STD_cout << " Create a homogenous disk with given radius:" << STD_endl; STD_cout << " gensample -dsk -n -f -R [-t1 ] [-t2 ] [-dc ] -o " << STD_endl; STD_cout << " Create coaxial cylinder:" << STD_endl; STD_cout << " gensample -cyl -n -f -Xi -Xo -Ri -Ro [-t1 -t2 -sl ] -o " << STD_endl; STD_cout << "Other options:" << STD_endl; STD_cout << " " << LogBase::get_usage() << STD_endl; STD_cout << " " << helpUsage() << STD_endl; if(missing_arg!="") STD_cout << "Missing argument: -" << missing_arg << STD_endl; } int main(int argc, char* argv[]) { LogBase::set_log_levels(argc,argv); Log odinlog("gensample","main"); if(hasHelpOption(argc,argv)) {usage(); return 0;} Range all=Range::all(); char optval[ODIN_MAXCHAR]; STD_string phantom_fname; if(getCommandlineOption(argc,argv,"-o",optval,ODIN_MAXCHAR)) phantom_fname=optval; else {usage("o");exit(0);} Sample sample("Virtual Sample",false); bool valid_mode=false; ////////////////////////////////////////////////////////////////////////////////////////////////////////// if(isCommandlineOption(argc,argv,"-psf")) { ODINLOG(odinlog,infoLog) << "Creating point spread function" << STD_endl; float t1=0.0; float t2=0.0; float D=0.0; if(getCommandlineOption(argc,argv,"-t1",optval,ODIN_MAXCHAR)) t1=atof(optval); else {usage("t1");exit(0);} if(getCommandlineOption(argc,argv,"-t2",optval,ODIN_MAXCHAR)) t2=atof(optval); else {usage("t2");exit(0);} if(getCommandlineOption(argc,argv,"-dc",optval,ODIN_MAXCHAR)) D=atof(optval); sample.resize(1,1,1,1,1); farray point(sample.get_extent()); point=1.0; sample.set_spinDensity(point); point=t1; sample.set_T1map(point); point=t2; sample.set_T2map(point); point=D; sample.set_DcoeffMap(point); sample.set_FOV(10.0); valid_mode=true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// if(isCommandlineOption(argc,argv,"-iso")) { ODINLOG(odinlog,infoLog) << "Creating isochromat distribution" << STD_endl; float t1,t2,df; int n; float D=0; if(getCommandlineOption(argc,argv,"-df",optval,ODIN_MAXCHAR)) df=atof(optval); else {usage("df");exit(0);} if(getCommandlineOption(argc,argv,"-t1",optval,ODIN_MAXCHAR)) t1=atof(optval); else {usage("t1");exit(0);} if(getCommandlineOption(argc,argv,"-t2",optval,ODIN_MAXCHAR)) t2=atof(optval); else {usage("t2");exit(0);} if(getCommandlineOption(argc,argv,"-n" ,optval,ODIN_MAXCHAR)) n=atoi(optval); else {usage("n");exit(0);} if(getCommandlineOption(argc,argv,"-dc",optval,ODIN_MAXCHAR)) D=atof(optval); float total_width=4.0*df; sample.resize(1,n,1,1,1); sample.set_freqrange(total_width); farray map(sample.get_extent()); map=t1; sample.set_T1map(map); map=t2; sample.set_T2map(map); map=D; sample.set_DcoeffMap(map); float sum=0.0; for(int i=0; i=0) nz=1; ODINLOG(odinlog,infoLog) << "nx/nz=" << nx << "/" << nz << STD_endl; ODINLOG(odinlog,infoLog) << "Initializing sample ..." << STD_endl; sample.resize(1,1,nz,1,nx); // x-z-plane sample.set_FOV(xAxis, fov); sample.set_FOV(yAxis, 1.0); sample.set_FOV(zAxis, fov); if(sl>=0) sample.set_FOV(zAxis, fov/n); ODINLOG(odinlog,infoLog) << "Initializing maps ..." << STD_endl; farray map(sample.get_extent()); farray sdmap (sample.get_extent()); sdmap=1.0; ODINLOG(odinlog,infoLog) << "Setting T1/T2 maps " << STD_endl; if(t1>0.0) {map=t1; sample.set_T1map(map);} if(t2>0.0) {map=t2; sample.set_T2map(map);} ODINLOG(odinlog,infoLog) << "Calculating sample ..." << STD_endl; map=0.0; ndim ii(n_sampleDim); ii[frameDim]=0; ii[freqDim]=0; ii[yDim]=0; for(int iz=0; iz=0) z=(double(sl)/double(n)-0.5)*fov; float r=norm(x,z); ii[zDim]=iz; ii[xDim]=ix; if(r>=Ri && r<=Ro) { if(Xo==0.0 && Xi==0.0) map(ii)=0.0; else { float factor=0.5*(Xo-Xi)*Ri*Ri; map(ii)=1.0-Xo/6.0 + secureDivision(factor*(x*x-z*z),r*r*r*r); } } else { sdmap(ii)=0.0; } } } ODINLOG(odinlog,infoLog) << "Setting spinDensity/ppmMap maps ..." << STD_endl; sample.set_spinDensity(sdmap); sample.set_ppmMap(map); valid_mode=true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// if(isCommandlineOption(argc,argv,"-dsk")) { ODINLOG(odinlog,infoLog) << "Creating disk" << STD_endl; float t1=0.0; float t2=0.0; float fov,R; int n; int nz=1; //20; float D=0; if(getCommandlineOption(argc,argv,"-t1",optval,ODIN_MAXCHAR)) t1=atof(optval); if(getCommandlineOption(argc,argv,"-t2",optval,ODIN_MAXCHAR)) t2=atof(optval); if(getCommandlineOption(argc,argv,"-dc",optval,ODIN_MAXCHAR)) D=atof(optval); if(getCommandlineOption(argc,argv,"-n" ,optval,ODIN_MAXCHAR)) n=atoi(optval); else {usage("n");exit(0);} if(getCommandlineOption(argc,argv,"-f" ,optval,ODIN_MAXCHAR)) fov=atof(optval);else {usage("f");exit(0);} if(getCommandlineOption(argc,argv,"-R" ,optval,ODIN_MAXCHAR)) R=atof(optval); else {usage("R");exit(0);} ODINLOG(odinlog,infoLog) << "Initializing sample ..." << STD_endl; sample.resize(1,1,nz,n,n); sample.set_FOV(xAxis, fov); sample.set_FOV(yAxis, fov); sample.set_FOV(zAxis, nz); ODINLOG(odinlog,infoLog) << "Initializing maps ..." << STD_endl; farray sdmap (sample.get_extent()); sdmap=0.0; farray Dmap (sample.get_extent()); Dmap=0.0; ODINLOG(odinlog,infoLog) << "Setting T1/T2 " << STD_endl; if(t1>0.0) {sample.set_T1(t1);} if(t2>0.0) {sample.set_T2(t2);} ODINLOG(odinlog,infoLog) << "Calculating sample ..." << STD_endl; for(int iy=0; iy0.0) {map=t1; sample.set_T1map(map);} if(t2>0.0) {map=t2; sample.set_T2map(map);} if(t2>0.0) {map=1.0; sample.set_spinDensity(map);} valid_mode=true; } ////////////////////////////////////////////////////////////////////////////////////////////////////////// if(!valid_mode) { ODINLOG(odinlog,infoLog) << "Combining arrays" << STD_endl; int inplane_reduction_factor=1; int single_slice=-1; dvector frame_durations; float FOVread; float FOVphase; float FOVslice; STD_string S0map_fname; STD_string T1map_fname; STD_string T2map_fname; STD_string ppmMap_fname; if(getCommandlineOption(argc,argv,"-fr",optval,ODIN_MAXCHAR)) FOVread=atof(optval); else {usage("fr");exit(0);} if(getCommandlineOption(argc,argv,"-fp",optval,ODIN_MAXCHAR)) FOVphase=atof(optval); else {usage("fp");exit(0);} if(getCommandlineOption(argc,argv,"-fs",optval,ODIN_MAXCHAR)) FOVslice=atof(optval); else {usage("fs");exit(0);} if(getCommandlineOption(argc,argv,"-s0",optval,ODIN_MAXCHAR)) S0map_fname=optval; else {usage("s0");exit(0);} if(getCommandlineOption(argc,argv,"-t1",optval,ODIN_MAXCHAR)) T1map_fname=optval; if(getCommandlineOption(argc,argv,"-t2",optval,ODIN_MAXCHAR)) T2map_fname=optval; if(getCommandlineOption(argc,argv,"-pm",optval,ODIN_MAXCHAR)) ppmMap_fname=optval; if(getCommandlineOption(argc,argv,"-ir",optval,ODIN_MAXCHAR)) inplane_reduction_factor=atoi(optval); if(getCommandlineOption(argc,argv,"-ss",optval,ODIN_MAXCHAR)) single_slice=atoi(optval); int nframes_arg=0; if(getCommandlineOption(argc,argv,"-fr",optval,ODIN_MAXCHAR)) { svector toks=tokens(optval,','); nframes_arg=toks.size(); ODINLOG(odinlog,infoLog) << "nframes_arg=" << nframes_arg << STD_endl; frame_durations.resize(nframes_arg); for(unsigned int i=0; i filedata_s0; filedata_s0.autoread(S0map_fname); nframes_max=STD_max(nframes_max, filedata_s0.extent(0)); Data filedata_t1; if(T1map_fname!="") filedata_t1.autoread(T1map_fname); nframes_max=STD_max(nframes_max, filedata_t1.extent(0)); Data filedata_t2; if(T2map_fname!="") filedata_t2.autoread(T2map_fname); nframes_max=STD_max(nframes_max, filedata_t2.extent(0)); Data filedata_ppmmap; if(ppmMap_fname!="") filedata_ppmmap.autoread(ppmMap_fname); nframes_max=STD_max(nframes_max, filedata_ppmmap.extent(0)); ODINLOG(odinlog,infoLog) << "nframes_max=" << nframes_max << STD_endl; if(nframes_max==nframes_arg) { sample.set_frame_durations(frame_durations); } else { ODINLOG(odinlog,infoLog) << "nframes_max(" << nframes_max << ") != nframes_arg(" << nframes_arg << ")" << STD_endl; return -1; } if(single_slice>=0) { FOVslice/=filedata_s0.extent(1); filedata_s0.reference(filedata_s0(all,Range(single_slice,single_slice),all,all)); if(filedata_t1.size()) { filedata_t1.reference(filedata_t1(all,Range(single_slice,single_slice),all,all)); } if(filedata_t2.size()) { filedata_t2.reference(filedata_t2(all,Range(single_slice,single_slice),all,all)); } if(filedata_ppmmap.size()) { filedata_ppmmap.reference(filedata_t2(all,Range(single_slice,single_slice),all,all)); } } /* for(int i=0; i index=filedata_s0.create_index(i); bool valid_voxel=true; if(filedata_s0(index)<=0.0) valid_voxel=false; if(filedata_t1(index)<=0.0) valid_voxel=false; if(filedata_t2(index)<=0.0) valid_voxel=false; if(!valid_voxel) { filedata_s0(index)=0.0; filedata_t1(index)=0.0; filedata_t2(index)=0.0; filedata_ppmmap(index)=0.0; } } */ if(inplane_reduction_factor>1) { inplane_reduction(filedata_s0,inplane_reduction_factor); if(filedata_t1.size()) inplane_reduction(filedata_t1,inplane_reduction_factor); if(filedata_t2.size()) inplane_reduction(filedata_t2,inplane_reduction_factor); if(filedata_ppmmap.size()) inplane_reduction(filedata_ppmmap,inplane_reduction_factor); } TinyVector s0shape=filedata_s0.shape(); sample.resize(s0shape(0),1,s0shape(1),s0shape(2),s0shape(3)); sample.set_FOV(xAxis, FOVread); sample.set_FOV(yAxis, FOVphase); sample.set_FOV(zAxis, FOVslice); sample.set_spinDensity(create_map(filedata_s0)); if(filedata_t1.size()) sample.set_T1map(create_map(filedata_t1)); else sample.set_T1(1000.0); if(filedata_t2.size()) sample.set_T2map(create_map(filedata_t2)); else sample.set_T2(100.0); if(filedata_ppmmap.size()) sample.set_ppmMap(create_map(filedata_ppmmap)); } ODINLOG(odinlog,infoLog) << "sample.get_extent()=" << STD_string(sample.get_extent()) << STD_endl; sample.write(phantom_fname); return 0; } odin-1.8.5/cmdline-utils/gensample.10000644000175000017500000000410011734623245014207 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH GENSAMPLE "1" "March 2012" "gensample 1.8.5" "User Commands" .SH NAME gensample \- Generates a virtual sample suitable for sequence simulation in ODIN .SH DESCRIPTION gensample: Generates a virtual sample suitable for sequence simulation in ODIN .SS "Usage and options:" .IP Create a sample from external maps: .TP gensample \fB\-fr\fR \fB\-fp\fR \fB\-fs\fR \fB\-s0\fR [\-t1 ] [\-t2 ] [\-pm ] [\-ir ] [\-ss ] [\-fr ] \fB\-o\fR .IP Create a point\-spread function: .IP gensample \fB\-psf\fR \fB\-t1\fR \fB\-t2\fR [\-dc ] \fB\-o\fR .IP Create rectangle of uniform spin distribution about origin in all 3 spatial dimensions: .IP gensample \fB\-uni\fR \fB\-n\fR \fB\-f\fR [\-t1 ] [\-t2 ] \fB\-o\fR .IP Create an isochromat distribution: .IP gensample \fB\-iso\fR \fB\-n\fR \fB\-df\fR \fB\-t1\fR \fB\-t2\fR [\-dc ] \fB\-o\fR .IP Create a homogenous disk with given radius: .IP gensample \fB\-dsk\fR \fB\-n\fR \fB\-f\fR \fB\-R\fR [\-t1 ] [\-t2 ] [\-dc ] \fB\-o\fR .IP Create coaxial cylinder: .IP gensample \fB\-cyl\fR \fB\-n\fR \fB\-f\fR \fB\-Xi\fR \fB\-Xo\fR \fB\-Ri\fR \fB\-Ro\fR [\-t1 \fB\-t2\fR \fB\-sl\fR ] \fB\-o\fR .SS "Other options:" .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/configure.in0000644000175000017500000006675111714537614011740 00000000000000dnl Boilerplate AC_INIT(tjutils/tjutils.h) AC_PREREQ(2.57) AM_INIT_AUTOMAKE(odin,1.8.5) AM_CONFIG_HEADER(tjutils/config.h) AC_PREFIX_DEFAULT(/usr/local) if test "x$prefix" = "xNONE"; then prefix=$ac_default_prefix ac_configure_args="$ac_configure_args --prefix $prefix" fi dnl Options AC_ARG_ENABLE([debug], [AC_HELP_STRING([--enable-debug],[Include code for debugging/tracing])], enable_debug=yes ) AC_ARG_ENABLE([stdcpp-replacement], [AC_HELP_STRING([--enable-stdcpp-replacement],[Use built-in replacement for C++ standard library (STL, strings, streams)])], enable_stdcpp_replacement=yes ) AC_ARG_ENABLE([custom-heap], [AC_HELP_STRING([--enable-custom-heap=SIZE],[Use a heap which is a static block of memory (SIZE MB large), useful for real-time systems which do not have a safe new/delete])], enable_custom_heap=yes custom_heap_size=$enableval if test "$enableval" = "yes"; then custom_heap_size=2; fi ) AC_ARG_ENABLE([cmdline], [AC_HELP_STRING([--disable-cmdline],[Disable code for the command line, useful for real-time systems])], enable_cmdline=no, enable_cmdline=yes ) AC_ARG_ENABLE([filehandling], [AC_HELP_STRING([--disable-filehandling],[Disable code for file handling, useful if ODIN is used on a platform without file system])], enable_filehandling=no, enable_filehandling=yes ) AC_ARG_ENABLE([threads], [AC_HELP_STRING([--disable-threads],[Disable multithreading])], enable_threads=no, enable_threads=yes ) AC_ARG_ENABLE([unit-test], [AC_HELP_STRING([--disable-unit-test],[Disable unit test])], enable_unittest=no, enable_unittest=yes ) AC_ARG_ENABLE([gui], [AC_HELP_STRING([--disable-gui],[Disable graphical user interface])], enable_gui=no, enable_gui=yes ) AC_ARG_ENABLE([only-corelibs], [AC_HELP_STRING([--enable-only-corelibs],[Compile only the essential libraries for sequence execution (tjutils/odinpara/odinseq)])], enable_onlylibs=yes ) srcdir_abs=$(cd "$srcdir" && pwd) have_ideaplugin=no have_paravisionplugin=no have_standaloneplugin=no have_epicplugin=no if test -d $srcdir_abs/platforms/IDEA_n4 ; then have_ideaplugin=yes ; fi if test -d $srcdir_abs/platforms/Paravision ; then have_paravisionplugin=yes ; fi if test -d $srcdir_abs/platforms/StandAlone ; then have_standaloneplugin=yes ; fi if test -d $srcdir_abs/platforms/EPIC ; then have_epicplugin=yes ; fi enable_ideaplugin=$have_ideaplugin enable_paravisionplugin=$have_paravisionplugin enable_standaloneplugin=$have_standaloneplugin enable_epicplugin=$have_epicplugin AC_ARG_ENABLE([only-epic-plugin], [AC_HELP_STRING([--enable-only-epic-plugin],[Compile only the plugin for Epic])], enable_ideaplugin=no enable_paravisionplugin=no enable_standaloneplugin=no ) AC_ARG_ENABLE([only-idea-plugin], [AC_HELP_STRING([--enable-only-idea-plugin],[Compile only the plugin for IDEA(Siemens)])], enable_paravisionplugin=no enable_standaloneplugin=no enable_epicplugin=no ) AC_ARG_ENABLE([only-paravision-plugin], [AC_HELP_STRING([--enable-only-paravision-plugin],[Compile only the plugin for Paravision(Bruker)])], enable_ideaplugin=no enable_standaloneplugin=no enable_epicplugin=no ) AC_ARG_ENABLE([only-standalone-plugin], [AC_HELP_STRING([--enable-only-standalone-plugin],[Compile only the plugin for stand-alone mode])], enable_ideaplugin=no enable_paravisionplugin=no enable_epicplugin=no ) dnl disable unavailable plugins if test "x$have_ideaplugin" = "xno" ; then enable_ideaplugin=no ; fi if test "x$have_paravisionplugin" = "xno" ; then enable_paravisionplugin=no ; fi if test "x$have_standaloneplugin" = "xno" ; then enable_standaloneplugin=no ; fi if test "x$have_epicplugin" = "xno" ; then enable_epicplugin=no ; fi AC_ARG_ENABLE([ideasupport], [AC_HELP_STRING([--enable-ideasupport],[Compile against IDEA(Siemens) libraries, implies --enable-only-corelibs and --enable-stdcpp-replacement])], enable_ideasupport=yes enable_onlylibs=yes enable_stdcpp_replacement=yes ) AC_ARG_ENABLE([niftisupport], [AC_HELP_STRING([--enable-niftisupport],[Use libniftiio to read/write NIFTI files])], enable_niftisupport="$enableval" ) AC_ARG_ENABLE([vtksupport], [AC_HELP_STRING([--enable-vtksupport],[Use VTK for input/output and visualization])], enable_vtksupport="$enableval" ) AC_ARG_ENABLE([dcmtksupport], [AC_HELP_STRING([--enable-dcmtksupport],[Use DICOMTK to read/write DICOM files])], enable_dcmtksupport="$enableval" ) AC_ARG_ENABLE([pngsupport], [AC_HELP_STRING([--enable-pngsupport],[Use libpng to write PNG files])], enable_pngsupport="$enableval" ) AC_ARG_WITH([qt-dir], [AC_HELP_STRING([--with-qt-dir=DIR],[Base directory of the Qt library])], with_qtdir=$withval ) AC_ARG_WITH([extra-include-base], [AC_HELP_STRING([--with-extra-include-base=DIR],[Extra base to find includes (default=/usr/include)])], extra_include_base=$withval, extra_include_base="/usr/include" ) AC_ARG_WITH([extra-build-cxxflags], [AC_HELP_STRING([--with-extra-build-cxxflags=FLAGS],[Extra compiler flags during ODIN build (but not during sequence compilation)])], extra_cxxflags=$withval ) AC_ARG_WITH([extra-build-ldflags], [AC_HELP_STRING([--with-extra-build-ldflags=FLAGS],[Extra linker flags during ODIN build (but not during sequence compilation)])], extra_ldflags=$withval ) AC_ARG_WITH([extra-odinseq-include-path], [AC_HELP_STRING([--with-extra-odinseq-include-path=PATH],[Extra include path for odinseq during ODIN build (but not during sequence compilation)])], extra_odinseq_includes=$withval ) AC_ARG_WITH([lapack-libname], [AC_HELP_STRING([--with-lapack-libname=LIBNAME],[Library name of LAPACK (default=lapack)])], lapack_libname=$withval, lapack_libname="lapack" ) AC_ARG_WITH([editor], [AC_HELP_STRING([--with-editor=EDITOR],[Initial settings for editor (default=/usr/bin/sensible-editor)])], initial_editor=$withval, initial_editor="/usr/bin/sensible-editor" ) AC_ARG_WITH([browser], [AC_HELP_STRING([--with-browser=BROWSER],[Initial settings for browser (default=/usr/bin/sensible-browser)])], initial_browser=$withval, initial_browser="/usr/bin/sensible-browser" ) dnl Cache user-supplied compiler flags, but ignore compiler flags of AC_PROG_CXX CXXFLAGS_CACHE="$CXXFLAGS" dnl Set C++ as the programming language and check for C++ compiler AC_LANG(C++) AC_PROG_CXX dnl Add compiler flags in debug/release mode if test "x$enable_debug" = "xyes" ; then dnl Disable debugging symbols and warnings when compiling for VxWorks if test "x$enable_ideasupport" = "xyes" ; then CXXFLAGS="-O2" else CXXFLAGS="-O2 -g -Wall" fi AC_MSG_CHECKING(whether compiler accepts debug flag(s) $CXXFLAGS) AC_COMPILE_IFELSE(int main() {return 0;}, AC_MSG_RESULT(yes); EXTRA_CXXFLAGS="$CXXFLAGS", AC_MSG_RESULT(no)) else dnl work around GCC bug CXXFLAGS="-O3 -fno-tree-vectorize" AC_MSG_CHECKING(whether compiler accepts release flag(s) $CXXFLAGS) AC_COMPILE_IFELSE(int main() {return 0;}, AC_MSG_RESULT(yes); EXTRA_CXXFLAGS="$CXXFLAGS", AC_MSG_RESULT(no)) fi CXXFLAGS="$EXTRA_CXXFLAGS $CXXFLAGS_CACHE" dnl Checks for debugger and xterm to attach debugger AC_CHECK_PROGS(GDB, gdb) AC_CHECK_PROGS(XTERM, xterm) dnl libtool stuff AC_ENABLE_SHARED(yes) AC_ENABLE_STATIC(no) AC_PROG_LIBTOOL dnl cache CXXFLAGS/CPPFLAGS/LDFLAGS for sequence compilation before adding extra_ldflags to exclude absolut pathes and Qt libs on windows CXXFLAGS_EXPORT="$CXXFLAGS" CPPFLAGS_EXPORT="$CPPFLAGS" LDFLAGS_EXPORT="$LDFLAGS" dnl add compiler/linker flags for ODIN build CXXFLAGS="$extra_cxxflags $CXXFLAGS" CPPFLAGS="$extra_cxxflags $CPPFLAGS" LDFLAGS="$extra_ldflags $LDFLAGS" case $host in *apple*) macos=yes ;; esac dnl Checks for libraries. if test "x$enable_onlylibs" = "xyes" ; then AC_MSG_NOTICE([Discarding library linking due to --enable-only-corelibs]) else LIBS_RETAIN="$LIBS" AC_CHECK_LIB(m,sin,LIBS="-lm $LIBS"; BASELIBS="-lm $BASELIBS") valid_dl=yes AC_CHECK_LIB(dl,dlopen,LIBS="-ldl $LIBS"; BASELIBS="-ldl $BASELIBS",valid_dl=no) AC_CHECK_HEADER(dlfcn.h,,valid_dl=no) valid_pthread=yes AC_CHECK_LIB(pthread,pthread_create,LIBS="-lpthread $LIBS"; BASELIBS="-lpthread $BASELIBS",valid_pthread=no) AC_CHECK_HEADER(pthread.h,,valid_pthread=no) valid_libz=yes AC_CHECK_LIB(z,main,LIBS="-lz $LIBS"; DATALIBS="-lz $DATALIBS", valid_libz=no) AC_CHECK_HEADER(zlib.h,,valid_libz=no) dnl GSL is used in tjutils and odindata so we add it to the global LIBS valid_gsl=yes AC_CHECK_LIB(gslcblas,main,LIBS="-lgslcblas $LIBS"; BASELIBS="-lgslcblas $BASELIBS") AC_CHECK_LIB(gsl,gsl_multifit_fdfsolver_iterate,BASELIBS="-lgsl $BASELIBS",valid_gsl=no) AC_CHECK_HEADER(gsl/gsl_multifit_nlin.h,,valid_gsl=no) if test "x$valid_gsl" = "xno" ; then AC_MSG_ERROR([Please install the GNU Scientific Library (There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://www.gnu.org/software/gsl)]) fi if test "x$macos" = "xyes" ; then AC_MSG_NOTICE([Using vecLib for lapack support]) valid_lapack=yes lapack_libname="vecLib" else dnl Prerequisites for different lapack implementations if test "$lapack_libname" = "lapack" ; then AC_CHECK_LIB(g2c,i_indx,DATALIBS="-lg2c $DATALIBS"; LIBS="-lg2c $LIBS") fi if test "$lapack_libname" = "acml" ; then AC_CHECK_LIB(acml_mv,main,DATALIBS="-lacml_mv $DATALIBS"; LIBS="-lacml_mv $LIBS") AC_CHECK_LIB(gfortran,main,DATALIBS="-lgfortran $DATALIBS"; LIBS="-lgfortran $LIBS") thread_safe_lapack=yes fi valid_lapack=no AC_CHECK_LIB($lapack_libname,cgelss_,DATALIBS="-l${lapack_libname} $DATALIBS"; valid_lapack=yes) if test "x$valid_lapack" = "xno" ; then AC_MSG_WARN([LAPACK not found (using slower GSL linear algebra instead)]) fi fi valid_blitz=yes AC_CHECK_LIB(blitz,main,DATALIBS="-lblitz $DATALIBS",valid_blitz=no) AC_CHECK_HEADER(blitz/array.h,,valid_blitz=no) AC_CHECK_HEADER(blitz/tinyvec-et.h,,valid_blitz=no) if test "x$valid_blitz" = "xno" ; then AC_MSG_ERROR([Please install Blitz++ (Version 0.8 or higher) in order to use the reconstruction library (There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://www.oonumerics.org/blitz)]) fi dnl optional libraries if test ! "x$enable_niftisupport" = "xno" ; then lib_nifti=yes dnl Hack for Debian if test -d ${extra_include_base}/nifti ; then all_includes="-I${extra_include_base}/nifti $all_includes" fi AC_CHECK_LIB(znz,main,LIBS="-lznz $LIBS"; DATALIBS="-lznz $DATALIBS") AC_CHECK_LIB(niftiio,nifti_image_read,DATALIBS="-lniftiio $DATALIBS",lib_nifti=no) CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" AC_CHECK_HEADER(nifti1_io.h,,lib_nifti=no) CPPFLAGS="$CPPFLAGS_CACHE" if test "x$lib_nifti" = "xno" ; then if test "x$enable_niftisupport" = "xyes" ; then AC_MSG_ERROR([libniftiio missing]) else AC_MSG_WARN([NIFTI I/O library not found, NIFTI support will be disabled]) fi fi fi if test ! "x$enable_vtksupport" = "xno" ; then lib_vtk=yes dnl vtk will also be used by Odin GUI so we add an extra variable VTKLIBS AC_CHECK_LIB(vtkIO,main,DATALIBS="-lvtkIO $DATALIBS",lib_vtk=no) AC_CHECK_LIB(vtkRendering,main,VTKLIBS="-lvtkRendering $VTKLIBS",lib_vtk=no) dnl Hack for Debian for vtk_header_dir in vtk vtk-5.0 vtk-5.2 vtk-5.4 ; do if test -d ${extra_include_base}/${vtk_header_dir} ; then all_includes="-I${extra_include_base}/${vtk_header_dir} $all_includes" fi done CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" AC_CHECK_HEADERS(vtkStructuredPoints.h vtkArrowSource.h,,lib_vtk=no) CPPFLAGS="$CPPFLAGS_CACHE" if test "x$lib_vtk" = "xno" ; then if test "x$enable_vtksupport" = "xyes" ; then AC_MSG_ERROR([VTK library missing]) else AC_MSG_WARN([VTK library (Version 4.4 or higher) not found, VTK support will be disabled]) fi fi fi if test ! "x$enable_dcmtksupport" = "xno" ; then lib_dcmtk=yes dnl Hack for Debian (dcmtk 3.5.3) if test -d ${extra_include_base}/dcmtk ; then all_includes="-I${extra_include_base}/dcmtk -I${extra_include_base}/dcmtk/dcmdata -I${extra_include_base}/dcmtk/ofstd $all_includes" fi CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="-DHAVE_CONFIG_H $all_includes $CPPFLAGS" AC_CHECK_HEADER(dcmtk/dcmdata/dcdatset.h,,lib_dcmtk=no) AC_CHECK_HEADER(dcmtk/dcmimgle/dcmimage.h,,lib_dcmtk=no) CPPFLAGS="$CPPFLAGS_CACHE" AC_CHECK_LIB(wsock32,main,LIBS="-lwsock32 $LIBS"; DATALIBS="-lwsock32 $DATALIBS") AC_CHECK_LIB(ofstd,main,LIBS="-lofstd $LIBS"; DATALIBS="-lofstd $DATALIBS",lib_dcmtk=no) AC_CHECK_LIB(oflog,main,LIBS="-loflog $LIBS"; DATALIBS="-loflog $DATALIBS") AC_CHECK_LIB(dcmdata,main,LIBS="-ldcmdata $LIBS"; DATALIBS="-ldcmdata $DATALIBS",lib_dcmtk=no) AC_CHECK_LIB(dcmimgle,main,LIBS="-ldcmimgle $LIBS"; DATALIBS="-ldcmimgle $DATALIBS",lib_dcmtk=no) if test "x$lib_dcmtk" = "xno" ; then if test "x$enable_dcmtksupport" = "xyes" ; then AC_MSG_ERROR([DICOMTK library missing]) else AC_MSG_WARN([DICOMTK library not found, DICOM support will be disabled]) fi fi fi if test ! "x$enable_pngsupport" = "xno" ; then lib_png=yes AC_CHECK_HEADER(png.h,,lib_png=no) AC_CHECK_LIB(png, png_create_write_struct, DATALIBS="-lpng $DATALIBS",lib_png=no) if test "x$lib_png" = "xno" ; then if test "x$enable_pngsupport" = "xyes" ; then AC_MSG_ERROR([libpng missing]) else AC_MSG_WARN([PNG library not found, PNG support will be disabled]) fi fi fi LIBS="$LIBS_RETAIN" fi dnl Checks for C/C++ stanard headers headers AC_CHECK_HEADERS(dirent.h unistd.h time.h) AC_CHECK_HEADERS(sys/stat.h sys/types.h sys/wait.h sys/time.h sys/mman.h) AC_CHECK_HEADERS(locale.h ctype.h) AC_CHECK_HEADERS(signal.h setjmp.h) AC_CHECK_HEADERS(typeinfo) dnl Checks for Windows headers have_win32_api=yes AC_CHECK_HEADERS(windows.h direct.h io.h,,have_win32_api=no) dnl get size of integral types AC_DEFUN([AC_COMPILE_CHECK_SIZEOF], [changequote(<<, >>)dnl dnl The name to #define. define(<>, translit(sizeof_$1, [a-z *], [A-Z_P]))dnl dnl The cache variable name. define(<>, translit(ac_cv_sizeof_$1, [ *], [_p]))dnl changequote([, ])dnl AC_MSG_CHECKING(size of $1) AC_CACHE_VAL(AC_CV_NAME, [for ac_size in 4 8 1 2 16 $2 ; do # List sizes in rough order of prevalence. AC_TRY_COMPILE([#include "confdefs.h" #include $2 ], [switch (0) case 0: case (sizeof ($1) == $ac_size):;], AC_CV_NAME=$ac_size) if test x$AC_CV_NAME != x ; then break; fi done ]) if test x$AC_CV_NAME = x ; then AC_MSG_ERROR([cannot determine a size for $1]) fi AC_MSG_RESULT($AC_CV_NAME) AC_DEFINE_UNQUOTED(AC_TYPE_NAME, $AC_CV_NAME, [The number of bytes in type $1]) undefine([AC_TYPE_NAME])dnl undefine([AC_CV_NAME])dnl ]) AC_COMPILE_CHECK_SIZEOF(char) AC_COMPILE_CHECK_SIZEOF(short) AC_COMPILE_CHECK_SIZEOF(int) AC_COMPILE_CHECK_SIZEOF(long) AC_DEFUN([AC_C_LONG_LONG], [AC_CACHE_CHECK(for long long int, ac_cv_c_long_long, [if test "$GCC" = yes; then ac_cv_c_long_long=yes else AC_TRY_COMPILE(,[long long int i;], ac_cv_c_long_long=yes, ac_cv_c_long_long=no) fi]) if test $ac_cv_c_long_long = yes; then AC_DEFINE(HAVE_LONG_LONG, 1, [compiler understands long long]) fi ]) AC_C_LONG_LONG dnl Checks for library functions. AC_CHECK_FUNCS([j1 snprintf erfc acosh gettimeofday nanosleep srand read stat sysconf stat64 fopen64 open64 fseeko fseeko64 ftello ftello64 mmap64 strftime strptime]) dnl Add configured LIBS and all_includes to exported compiler/linker flags CXXFLAGS_EXPORT="$CXXFLAGS_EXPORT $all_includes" CPPFLAGS_EXPORT="$CPPFLAGS_EXPORT $all_includes" LDFLAGS_EXPORT="$LDFLAGS_EXPORT $LIBS" dnl Find location of GUI libraries, they will NOT get exported to sequence compilation if test "x$enable_onlylibs" = "xyes" ; then AC_MSG_NOTICE([Discarding Qt linking due to --enable-only-corelibs]) enable_gui=no fi if test "x$enable_gui" = "xyes" ; then if test -z $with_qtdir ; then CONF_QTDIR="$QTDIR" else CONF_QTDIR="$with_qtdir" fi AC_PATH_X if test "$x_includes" = "" ; then x_includes="." fi if test "$x_libraries" = "" ; then x_libraries="." fi if ! test "$x_includes" = "NONE" ; then all_includes="-I$x_includes $all_includes" fi dnl Add X11 libraries which might be necessary for Qt dnl if ! test "$x_libraries" = "NONE" ; then dnl LDFLAGS="-L$x_libraries $LDFLAGS" dnl for xlib in X11 Xext ICE SM Xi Xrender Xfixes Xinerama Xrandr Xcursor Xft ; do dnl AC_CHECK_LIB($xlib,main,GUILIBS="-l${xlib} $GUILIBS") dnl done dnl fi dnl Trying to detect QTDIR if not provided if test -z $CONF_QTDIR ; then AC_MSG_NOTICE([Environment variable QTDIR not specified, searching for Qt:]) qtdir_found=no for qtdir in /usr/share/qt3 /usr/share/qt4 ; do for subdir in "" "QtCore/" ; do if test "x$qtdir_found" = "xno" ; then AC_CHECK_FILE($qtdir/include/${subdir}qglobal.h, qtdir_found=yes; CONF_QTDIR=$qtdir) fi done done if test "x$qtdir_found" = "xno" ; then AC_MSG_ERROR([Qt headers not found]); exit -1 fi fi dnl Detect Qt version, start with Qt3 AC_CHECK_FILE($CONF_QTDIR/include/qglobal.h, QTVERSION="3") AC_CHECK_FILE($CONF_QTDIR/include/QtCore/qglobal.h, QTVERSION="4") if test -z $QTVERSION ; then AC_MSG_ERROR([Cannot detect Qt version]); exit -1 fi dnl Add QTDIR to include path all_includes="-I$CONF_QTDIR/include $all_includes" dnl Add QTDIR to lib path if test ! -z $CONF_QTDIR ; then for extra_qt_libdir in lib lib64 ; do if test -d $CONF_QTDIR/$extra_qt_libdir ; then LDFLAGS="-L$CONF_QTDIR/$extra_qt_libdir $LDFLAGS" fi done fi lib_qt=no if test "$QTVERSION" = "3" ; then if test "x$lib_qt" = "xno" ; then AC_CHECK_LIB(qt-mt,main,GUILIBS="-lqt-mt $GUILIBS"; lib_qt=yes; CXXFLAGS="-DQT_THREAD_SUPPORT $CXXFLAGS") fi if test "x$lib_qt" = "xno" ; then AC_CHECK_LIB(qt,main,GUILIBS="-lqt $GUILIBS"; lib_qt=yes) fi fi if test "$QTVERSION" = "4" ; then AC_MSG_NOTICE([Searching for Qt4 subdirs:]) AC_CHECK_FILE($CONF_QTDIR/include/QtCore/QPointF, all_includes="-I$CONF_QTDIR/include/QtCore $all_includes") AC_CHECK_FILE($CONF_QTDIR/include/QtGui/QPolygonF, all_includes="-I$CONF_QTDIR/include/QtGui $all_includes") for qt4_extension in "" "4" ; do if test "x$lib_qt" = "xno" ; then AC_CHECK_LIB(QtCore${qt4_extension},main,GUILIBS="-lQtCore${qt4_extension} $GUILIBS"; lib_qtcore=yes) if test "x$lib_qtcore" = "xyes" ; then AC_CHECK_LIB(QtGui${qt4_extension},main,GUILIBS="-lQtGui${qt4_extension} $GUILIBS"; lib_qt=yes) fi fi done fi if test "x$lib_qt" = "xno" ; then if test -z "$extra_ldflags"; then AC_MSG_ERROR([Qt library not found]); exit -1 else AC_MSG_NOTICE([Assuming that Qt library was specified by --extra-build-ldflags=$extra_ldflags]) fi fi AC_CHECK_FILE($CONF_QTDIR/bin/moc, QTMOC=$CONF_QTDIR/bin/moc) if test -z $QTMOC ; then AC_MSG_ERROR([Qt moc not found]); exit -1 fi QWT_ERROR_STR="Qwt Widget Library not found. There is probably a precompiled package for your UNIX/Linux distribution, otherwise see http://qwt.sourceforge.net" qwt_lib=no if test "$QTVERSION" = "3" ; then AC_CHECK_LIB(qwt,main,GUILIBS="-lqwt $GUILIBS"; qwt_lib=yes) fi if test "$QTVERSION" = "4" ; then for qwt_extension in "-qt4" "" ; do if test "x$qwt_lib" = "xno" ; then AC_CHECK_LIB(qwt${qwt_extension},main,GUILIBS="-lqwt${qwt_extension} $GUILIBS"; qwt_lib=yes) fi done fi if test "x$qwt_lib" = "xno" ; then AC_MSG_ERROR($QWT_ERROR_STR); exit -1 fi dnl Check for Qwt headers CPPFLAGS_CACHE="$CPPFLAGS" CPPFLAGS="$all_includes $CPPFLAGS" dnl Shell expansion does not work in AC_CHECK_HEADERS, therefore, we unroll the loop over header locations qwt_headers=no if test "$QTVERSION" = "4" ; then if test "x$qwt_headers" = "xno" ; then dnl for Debian AC_CHECK_HEADERS(qwt-qt4/qwt_global.h,qwt_headers=yes) fi fi if test "x$qwt_headers" = "xno" ; then AC_CHECK_HEADERS(qwt/qwt_global.h,qwt_headers=yes) fi CPPFLAGS="$CPPFLAGS_CACHE" if test "x$qwt_headers" = "xno" ; then AC_MSG_ERROR($QWT_ERROR_STR); exit -1 fi fi dnl Checks for typedefs, structures, and compiler characteristics. AC_MSG_CHECKING(whether compiler accepts empty template list) AC_COMPILE_IFELSE(template class TC{static int s;}; template<> int TC::s; int main() {return 0;}, AC_MSG_RESULT(yes); empty_templ_list=yes, AC_MSG_RESULT(no); empty_templ_list=no) AC_MSG_CHECKING(whether compiler accepts/needs self-friend classes) AC_COMPILE_IFELSE(class C{friend class C;}; int main() {return 0;}, AC_MSG_RESULT(yes); self_friend_class=yes, AC_MSG_RESULT(no); self_friend_class=no) dnl Create Defines AC_MSG_NOTICE([------------ Custom ODIN Configuration ------------]) AC_MSG_NOTICE([host=$host]) if test "x$macos" = "xyes" ; then AC_DEFINE(MACOS,,"MacOS support") fi if test "x$GXX" = "xyes" ; then AC_MSG_NOTICE([Using the GNU compiler collection]) AC_DEFINE(USING_GCC,,"Using the GNU compiler collection") fi if test "x$enable_debug" = "xyes" ; then AC_MSG_NOTICE([Debug compilation]) AC_DEFINE(ODIN_DEBUG,,"Debug compilation") fi if test "x$enable_stdcpp_replacement" = "xyes" ; then AC_MSG_NOTICE([Using built-in C++ standard library]) AC_DEFINE(STL_REPLACEMENT,,"Using STL replacement") AC_DEFINE(STRING_REPLACEMENT,,"Using string replacement") AC_DEFINE(STREAM_REPLACEMENT,,"Using stream replacement") fi if test "x$enable_custom_heap" = "xyes" ; then AC_MSG_NOTICE([Using custom heap of size $custom_heap_size MB]) AC_DEFINE(CUSTOM_HEAP,,"Using custom heap") AC_DEFINE_UNQUOTED(CUSTOM_HEAP_SIZE,$custom_heap_size,[Size of Custom Heap in MB]) fi if test "x$enable_cmdline" = "xno" ; then AC_MSG_NOTICE([Not using command line]) AC_DEFINE(NO_CMDLINE,,"Not using command line") fi if test "x$enable_filehandling" = "xno" ; then AC_MSG_NOTICE([No file handling]) AC_DEFINE(NO_FILEHANDLING,,"No file handling") fi if test "x$enable_ideasupport" = "xyes" ; then AC_MSG_NOTICE([IDEA support]) AC_DEFINE(ODIN4IDEA,,"IDEA support") fi if test "x$have_win32_api" = "xyes" ; then AC_MSG_NOTICE([Using Win32-API]) AC_DEFINE(USING_WIN32,,"Using Win32-API") fi if test "x$enable_onlylibs" = "xyes" ; then AC_MSG_NOTICE([Only essential libraries]) fi AM_CONDITIONAL(ONLY_LIBS, test "x$enable_onlylibs" = "xyes") if test "x$enable_gui" = "xyes" ; then AC_DEFINE(GUISUPPORT,,"Graphical User Interface enabled") AC_MSG_NOTICE([Graphical User Interface enabled]) AC_MSG_NOTICE([QTDIR:QTVERSION=${CONF_QTDIR}:${QTVERSION}]) fi AM_CONDITIONAL(GUI_ENABLED, test "x$enable_gui" = "xyes") if test "x$enable_ideaplugin" = "xyes" ; then AC_MSG_NOTICE([Compiling IDEA drivers]) PLUGIN_LIBS="$PLUGIN_LIBS odinseq_idea" AC_DEFINE(IDEA_PLUGIN,,"Compile IDEA drivers") PLATFORMS="$PLATFORMS IDEA_n4" fi AM_CONDITIONAL(IDEA_PLUGIN, test "x$enable_ideaplugin" = "xyes") if test "x$enable_paravisionplugin" = "xyes" ; then AC_MSG_NOTICE([Compiling Paravision drivers]) PLUGIN_LIBS="$PLUGIN_LIBS odinseq_paravision" AC_DEFINE(PARAVISION_PLUGIN,,"Compile Paravision drivers") PLATFORMS="$PLATFORMS Paravision" fi AM_CONDITIONAL(PARAVISION_PLUGIN, test "x$enable_paravisionplugin" = "xyes") if test "x$enable_standaloneplugin" = "xyes" ; then AC_MSG_NOTICE([Compiling Standalone drivers]) PLUGIN_LIBS="$PLUGIN_LIBS odinseq_standalone" AC_DEFINE(STANDALONE_PLUGIN,,"Compile Standalone drivers") PLATFORMS="$PLATFORMS StandAlone" fi AM_CONDITIONAL(STANDALONE_PLUGIN, test "x$enable_standaloneplugin" = "xyes") if test "x$enable_epicplugin" = "xyes" ; then AC_MSG_NOTICE([Compiling EPIC drivers]) PLUGIN_LIBS="$PLUGIN_LIBS odinseq_epic" AC_DEFINE(EPIC_PLUGIN,,"Compile EPIC drivers") PLATFORMS="$PLATFORMS EPIC" fi AM_CONDITIONAL(EPIC_PLUGIN, test "x$enable_epicplugin" = "xyes") if test "x$enable_unittest" = "xno" ; then AC_MSG_NOTICE([Unit test disabled]) AC_DEFINE(NO_UNIT_TEST,,"Unit test disabled") fi if test "x$enable_threads" = "xno" ; then AC_MSG_NOTICE([Multithreading disabled]) AC_DEFINE(NO_THREADS,,"Multithreading disabled") fi if test "x$valid_dl" = "xyes" ; then AC_MSG_NOTICE([Using dynamic linking loader]) AC_DEFINE(HAVE_DL,,"Using dynamic linking loader") fi if test "x$valid_pthread" = "xyes" ; then AC_MSG_NOTICE([Using POSIX threads]) AC_DEFINE(HAVE_PTHREAD,,"Using POSIX threads") fi if test "x$valid_lapack" = "xyes" ; then if test "x$thread_safe_lapack" = "xyes" ; then AC_DEFINE(HAVE_THREADSAFE_LAPACK,,"Thread-safe LAPACK") tsmessage=" thread-safe" fi AC_MSG_NOTICE([Using${tsmessage} LAPACK($lapack_libname)]) AC_DEFINE(HAVE_LAPACK,,"Using LAPACK") fi if test "x$valid_libz" = "xyes" ; then AC_DEFINE(HAVE_LIBZ,,"libz support") fi if test "x$valid_gsl" = "xyes" ; then AC_DEFINE(HAVE_LIBGSL,,"GSL support") fi if test "x$lib_vista" = "xyes" ; then AC_MSG_NOTICE([Vista support]) AC_DEFINE(VISTASUPPORT,,"Vista support") fi if test "x$lib_nifti" = "xyes" ; then AC_MSG_NOTICE([NIFTI support]) AC_DEFINE(NIFTISUPPORT,,"NIFTI support") fi if test "x$lib_vtk" = "xyes" ; then AC_MSG_NOTICE([VTK support]) AC_DEFINE(VTKSUPPORT,,"VTK support") fi if test "x$lib_dcmtk" = "xyes" ; then AC_MSG_NOTICE([DICOM support]) AC_DEFINE(DICOMSUPPORT,,"DICOM support") fi if test "x$lib_png" = "xyes" ; then AC_MSG_NOTICE([PNG support]) AC_DEFINE(PNGSUPPORT,,"PNG support") fi if test "x$empty_templ_list" = "xyes" ; then AC_DEFINE(EMPTY_TEMPL_LIST,template<>,"empty template list") else AC_DEFINE(EMPTY_TEMPL_LIST,,define for empty template list) fi if test "x$self_friend_class" = "xyes" ; then AC_DEFINE(SELF_FRIEND_CLASS,,"self-friend class possible/required") fi if test ! -z "$GDB" -a ! -z "$XTERM" ; then AC_MSG_NOTICE([Using gdb/xterm to attach debugger]) AC_DEFINE(HAVE_GDB_XTERM,,"Using gdb/xterm") fi AC_MSG_NOTICE([INSTALL_PREFIX=$prefix]) AC_MSG_NOTICE([---------------------------------------------------]) AC_SUBST(PLATFORMS,$PLATFORMS) dnl Common generation command for manpages AC_SUBST(HELP2MAN,"help2man -N") AC_SUBST(MOC,$QTMOC) AC_SUBST(BASELIBS) AC_SUBST(GUILIBS) AC_SUBST(DATALIBS) AC_SUBST(VTKLIBS) AC_SUBST(ODINSEQ_INCLUDES,$extra_odinseq_includes) dnl Make sure top-level source and build dir are in the include path all_includes="-I.. -I$srcdir_abs $all_includes" AC_SUBST(all_includes) AC_DEFINE_UNQUOTED(BASELIBS,"$BASELIBS",[Third-party libraries used by all ODIN components]) AC_DEFINE_UNQUOTED(CXXFLAGS,"$CXXFLAGS_EXPORT",[Compiler flags]) AC_DEFINE_UNQUOTED(CPPFLAGS,"$CPPFLAGS_EXPORT",[Preprocessor flags]) AC_DEFINE_UNQUOTED(LDFLAGS,"$LDFLAGS_EXPORT",[Linker flags]) AC_DEFINE_UNQUOTED(CXX,"$CXX",[Compiler]) AC_DEFINE_UNQUOTED(LD,"$LD",[Linker]) AC_DEFINE_UNQUOTED(PLUGIN_LIBS,"$PLUGIN_LIBS",[Plugin-Libraries]) AC_DEFINE_UNQUOTED(DEFAULT_EDITOR,"$initial_editor",[Initial default editor]) AC_DEFINE_UNQUOTED(DEFAULT_BROWSER,"$initial_browser",[Initial default browser]) AC_DEFINE_UNQUOTED(INSTALL_PREFIX,"$prefix",[Installation prefix]) if test ! "$libdir" = '${exec_prefix}/lib' ; then libdir_export="$libdir" fi AC_DEFINE_UNQUOTED(LIBDIR_CONFIGURE,"$libdir_export",[libdir of configure]) dnl Output AC_OUTPUT(Makefile tjutils/Makefile odinpara/Makefile odinseq/Makefile odinqt/Makefile odindata/Makefile \ odin/Makefile pulsar/Makefile geoedit/Makefile miview/Makefile \ odinreco/Makefile cmdline-utils/Makefile sequences/Makefile samples/Makefile coils/Makefile \ docs/Makefile docs/homepage/Makefile docs/tutorials/Makefile replacements/Makefile) odin-1.8.5/config.guess0000755000175000017500000012763711734622601011741 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2009-12-30' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Per Bothner. Please send patches (context # diff format) to and include a ChangeLog # entry. # # This script attempts to guess a canonical system name similar to # config.sub. If it succeeds, it prints the system name on stdout, and # exits with 0. Otherwise, it exits with 1. # # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" >&2 exit 1 ;; * ) break ;; esac done if test $# != 0; then echo "$me: too many arguments$help" >&2 exit 1 fi trap 'exit 1' 1 2 15 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a # compiler to aid in system detection is discouraged as it requires # temporary files to be created and, as you can see below, it is a # headache to deal with in a portable fashion. # Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still # use `HOST_CC' if defined, but it is deprecated. # Portable tmp directory creation inspired by the Autoconf team. set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in ,,) echo "int x;" > $dummy.c ; for c in cc gcc c89 c99 ; do if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; if test x"$CC_FOR_BUILD" = x ; then CC_FOR_BUILD=no_compiler_found ; fi ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) if (test -f /.attbin/uname) >/dev/null 2>&1 ; then PATH=$PATH:/.attbin ; export PATH fi UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown # Note: order is significant - the case branches are not exclusive. case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently # switched to ELF, *-*-netbsd* would select the old # object file format. This provides both forward # compatibility and a consistent mechanism for selecting the # object file format. # # Note: NetBSD doesn't particularly care about the vendor # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ /usr/sbin/$sysctl 2>/dev/null || echo unknown)` case "${UNAME_MACHINE_ARCH}" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched # to ELF recently, or will in the future. case "${UNAME_MACHINE_ARCH}" in arm*|i386|m68k|ns32k|sh3*|sparc|vax) eval $set_cc_for_build if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). # Return netbsd for either. FIX? os=netbsd else os=netbsdelf fi ;; *) os=netbsd ;; esac # The OS release # Debian GNU/NetBSD machines have a different userland, and # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. case "${UNAME_VERSION}" in Debian*) release='-gnu' ;; *) release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; *:SolidBSD:*:*) echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} exit ;; macppc:MirBSD:*:*) echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` ;; *5.*) UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` ;; esac # According to Compaq, /usr/sbin/psrinfo has been available on # OSF/1 and Tru64 systems produced since 1995. I hope that # covers most systems running today. This code pipes the CPU # types through head -n 1, so we only detect the type of CPU 0. ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") UNAME_MACHINE="alpha" ;; "EV4.5 (21064)") UNAME_MACHINE="alpha" ;; "LCA4 (21066/21068)") UNAME_MACHINE="alpha" ;; "EV5 (21164)") UNAME_MACHINE="alphaev5" ;; "EV5.6 (21164A)") UNAME_MACHINE="alphaev56" ;; "EV5.6 (21164PC)") UNAME_MACHINE="alphapca56" ;; "EV5.7 (21164PC)") UNAME_MACHINE="alphapca57" ;; "EV6 (21264)") UNAME_MACHINE="alphaev6" ;; "EV6.7 (21264A)") UNAME_MACHINE="alphaev67" ;; "EV6.8CB (21264C)") UNAME_MACHINE="alphaev68" ;; "EV6.8AL (21264B)") UNAME_MACHINE="alphaev68" ;; "EV6.8CX (21264D)") UNAME_MACHINE="alphaev68" ;; "EV6.9A (21264/EV69A)") UNAME_MACHINE="alphaev69" ;; "EV7 (21364)") UNAME_MACHINE="alphaev7" ;; "EV7.9 (21364A)") UNAME_MACHINE="alphaev79" ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` exit ;; Alpha\ *:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # Should we change UNAME_MACHINE based on the output of uname instead # of the specific Alpha model? echo alpha-pc-interix exit ;; 21064:Windows_NT:50:3) echo alpha-dec-winnt3.5 exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) echo ${UNAME_MACHINE}-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition exit ;; *:z/VM:*:*) echo s390-ibm-zvmoe exit ;; *:OS400:*:*) echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) echo arm-acorn-riscix${UNAME_RELEASE} exit ;; arm:riscos:*:*|arm:RISCOS:*:*) echo arm-unknown-riscos exit ;; SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) echo hppa1.1-hitachi-hiuxmpp exit ;; Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. if test "`(/bin/universe) 2>/dev/null`" = att ; then echo pyramid-pyramid-sysv3 else echo pyramid-pyramid-bsd fi exit ;; NILE*:*:*:dcosx) echo pyramid-pyramid-svr4 exit ;; DRS?6000:unix:4.0:6*) echo sparc-icl-nx6 exit ;; DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) case `/usr/bin/uname -p` in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4H:SunOS:5.*:*) echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) echo i386-pc-auroraux${UNAME_RELEASE} exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) eval $set_cc_for_build SUN_ARCH="i386" # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then SUN_ARCH="x86_64" fi fi echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in Series*|S4*) UNAME_RELEASE=`uname -v` ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` exit ;; sun3*:SunOS:*:*) echo m68k-sun-sunos${UNAME_RELEASE} exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) echo m68k-sun-sunos${UNAME_RELEASE} ;; sun4) echo sparc-sun-sunos${UNAME_RELEASE} ;; esac exit ;; aushp:SunOS:*:*) echo sparc-auspex-sunos${UNAME_RELEASE} exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not # "atarist" or "atariste" at least should have a processor # > m68000). The system name ranges from "MiNT" over "FreeMiNT" # to the lowercase version "mint" (or "freemint"). Finally # the system name "TOS" denotes a system which is actually not # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) echo m68k-atari-mint${UNAME_RELEASE} exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) echo m68k-milan-mint${UNAME_RELEASE} exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) echo m68k-hades-mint${UNAME_RELEASE} exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) echo m68k-unknown-mint${UNAME_RELEASE} exit ;; m68k:machten:*:*) echo m68k-apple-machten${UNAME_RELEASE} exit ;; powerpc:machten:*:*) echo powerpc-apple-machten${UNAME_RELEASE} exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) echo mips-dec-ultrix${UNAME_RELEASE} exit ;; VAX*:ULTRIX*:*:*) echo vax-dec-ultrix${UNAME_RELEASE} exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) echo clipper-intergraph-clix${UNAME_RELEASE} exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { #else int main (argc, argv) int argc; char *argv[]; { #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && SYSTEM_NAME=`$dummy $dummyarg` && { echo "$SYSTEM_NAME"; exit; } echo mips-mips-riscos${UNAME_RELEASE} exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax exit ;; Motorola:*:4.3:PL8-*) echo powerpc-harris-powermax exit ;; Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) echo powerpc-harris-powermax exit ;; Night_Hawk:Power_UNIX:*:*) echo powerpc-harris-powerunix exit ;; m88k:CX/UX:7*:*) echo m88k-harris-cxux7 exit ;; m88k:*:4*:R4*) echo m88k-motorola-sysv4 exit ;; m88k:*:3*:R3*) echo m88k-motorola-sysv3 exit ;; AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] then if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ [ ${TARGET_BINARY_INTERFACE}x = x ] then echo m88k-dg-dgux${UNAME_RELEASE} else echo m88k-dg-dguxbcs${UNAME_RELEASE} fi else echo i586-dg-dgux${UNAME_RELEASE} fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) echo m88k-dolphin-sysv3 exit ;; M88*:*:R3*:*) # Delta 88k system running SVR3 echo m88k-motorola-sysv3 exit ;; XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) echo m88k-tektronix-sysv3 exit ;; Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' i*86:AIX:*:*) echo i386-ibm-aix exit ;; ia64:AIX:*:*) if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include main() { if (!__power_pc()) exit(1); puts("powerpc-ibm-aix3.2.5"); exit(0); } EOF if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` then echo "$SYSTEM_NAME" else echo rs6000-ibm-aix3.2.5 fi elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then echo rs6000-ibm-aix3.2.4 else echo rs6000-ibm-aix3.2 fi exit ;; *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc fi if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} fi echo ${IBM_ARCH}-ibm-aix${IBM_REV} exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; ibmrt:4.4BSD:*|romp-ibm:BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx exit ;; DPX/2?00:B.O.S.:*:*) echo m68k-bull-sysv3 exit ;; 9000/[34]??:4.3bsd:1.*:*) echo m68k-hp-bsd exit ;; hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` case "${UNAME_MACHINE}" in 9000/31? ) HP_ARCH=m68000 ;; 9000/[34]?? ) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` case "${sc_cpu_version}" in 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 case "${sc_kernel_bits}" in 32) HP_ARCH="hppa2.0n" ;; 64) HP_ARCH="hppa2.0w" ;; '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 esac ;; esac fi if [ "${HP_ARCH}" = "" ]; then eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #define _HPUX_SOURCE #include #include int main () { #if defined(_SC_KERNEL_BITS) long bits = sysconf(_SC_KERNEL_BITS); #endif long cpu = sysconf (_SC_CPU_VERSION); switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0"); break; case CPU_PA_RISC1_1: puts ("hppa1.1"); break; case CPU_PA_RISC2_0: #if defined(_SC_KERNEL_BITS) switch (bits) { case 64: puts ("hppa2.0w"); break; case 32: puts ("hppa2.0n"); break; default: puts ("hppa2.0"); break; } break; #else /* !defined(_SC_KERNEL_BITS) */ puts ("hppa2.0"); break; #endif default: puts ("hppa1.0"); break; } exit (0); } EOF (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac if [ ${HP_ARCH} = "hppa2.0w" ] then eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler # generating 64-bit code. GNU and HP use different nomenclature: # # $ CC_FOR_BUILD=cc ./config.guess # => hppa2.0w-hp-hpux11.23 # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then HP_ARCH="hppa2.0w" else HP_ARCH="hppa64" fi fi echo ${HP_ARCH}-hp-hpux${HPUX_REV} exit ;; ia64:HP-UX:*:*) HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` echo ia64-hp-hpux${HPUX_REV} exit ;; 3050*:HI-UX:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #include int main () { long cpu = sysconf (_SC_CPU_VERSION); /* The order matters, because CPU_IS_HP_MC68K erroneously returns true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct results, however. */ if (CPU_IS_PA_RISC (cpu)) { switch (cpu) { case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; default: puts ("hppa-hitachi-hiuxwe2"); break; } } else if (CPU_IS_HP_MC68K (cpu)) puts ("m68k-hitachi-hiuxwe2"); else puts ("unknown-hitachi-hiuxwe2"); exit (0); } EOF $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) echo hppa1.0-hp-bsd exit ;; *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) echo hppa1.0-hp-osf exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then echo ${UNAME_MACHINE}-unknown-osf1mk else echo ${UNAME_MACHINE}-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) echo hppa1.1-hp-lites exit ;; C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) echo c1-convex-bsd exit ;; C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) echo c34-convex-bsd exit ;; C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) echo c38-convex-bsd exit ;; C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} exit ;; sparc*:BSD/OS:*:*) echo sparc-unknown-bsdi${UNAME_RELEASE} exit ;; *:BSD/OS:*:*) echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) case ${UNAME_MACHINE} in pc98) echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) # uname -m includes "-pc" on this system. echo ${UNAME_MACHINE}-mingw32 exit ;; i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; *:Interix*:*) case ${UNAME_MACHINE} in x86) echo i586-pc-interix${UNAME_RELEASE} exit ;; authenticamd | genuineintel | EM64T) echo x86_64-unknown-interix${UNAME_RELEASE} exit ;; IA64) echo ia64-unknown-interix${UNAME_RELEASE} exit ;; esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; 8664:Windows_NT:*) echo x86_64-pc-mks exit ;; i*:Windows_NT*:* | Pentium*:Windows_NT*:*) # How do we know it's Interix rather than the generic POSIX subsystem? # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we # UNAME_MACHINE based on the output of uname instead of i386? echo i586-pc-interix exit ;; i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) echo powerpcle-unknown-cygwin exit ;; prep*:SunOS:5.*:*) echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; *:GNU:*:*) # the GNU system echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in EV5) UNAME_MACHINE=alphaev5 ;; EV56) UNAME_MACHINE=alphaev56 ;; PCA56) UNAME_MACHINE=alphapca56 ;; PCA57) UNAME_MACHINE=alphapca56 ;; EV6) UNAME_MACHINE=alphaev6 ;; EV67) UNAME_MACHINE=alphaev67 ;; EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} exit ;; arm*:Linux:*:*) eval $set_cc_for_build if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then echo ${UNAME_MACHINE}-unknown-linux-gnu else echo ${UNAME_MACHINE}-unknown-linux-gnueabi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) echo cris-axis-linux-gnu exit ;; crisv32:Linux:*:*) echo crisv32-axis-linux-gnu exit ;; frv:Linux:*:*) echo frv-unknown-linux-gnu exit ;; i*86:Linux:*:*) LIBC=gnu eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #ifdef __dietlibc__ LIBC=dietlibc #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; mips:Linux:*:* | mips64:Linux:*:*) eval $set_cc_for_build sed 's/^ //' << EOF >$dummy.c #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) CPU=${UNAME_MACHINE}el #else #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) CPU=${UNAME_MACHINE} #else CPU= #endif #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; or32:Linux:*:*) echo or32-unknown-linux-gnu exit ;; padre:Linux:*:*) echo sparc-unknown-linux-gnu exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-gnu exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in PA7*) echo hppa1.1-unknown-linux-gnu ;; PA8*) echo hppa2.0-unknown-linux-gnu ;; *) echo hppa-unknown-linux-gnu ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-gnu exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-gnu exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. # earlier versions are messed up and put the nodename in both # sysname and nodename. echo i386-sequent-sysv4 exit ;; i*86:UNIX_SV:4.2MP:2.*) # Unixware is an offshoot of SVR4, but it has its own version # number series starting with 2... # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. echo ${UNAME_MACHINE}-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) echo ${UNAME_MACHINE}-unknown-stop exit ;; i*86:atheos:*:*) echo ${UNAME_MACHINE}-unknown-atheos exit ;; i*86:syllable:*:*) echo ${UNAME_MACHINE}-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) echo i386-unknown-lynxos${UNAME_RELEASE} exit ;; i*86:*DOS:*:*) echo ${UNAME_MACHINE}-pc-msdosdjgpp exit ;; i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} else echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} fi exit ;; i*86:*:5:[678]*) # UnixWare 7.x, OpenUNIX and OpenServer 6. case `/bin/uname -X | grep "^Machine"` in *486*) UNAME_MACHINE=i486 ;; *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ && UNAME_MACHINE=i586 (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 echo ${UNAME_MACHINE}-pc-sco$UNAME_REL else echo ${UNAME_MACHINE}-pc-sysv32 fi exit ;; pc:*:*:*) # Left here for compatibility: # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub # prints for the "djgpp" host, or else GDB configury will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; Intel:Mach:3*:*) echo i386-pc-mach3 exit ;; paragon:*:*:*) echo i860-intel-osf1 exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) # "miniframe" echo m68010-convergent-sysv exit ;; mc68k:UNIX:SYSTEM5:3.51m) echo m68k-convergent-sysv exit ;; M680?0:D-NIX:5.3:*) echo m68k-diab-dnix exit ;; M68*:*:R3V[5678]*:*) test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) OS_REL='' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; NCR*:*:4.2:* | MPRAS*:*:4.2:*) OS_REL='.3' test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) echo m68k-unknown-lynxos${UNAME_RELEASE} exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) echo sparc-unknown-lynxos${UNAME_RELEASE} exit ;; rs6000:LynxOS:2.*:*) echo rs6000-unknown-lynxos${UNAME_RELEASE} exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) echo powerpc-unknown-lynxos${UNAME_RELEASE} exit ;; SM[BE]S:UNIX_SV:*:*) echo mips-dde-sysv${UNAME_RELEASE} exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 exit ;; RM*:SINIX-*:*:*) echo mips-sni-sysv4 exit ;; *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` echo ${UNAME_MACHINE}-sni-sysv4 else echo ns32k-sni-sysv fi exit ;; PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort # says echo i586-unisys-sysv4 exit ;; *:UNIX_System_V:4*:FTX*) # From Gerald Hewes . # How about differentiating between stratus architectures? -djm echo hppa1.1-stratus-sysv4 exit ;; *:*:*:FTX*) # From seanf@swdc.stratus.com. echo i860-stratus-sysv4 exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. echo ${UNAME_MACHINE}-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) echo m68k-apple-aux${UNAME_RELEASE} exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then echo mips-nec-sysv${UNAME_RELEASE} else echo mips-unknown-sysv${UNAME_RELEASE} fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. echo powerpc-be-beos exit ;; BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. echo powerpc-apple-beos exit ;; BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; BePC:Haiku:*:*) # Haiku running on Intel PC compatible. echo i586-pc-haiku exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; SX-5:SUPER-UX:*:*) echo sx5-nec-superux${UNAME_RELEASE} exit ;; SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; SX-7:SUPER-UX:*:*) echo sx7-nec-superux${UNAME_RELEASE} exit ;; SX-8:SUPER-UX:*:*) echo sx8-nec-superux${UNAME_RELEASE} exit ;; SX-8R:SUPER-UX:*:*) echo sx8r-nec-superux${UNAME_RELEASE} exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; *:Rhapsody:*:*) echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in i386) eval $set_cc_for_build if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then UNAME_PROCESSOR="x86_64" fi fi ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` if test "$UNAME_PROCESSOR" = "x86"; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; NSE-?:NONSTOP_KERNEL:*:*) echo nse-tandem-nsk${UNAME_RELEASE} exit ;; NSR-?:NONSTOP_KERNEL:*:*) echo nsr-tandem-nsk${UNAME_RELEASE} exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux exit ;; BS2000:POSIX*:*:*) echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. if test "$cputype" = "386"; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi echo ${UNAME_MACHINE}-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 exit ;; *:TENEX:*:*) echo pdp10-unknown-tenex exit ;; KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) echo pdp10-dec-tops20 exit ;; XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) echo pdp10-xkl-tops20 exit ;; *:TOPS-20:*:*) echo pdp10-unknown-tops20 exit ;; *:ITS:*:*) echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) echo mips-sei-seiux${UNAME_RELEASE} exit ;; *:DragonFly:*:*) echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` case "${UNAME_MACHINE}" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; esac ;; *:XENIX:*:SysV) echo i386-pc-xenix exit ;; i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; i*86:rdos:*:*) echo ${UNAME_MACHINE}-pc-rdos exit ;; i*86:AROS:*:*) echo ${UNAME_MACHINE}-pc-aros exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 #echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 eval $set_cc_for_build cat >$dummy.c < # include #endif main () { #if defined (sony) #if defined (MIPSEB) /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, I don't know.... */ printf ("mips-sony-bsd\n"); exit (0); #else #include printf ("m68k-sony-newsos%s\n", #ifdef NEWSOS4 "4" #else "" #endif ); exit (0); #endif #endif #if defined (__arm) && defined (__acorn) && defined (__unix) printf ("arm-acorn-riscix\n"); exit (0); #endif #if defined (hp300) && !defined (hpux) printf ("m68k-hp-bsd\n"); exit (0); #endif #if defined (NeXT) #if !defined (__ARCHITECTURE__) #define __ARCHITECTURE__ "m68k" #endif int version; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; if (version < 4) printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); else printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); exit (0); #endif #if defined (MULTIMAX) || defined (n16) #if defined (UMAXV) printf ("ns32k-encore-sysv\n"); exit (0); #else #if defined (CMU) printf ("ns32k-encore-mach\n"); exit (0); #else printf ("ns32k-encore-bsd\n"); exit (0); #endif #endif #endif #if defined (__386BSD__) printf ("i386-pc-bsd\n"); exit (0); #endif #if defined (sequent) #if defined (i386) printf ("i386-sequent-dynix\n"); exit (0); #endif #if defined (ns32000) printf ("ns32k-sequent-dynix\n"); exit (0); #endif #endif #if defined (_SEQUENT_) struct utsname un; uname(&un); if (strncmp(un.version, "V2", 2) == 0) { printf ("i386-sequent-ptx2\n"); exit (0); } if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ printf ("i386-sequent-ptx1\n"); exit (0); } printf ("i386-sequent-ptx\n"); exit (0); #endif #if defined (vax) # if !defined (ultrix) # include # if defined (BSD) # if BSD == 43 printf ("vax-dec-bsd4.3\n"); exit (0); # else # if BSD == 199006 printf ("vax-dec-bsd4.3reno\n"); exit (0); # else printf ("vax-dec-bsd\n"); exit (0); # endif # endif # else printf ("vax-dec-bsd\n"); exit (0); # endif # else printf ("vax-dec-ultrix\n"); exit (0); # endif #endif #if defined (alliant) && defined (i860) printf ("i860-alliant-bsd\n"); exit (0); #endif exit (1); } EOF $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && { echo "$SYSTEM_NAME"; exit; } # Apollos put the system type in the environment. test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } # Convex versions that predate uname can use getsysinfo(1) if [ -x /usr/convex/getsysinfo ] then case `getsysinfo -f cpu_type` in c1*) echo c1-convex-bsd exit ;; c2*) if getsysinfo -f scalar_acc then echo c32-convex-bsd else echo c2-convex-bsd fi exit ;; c34*) echo c34-convex-bsd exit ;; c38*) echo c38-convex-bsd exit ;; c4*) echo c4-convex-bsd exit ;; esac fi cat >&2 < in order to provide the needed information to handle your system. config.guess timestamp = $timestamp uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` /bin/uname -X = `(/bin/uname -X) 2>/dev/null` hostinfo = `(hostinfo) 2>/dev/null` /bin/universe = `(/bin/universe) 2>/dev/null` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` /bin/arch = `(/bin/arch) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` UNAME_MACHINE = ${UNAME_MACHINE} UNAME_RELEASE = ${UNAME_RELEASE} UNAME_SYSTEM = ${UNAME_SYSTEM} UNAME_VERSION = ${UNAME_VERSION} EOF exit 1 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: odin-1.8.5/install-sh0000755000175000017500000003253711734622601011417 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2009-04-28.21; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. nl=' ' IFS=" "" $nl" # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} if test -z "$doit"; then doit_exec=exec else doit_exec=$doit fi # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_glob='?' initialize_posix_glob=' test "$posix_glob" != "?" || { if (set -f) 2>/dev/null; then posix_glob= else posix_glob=: fi } ' posix_mkdir= # Desired mode of installed file. mode=0755 chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false no_target_directory= usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve the last data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -s $stripprog installed files. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *' '* | *' '* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -s) stripcmd=$stripprog;; -t) dst_arg=$2 shift;; -T) no_target_directory=true;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call `install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then trap '(exit $?); exit' 1 2 13 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names starting with `-'. case $src in -*) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # Protect names starting with `-'. case $dst in -*) dst=./$dst;; esac # If destination is a directory, append the input filename; won't work # if double slashes aren't ignored. if test -d "$dst"; then if test -n "$no_target_directory"; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dst=$dstdir/`basename "$src"` dstdir_status=0 else # Prefer dirname, but fall back on a substitute if dirname fails. dstdir=` (dirname "$dst") 2>/dev/null || expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$dst" : 'X\(//\)[^/]' \| \ X"$dst" : 'X\(//\)$' \| \ X"$dst" : 'X\(/\)' \| . 2>/dev/null || echo X"$dst" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q' ` test -d "$dstdir" dstdir_status=$? fi fi obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # Create intermediate dirs using mode 755 as modified by the umask. # This is like FreeBSD 'install' as of 1997-10-28. umask=`umask` case $stripcmd.$umask in # Optimize common cases. *[2367][2367]) mkdir_umask=$umask;; .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; *[0-7]) mkdir_umask=`expr $umask + 22 \ - $umask % 100 % 40 + $umask % 20 \ - $umask % 10 % 4 + $umask % 2 `;; *) mkdir_umask=$umask,go-w;; esac # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false case $umask in *[123567][0-7][0-7]) # POSIX mkdir -p sets u+wx bits regardless of umask, which # is incompatible with FreeBSD 'install' when (umask & 300) != 0. ;; *) tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 if (umask $mkdir_umask && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writeable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. ls_ld_tmpdir=`ls -ld "$tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/d" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null fi trap '' 0;; esac;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # The umask is ridiculous, or mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; -*) prefix='./';; *) prefix='';; esac eval "$initialize_posix_glob" oIFS=$IFS IFS=/ $posix_glob set -f set fnord $dstdir shift $posix_glob set +f IFS=$oIFS prefixes= for d do test -z "$d" && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask=$mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=$dstdir/_inst.$$_ rmtmp=$dstdir/_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && eval "$initialize_posix_glob" && $posix_glob set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && $posix_glob set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd -f "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: odin-1.8.5/config.sub0000755000175000017500000010344511734622601011373 00000000000000#! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, # 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 # Free Software Foundation, Inc. timestamp='2010-01-22' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software # can handle that machine. It does not imply ALL GNU software can. # # This file is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA # 02110-1301, USA. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Please send patches to . Submit a context # diff and a properly formatted GNU ChangeLog entry. # # Configuration subroutine to validate and canonicalize a configuration type. # Supply the specified configuration type as an argument. # If it is invalid, we print an error message on stderr and exit with code 1. # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases # that are meaningful with *any* GNU software. # Each package is responsible for reporting which valid configurations # it does not support. The user should be able to distinguish # a failure to support a valid configuration from a meaningless # configuration. # The goal of this file is to map all the various variations of a given # machine specification into a single specification in the form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM # or in some cases, the newer four-part form: # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM # It is wrong to echo any other type of specification. me=`echo "$0" | sed -e 's,.*/,,'` usage="\ Usage: $0 [OPTION] CPU-MFR-OPSYS $0 [OPTION] ALIAS Canonicalize a configuration name. Operation modes: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit Report bugs and patches to ." version="\ GNU config.sub ($timestamp) Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." help=" Try \`$me --help' for more information." # Parse command line while test $# -gt 0 ; do case $1 in --time-stamp | --time* | -t ) echo "$timestamp" ; exit ;; --version | -v ) echo "$version" ; exit ;; --help | --h* | -h ) echo "$usage"; exit ;; -- ) # Stop option processing shift; break ;; - ) # Use stdin as input. break ;; -* ) echo "$me: invalid option $1$help" exit 1 ;; *local*) # First pass through any local machine types. echo $1 exit ;; * ) break ;; esac done case $# in 0) echo "$me: missing argument$help" >&2 exit 1;; 1) ;; *) echo "$me: too many arguments$help" >&2 exit 1;; esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ kopensolaris*-gnu* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; *) basic_machine=`echo $1 | sed 's/-[^-]*$//'` if [ $basic_machine != $1 ] then os=`echo $1 | sed 's/.*-/-/'` else os=; fi ;; esac ### Let's recognize common machines as not being operating systems so ### that things like config.sub decstation-3100 work. We also ### recognize some manufacturers as not being operating systems, so we ### can provide default operating systems below. case $os in -sun*os*) # Prevent following clause from handling this invalid input. ;; -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -apple | -axis | -knuth | -cray | -microblaze) os= basic_machine=$1 ;; -bluegene*) os=-cnk ;; -sim | -cisco | -oki | -wec | -winbond) os= basic_machine=$1 ;; -scout) ;; -wrs) os=-vxworks basic_machine=$1 ;; -chorusos*) os=-chorusos basic_machine=$1 ;; -chorusrdb) os=-chorusrdb basic_machine=$1 ;; -hiux*) os=-hiuxwe2 ;; -sco6) os=-sco5v6 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -udk*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; -lynx*) os=-lynxos ;; -ptx*) basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` ;; -windowsnt*) os=`echo $os | sed -e 's/windowsnt/winnt/'` ;; -psos*) os=-psos ;; -mint | -mint[0-9]*) basic_machine=m68k-atari os=-mint ;; esac # Decode aliases for certain CPU-COMPANY combinations. case $basic_machine in # Recognize the basic CPU types without company name. # Some are omitted here because they have special meanings below. 1750a | 580 \ | a29k \ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ | lm32 \ | m32c | m32r | m32rle | m68000 | m68k | m88k \ | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ | mips64r5900 | mips64r5900el \ | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ | mipsisa64r2 | mipsisa64r2el \ | mipsisa64sb1 | mipsisa64sb1el \ | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ | moxie \ | mt \ | msp430 \ | nios | nios2 \ | ns16k | ns32k \ | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ | rx \ | score \ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | ubicom32 \ | v850 | v850e \ | we32k \ | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown ;; m6811 | m68hc11 | m6812 | m68hc12 | picochip) # Motorola 68HC11/12. basic_machine=$basic_machine-unknown os=-none ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; ms1) basic_machine=mt-unknown ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and # (2) the word "unknown" tends to confuse beginning users. i*86 | x86_64) basic_machine=$basic_machine-pc ;; # Object if more than one company name word. *-*-*) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. 580-* \ | a29k-* \ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ | lm32-* \ | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ | mips64r5900-* | mips64r5900el-* \ | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ | mipsisa64r2-* | mipsisa64r2el-* \ | mipsisa64sb1-* | mipsisa64sb1el-* \ | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ | mt-* \ | msp430-* \ | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* | rx-* \ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ | tile-* | tilegx-* \ | tron-* \ | ubicom32-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-* | z80-*) ;; # Recognize the basic CPU types without company name, with glob match. xtensa*) basic_machine=$basic_machine-unknown ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) basic_machine=i386-unknown os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) basic_machine=m68000-att ;; 3b*) basic_machine=we32k-att ;; a29khif) basic_machine=a29k-amd os=-udi ;; abacus) basic_machine=abacus-unknown ;; adobe68k) basic_machine=m68010-adobe os=-scout ;; alliant | fx80) basic_machine=fx80-alliant ;; altos | altos3068) basic_machine=m68k-altos ;; am29k) basic_machine=a29k-none os=-bsd ;; amd64) basic_machine=x86_64-pc ;; amd64-*) basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl os=-sysv ;; amiga | amiga-*) basic_machine=m68k-unknown ;; amigaos | amigados) basic_machine=m68k-unknown os=-amigaos ;; amigaunix | amix) basic_machine=m68k-unknown os=-sysv4 ;; apollo68) basic_machine=m68k-apollo os=-sysv ;; apollo68bsd) basic_machine=m68k-apollo os=-bsd ;; aros) basic_machine=i386-pc os=-aros ;; aux) basic_machine=m68k-apple os=-aux ;; balance) basic_machine=ns32k-sequent os=-dynix ;; blackfin) basic_machine=bfin-unknown os=-linux ;; blackfin-*) basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) basic_machine=powerpc-ibm os=-cnk ;; c90) basic_machine=c90-cray os=-unicos ;; cegcc) basic_machine=arm-unknown os=-cegcc ;; convex-c1) basic_machine=c1-convex os=-bsd ;; convex-c2) basic_machine=c2-convex os=-bsd ;; convex-c32) basic_machine=c32-convex os=-bsd ;; convex-c34) basic_machine=c34-convex os=-bsd ;; convex-c38) basic_machine=c38-convex os=-bsd ;; cray | j90) basic_machine=j90-cray os=-unicos ;; craynv) basic_machine=craynv-cray os=-unicosmp ;; cr16) basic_machine=cr16-unknown os=-elf ;; crds | unos) basic_machine=m68k-crds ;; crisv32 | crisv32-* | etraxfs*) basic_machine=crisv32-axis ;; cris | cris-* | etrax*) basic_machine=cris-axis ;; crx) basic_machine=crx-unknown os=-elf ;; da30 | da30-*) basic_machine=m68k-da30 ;; decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) basic_machine=mips-dec ;; decsystem10* | dec10*) basic_machine=pdp10-dec os=-tops10 ;; decsystem20* | dec20*) basic_machine=pdp10-dec os=-tops20 ;; delta | 3300 | motorola-3300 | motorola-delta \ | 3300-motorola | delta-motorola) basic_machine=m68k-motorola ;; delta88) basic_machine=m88k-motorola os=-sysv3 ;; dicos) basic_machine=i686-pc os=-dicos ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp ;; dpx20 | dpx20-*) basic_machine=rs6000-bull os=-bosx ;; dpx2* | dpx2*-bull) basic_machine=m68k-bull os=-sysv3 ;; ebmon29k) basic_machine=a29k-amd os=-ebmon ;; elxsi) basic_machine=elxsi-elxsi os=-bsd ;; encore | umax | mmax) basic_machine=ns32k-encore ;; es1800 | OSE68k | ose68k | ose | OSE) basic_machine=m68k-ericsson os=-ose ;; fx2800) basic_machine=i860-alliant ;; genix) basic_machine=ns32k-ns ;; gmicro) basic_machine=tron-gmicro os=-sysv ;; go32) basic_machine=i386-pc os=-go32 ;; h3050r* | hiux*) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; h8300hms) basic_machine=h8300-hitachi os=-hms ;; h8300xray) basic_machine=h8300-hitachi os=-xray ;; h8500hms) basic_machine=h8500-hitachi os=-hms ;; harris) basic_machine=m88k-harris os=-sysv3 ;; hp300-*) basic_machine=m68k-hp ;; hp300bsd) basic_machine=m68k-hp os=-bsd ;; hp300hpux) basic_machine=m68k-hp os=-hpux ;; hp3k9[0-9][0-9] | hp9[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k2[0-9][0-9] | hp9k31[0-9]) basic_machine=m68000-hp ;; hp9k3[2-9][0-9]) basic_machine=m68k-hp ;; hp9k6[0-9][0-9] | hp6[0-9][0-9]) basic_machine=hppa1.0-hp ;; hp9k7[0-79][0-9] | hp7[0-79][0-9]) basic_machine=hppa1.1-hp ;; hp9k78[0-9] | hp78[0-9]) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) # FIXME: really hppa2.0-hp basic_machine=hppa1.1-hp ;; hp9k8[0-9][13679] | hp8[0-9][13679]) basic_machine=hppa1.1-hp ;; hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; hppa-next) os=-nextstep3 ;; hppaosf) basic_machine=hppa1.1-hp os=-osf ;; hppro) basic_machine=hppa1.1-hp os=-proelf ;; i370-ibm* | ibm*) basic_machine=i370-ibm ;; # I'm not sure what "Sysv32" means. Should this be sysv3.2? i*86v32) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; i386-vsta | vsta) basic_machine=i386-unknown os=-vsta ;; iris | iris4d) basic_machine=mips-sgi case $os in -irix*) ;; *) os=-irix4 ;; esac ;; isi68 | isi) basic_machine=m68k-isi os=-sysv ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; m88k-omron*) basic_machine=m88k-omron ;; magnum | m3230) basic_machine=mips-mips os=-sysv ;; merlin) basic_machine=ns32k-utek os=-sysv ;; microblaze) basic_machine=microblaze-xilinx ;; mingw32) basic_machine=i386-pc os=-mingw32 ;; mingw32ce) basic_machine=arm-unknown os=-mingw32ce ;; miniframe) basic_machine=m68000-convergent ;; *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) basic_machine=m68k-atari os=-mint ;; mips3*-*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` ;; mips3*) basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k os=-coff ;; morphos) basic_machine=powerpc-unknown os=-morphos ;; msdos) basic_machine=i386-pc os=-msdos ;; ms1-*) basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` ;; mvs) basic_machine=i370-ibm os=-mvs ;; ncr3000) basic_machine=i486-ncr os=-sysv4 ;; netbsd386) basic_machine=i386-unknown os=-netbsd ;; netwinder) basic_machine=armv4l-rebel os=-linux ;; news | news700 | news800 | news900) basic_machine=m68k-sony os=-newsos ;; news1000) basic_machine=m68030-sony os=-newsos ;; news-3600 | risc-news) basic_machine=mips-sony os=-newsos ;; necv70) basic_machine=v70-nec os=-sysv ;; next | m*-next ) basic_machine=m68k-next case $os in -nextstep* ) ;; -ns2*) os=-nextstep2 ;; *) os=-nextstep3 ;; esac ;; nh3000) basic_machine=m68k-harris os=-cxux ;; nh[45]000) basic_machine=m88k-harris os=-cxux ;; nindy960) basic_machine=i960-intel os=-nindy ;; mon960) basic_machine=i960-intel os=-mon960 ;; nonstopux) basic_machine=mips-compaq os=-nonstopux ;; np1) basic_machine=np1-gould ;; nsr-tandem) basic_machine=nsr-tandem ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf ;; openrisc | openrisc-*) basic_machine=or32-unknown ;; os400) basic_machine=powerpc-ibm os=-os400 ;; OSE68000 | ose68000) basic_machine=m68000-ericsson os=-ose ;; os68k) basic_machine=m68k-none os=-os68k ;; pa-hitachi) basic_machine=hppa1.1-hitachi os=-hiuxwe2 ;; paragon) basic_machine=i860-intel os=-osf ;; parisc) basic_machine=hppa-unknown os=-linux ;; parisc-*) basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` os=-linux ;; pbd) basic_machine=sparc-tti ;; pbb) basic_machine=m68k-tti ;; pc532 | pc532-*) basic_machine=ns32k-pc532 ;; pc98) basic_machine=i386-pc ;; pc98-*) basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; pentiumpro | p6 | 6x86 | athlon | athlon_*) basic_machine=i686-pc ;; pentiumii | pentium2 | pentiumiii | pentium3) basic_machine=i686-pc ;; pentium4) basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pentium4-*) basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould ;; power) basic_machine=power-ibm ;; ppc) basic_machine=powerpc-unknown ;; ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppcle | powerpclittle | ppc-le | powerpc-little) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ppc64le | powerpc64little | ppc64-le | powerpc64-little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm ;; pw32) basic_machine=i586-unknown os=-pw32 ;; rdos) basic_machine=i386-pc os=-rdos ;; rom68k) basic_machine=m68k-rom68k os=-coff ;; rm[46]00) basic_machine=mips-siemens ;; rtpc | rtpc-*) basic_machine=romp-ibm ;; s390 | s390-*) basic_machine=s390-ibm ;; s390x | s390x-*) basic_machine=s390x-ibm ;; sa29200) basic_machine=a29k-amd os=-udi ;; sb1) basic_machine=mipsisa64sb1-unknown ;; sb1el) basic_machine=mipsisa64sb1el-unknown ;; sde) basic_machine=mipsisa32-sde os=-elf ;; sei) basic_machine=mips-sei os=-seiux ;; sequent) basic_machine=i386-sequent ;; sh) basic_machine=sh-hitachi os=-hms ;; sh5el) basic_machine=sh5le-unknown ;; sh64) basic_machine=sh64-unknown ;; sparclite-wrs | simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; sps7) basic_machine=m68k-bull os=-sysv2 ;; spur) basic_machine=spur-unknown ;; st2000) basic_machine=m68k-tandem ;; stratus) basic_machine=i860-stratus os=-sysv4 ;; sun2) basic_machine=m68000-sun ;; sun2os3) basic_machine=m68000-sun os=-sunos3 ;; sun2os4) basic_machine=m68000-sun os=-sunos4 ;; sun3os3) basic_machine=m68k-sun os=-sunos3 ;; sun3os4) basic_machine=m68k-sun os=-sunos4 ;; sun4os3) basic_machine=sparc-sun os=-sunos3 ;; sun4os4) basic_machine=sparc-sun os=-sunos4 ;; sun4sol2) basic_machine=sparc-sun os=-solaris2 ;; sun3 | sun3-*) basic_machine=m68k-sun ;; sun4) basic_machine=sparc-sun ;; sun386 | sun386i | roadrunner) basic_machine=i386-sun ;; sv1) basic_machine=sv1-cray os=-unicos ;; symmetry) basic_machine=i386-sequent os=-dynix ;; t3e) basic_machine=alphaev5-cray os=-unicos ;; t90) basic_machine=t90-cray os=-unicos ;; tic54x | c54x*) basic_machine=tic54x-unknown os=-coff ;; tic55x | c55x*) basic_machine=tic55x-unknown os=-coff ;; tic6x | c6x*) basic_machine=tic6x-unknown os=-coff ;; # This must be matched before tile*. tilegx*) basic_machine=tilegx-unknown os=-linux-gnu ;; tile*) basic_machine=tile-unknown os=-linux-gnu ;; tx39) basic_machine=mipstx39-unknown ;; tx39el) basic_machine=mipstx39el-unknown ;; toad1) basic_machine=pdp10-xkl os=-tops20 ;; tower | tower-32) basic_machine=m68k-ncr ;; tpf) basic_machine=s390x-ibm os=-tpf ;; udi29k) basic_machine=a29k-amd os=-udi ;; ultra3) basic_machine=a29k-nyu os=-sym1 ;; v810 | necv810) basic_machine=v810-nec os=-none ;; vaxv) basic_machine=vax-dec os=-sysv ;; vms) basic_machine=vax-dec os=-vms ;; vpp*|vx|vx-*) basic_machine=f301-fujitsu ;; vxworks960) basic_machine=i960-wrs os=-vxworks ;; vxworks68) basic_machine=m68k-wrs os=-vxworks ;; vxworks29k) basic_machine=a29k-wrs os=-vxworks ;; w65*) basic_machine=w65-wdc os=-none ;; w89k-*) basic_machine=hppa1.1-winbond os=-proelf ;; xbox) basic_machine=i686-pc os=-mingw32 ;; xps | xps100) basic_machine=xps100-honeywell ;; ymp) basic_machine=ymp-cray os=-unicos ;; z8k-*-coff) basic_machine=z8k-unknown os=-sim ;; z80-*-coff) basic_machine=z80-unknown os=-sim ;; none) basic_machine=none-none os=-none ;; # Here we handle the default manufacturer of certain CPU types. It is in # some cases the only manufacturer, in others, it is the most popular. w89k) basic_machine=hppa1.1-winbond ;; op50n) basic_machine=hppa1.1-oki ;; op60c) basic_machine=hppa1.1-oki ;; romp) basic_machine=romp-ibm ;; mmix) basic_machine=mmix-knuth ;; rs6000) basic_machine=rs6000-ibm ;; vax) basic_machine=vax-dec ;; pdp10) # there are many clones, so DEC is not a safe bet basic_machine=pdp10-unknown ;; pdp11) basic_machine=pdp11-dec ;; we32k) basic_machine=we32k-att ;; sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) basic_machine=cydra-cydrome ;; orion) basic_machine=orion-highlevel ;; orion105) basic_machine=clipper-highlevel ;; mac | mpw | mac-mpw) basic_machine=m68k-apple ;; pmac | pmac-mpw) basic_machine=powerpc-apple ;; *-unknown) # Make sure to match an already-canonicalized machine name. ;; *) echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 exit 1 ;; esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` ;; *-commodore*) basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` ;; *) ;; esac # Decode manufacturer-specific aliases for certain operating systems. if [ x"$os" != x"" ] then case $os in # First match some system type aliases # that might get confused with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux ;; -solaris1 | -solaris1.*) os=`echo $os | sed -e 's|solaris1|sunos4|'` ;; -solaris) os=-solaris2 ;; -svr4*) os=-sysv4 ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; # First accept the basic system types. # The portable systems comes first. # Each alternative MUST END IN A *, to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ | -sym* | -kopensolaris* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ | -aos* | -aros* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) case $basic_machine in x86-* | i*86-*) ;; *) os=-nto$os ;; esac ;; -nto-qnx*) ;; -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) os=`echo $os | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc ;; -linux*) os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) os=`echo $os | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) os=`echo $os | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition ;; -os400*) os=-os400 ;; -wince*) os=-wince ;; -osfrose*) os=-osfrose ;; -osf*) os=-osf ;; -utek*) os=-bsd ;; -dynix*) os=-bsd ;; -acis*) os=-aos ;; -atheos*) os=-atheos ;; -syllable*) os=-syllable ;; -386bsd) os=-bsd ;; -ctix* | -uts*) os=-sysv ;; -nova*) os=-rtmk-nova ;; -ns2 ) os=-nextstep2 ;; -nsk*) os=-nsk ;; # Preserve the version number of sinix5. -sinix5.*) os=`echo $os | sed -e 's|sinix|sysv|'` ;; -sinix*) os=-sysv4 ;; -tpf*) os=-tpf ;; -triton*) os=-sysv3 ;; -oss*) os=-sysv3 ;; -svr4) os=-sysv4 ;; -svr3) os=-sysv3 ;; -sysvr4) os=-sysv4 ;; # This must come after -sysvr4. -sysv*) ;; -ose*) os=-ose ;; -es1800*) os=-ose ;; -xenix) os=-xenix ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; -aros*) os=-aros ;; -kaos*) os=-kaos ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; -nacl*) ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 exit 1 ;; esac else # Here we handle the default operating systems that come with various machines. # The value should be what the vendor currently ships out the door with their # machine or put another way, the most popular os provided with the machine. # Note that if you're going to try to match "-MANUFACTURER" here (say, # "-sun"), then you have to tell the case statement up towards the top # that MANUFACTURER isn't an operating system. Otherwise, code above # will signal an error saying that MANUFACTURER isn't an operating # system, and we'll never get to this point. case $basic_machine in score-*) os=-elf ;; spu-*) os=-elf ;; *-acorn) os=-riscix1.2 ;; arm*-rebel) os=-linux ;; arm*-semi) os=-aout ;; c4x-* | tic4x-*) os=-coff ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 ;; pdp11-*) os=-none ;; *-dec | vax-*) os=-ultrix4.2 ;; m68*-apollo) os=-domain ;; i386-sun) os=-sunos4.0.2 ;; m68000-sun) os=-sunos3 # This also exists in the configure program, but was not the # default. # os=-sunos4 ;; m68*-cisco) os=-aout ;; mep-*) os=-elf ;; mips*-cisco) os=-elf ;; mips*-*) os=-elf ;; or32-*) os=-coff ;; *-tti) # must be before sparc entry or we get the wrong os. os=-sysv3 ;; sparc-* | *-sun) os=-sunos4.1.1 ;; *-be) os=-beos ;; *-haiku) os=-haiku ;; *-ibm) os=-aix ;; *-knuth) os=-mmixware ;; *-wec) os=-proelf ;; *-winbond) os=-proelf ;; *-oki) os=-proelf ;; *-hp) os=-hpux ;; *-hitachi) os=-hiux ;; i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) os=-sysv ;; *-cbm) os=-amigaos ;; *-dg) os=-dgux ;; *-dolphin) os=-sysv3 ;; m68k-ccur) os=-rtu ;; m88k-omron*) os=-luna ;; *-next ) os=-nextstep ;; *-sequent) os=-ptx ;; *-crds) os=-unos ;; *-ns) os=-genix ;; i370-*) os=-mvs ;; *-next) os=-nextstep3 ;; *-gould) os=-sysv ;; *-highlevel) os=-bsd ;; *-encore) os=-bsd ;; *-sgi) os=-irix ;; *-siemens) os=-sysv4 ;; *-masscomp) os=-rtu ;; f30[01]-fujitsu | f700-fujitsu) os=-uxpv ;; *-rom68k) os=-coff ;; *-*bug) os=-coff ;; *-apple) os=-macos ;; *-atari*) os=-mint ;; *) os=-none ;; esac fi # Here we handle the case where we know the os, and the CPU type, but not the # manufacturer. We pick the logical manufacturer. vendor=unknown case $basic_machine in *-unknown) case $os in -riscix*) vendor=acorn ;; -sunos*) vendor=sun ;; -cnk*|-aix*) vendor=ibm ;; -beos*) vendor=be ;; -hpux*) vendor=hp ;; -mpeix*) vendor=hp ;; -hiux*) vendor=hitachi ;; -unos*) vendor=crds ;; -dgux*) vendor=dg ;; -luna*) vendor=omron ;; -genix*) vendor=ns ;; -mvs* | -opened*) vendor=ibm ;; -os400*) vendor=ibm ;; -ptx*) vendor=sequent ;; -tpf*) vendor=ibm ;; -vxsim* | -vxworks* | -windiss*) vendor=wrs ;; -aux*) vendor=apple ;; -hms*) vendor=hitachi ;; -mpw* | -macos*) vendor=apple ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) vendor=atari ;; -vos*) vendor=stratus ;; esac basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` ;; esac echo $basic_machine$os exit # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" # End: odin-1.8.5/missing0000755000175000017500000002623311734622601011006 00000000000000#! /bin/sh # Common stub for a few missing GNU programs while installing. scriptversion=2009-04-28.21; # UTC # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006, # 2008, 2009 Free Software Foundation, Inc. # Originally by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try \`$0 --help' for more information" exit 1 fi run=: sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' sed_minuso='s/.* -o \([^ ]*\).*/\1/p' # In the cases where this matters, `missing' is being run in the # srcdir already. if test -f configure.ac; then configure_ac=configure.ac else configure_ac=configure.in fi msg="missing on your system" case $1 in --run) # Try to run requested program, and just exit if it succeeds. run= shift "$@" && exit 0 # Exit code 63 means version mismatch. This often happens # when the user try to use an ancient version of a tool on # a file that requires a minimum version. In this case we # we should proceed has if the program had been absent, or # if --run hadn't been passed. if test $? = 63; then run=: msg="probably too old" fi ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an error status if there is no known handling for PROGRAM. Options: -h, --help display this help and exit -v, --version output version information and exit --run try to run the given command, and emulate it if it fails Supported PROGRAM values: aclocal touch file \`aclocal.m4' autoconf touch file \`configure' autoheader touch file \`config.h.in' autom4te touch the output file, or create a stub one automake touch all \`Makefile.in' files bison create \`y.tab.[ch]', if possible, from existing .[ch] flex create \`lex.yy.c', if possible, from existing .c help2man touch the output file lex create \`lex.yy.c', if possible, from existing .c makeinfo touch the output file tar try tar, gnutar, gtar, then tar without non-portable flags yacc create \`y.tab.[ch]', if possible, from existing .[ch] Version suffixes to PROGRAM as well as the prefixes \`gnu-', \`gnu', and \`g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: Unknown \`$1' option" echo 1>&2 "Try \`$0 --help' for more information" exit 1 ;; esac # normalize program name to check for. program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` # Now exit if we have it, but it failed. Also exit now if we # don't have it and --version was passed (most likely to detect # the program). This is about non-GNU programs, so use $1 not # $program. case $1 in lex*|yacc*) # Not GNU programs, they don't have --version. ;; tar*) if test -n "$run"; then echo 1>&2 "ERROR: \`tar' requires --run" exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then exit 1 fi ;; *) if test -z "$run" && ($1 --version) > /dev/null 2>&1; then # We have it, but it failed. exit 1 elif test "x$2" = "x--version" || test "x$2" = "x--help"; then # Could not run --version or --help. This is probably someone # running `$TOOL --version' or `$TOOL --help' to check whether # $TOOL exists and not knowing $TOOL uses missing. exit 1 fi ;; esac # If it does not exist, or fails to run (possibly an outdated version), # try to emulate it. case $program in aclocal*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." touch aclocal.m4 ;; autoconf*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." touch configure ;; autoheader*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`acconfig.h' or \`${configure_ac}'. You might want to install the \`Autoconf' and \`GNU m4' packages. Grab them from any GNU archive site." files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` test -z "$files" && files="config.h" touch_files= for f in $files; do case $f in *:*) touch_files="$touch_files "`echo "$f" | sed -e 's/^[^:]*://' -e 's/:.*//'`;; *) touch_files="$touch_files $f.in";; esac done touch $touch_files ;; automake*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. You might want to install the \`Automake' and \`Perl' packages. Grab them from any GNU archive site." find . -type f -name Makefile.am -print | sed 's/\.am$/.in/' | while read f; do touch "$f"; done ;; autom4te*) echo 1>&2 "\ WARNING: \`$1' is needed, but is $msg. You might have modified some files without having the proper tools for further handling them. You can get \`$1' as part of \`Autoconf' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo "#! /bin/sh" echo "# Created by GNU Automake missing as a replacement of" echo "# $ $@" echo "exit 0" chmod +x $file exit 1 fi ;; bison*|yacc*) echo 1>&2 "\ WARNING: \`$1' $msg. You should only need it if you modified a \`.y' file. You may need the \`Bison' package in order for those modifications to take effect. You can get \`Bison' from any GNU archive site." rm -f y.tab.c y.tab.h if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.y) SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.c fi SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` if test -f "$SRCFILE"; then cp "$SRCFILE" y.tab.h fi ;; esac fi if test ! -f y.tab.h; then echo >y.tab.h fi if test ! -f y.tab.c; then echo 'main() { return 0; }' >y.tab.c fi ;; lex*|flex*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.l' file. You may need the \`Flex' package in order for those modifications to take effect. You can get \`Flex' from any GNU archive site." rm -f lex.yy.c if test $# -ne 1; then eval LASTARG="\${$#}" case $LASTARG in *.l) SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` if test -f "$SRCFILE"; then cp "$SRCFILE" lex.yy.c fi ;; esac fi if test ! -f lex.yy.c; then echo 'main() { return 0; }' >lex.yy.c fi ;; help2man*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a dependency of a manual page. You may need the \`Help2man' package in order for those modifications to take effect. You can get \`Help2man' from any GNU archive site." file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -f "$file"; then touch $file else test -z "$file" || exec >$file echo ".ab help2man is required to generate this page" exit $? fi ;; makeinfo*) echo 1>&2 "\ WARNING: \`$1' is $msg. You should only need it if you modified a \`.texi' or \`.texinfo' file, or any other file indirectly affecting the aspect of the manual. The spurious call might also be the consequence of using a buggy \`make' (AIX, DU, IRIX). You might want to install the \`Texinfo' package or the \`GNU make' package. Grab either from any GNU archive site." # The file to touch is that specified with -o ... file=`echo "$*" | sed -n "$sed_output"` test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` if test -z "$file"; then # ... or it is the one specified with @setfilename ... infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` file=`sed -n ' /^@setfilename/{ s/.* \([^ ]*\) *$/\1/ p q }' $infile` # ... or it is derived from the source name (dir/f.texi becomes f.info) test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info fi # If the file does not exist, the user really needs makeinfo; # let's fail without touching anything. test -f $file || exit 1 touch $file ;; tar*) shift # We have already tried tar in the generic part. # Look for gnutar/gtar before invocation to avoid ugly error # messages. if (gnutar --version > /dev/null 2>&1); then gnutar "$@" && exit 0 fi if (gtar --version > /dev/null 2>&1); then gtar "$@" && exit 0 fi firstarg="$1" if shift; then case $firstarg in *o*) firstarg=`echo "$firstarg" | sed s/o//` tar "$firstarg" "$@" && exit 0 ;; esac case $firstarg in *h*) firstarg=`echo "$firstarg" | sed s/h//` tar "$firstarg" "$@" && exit 0 ;; esac fi echo 1>&2 "\ WARNING: I can't seem to be able to run \`tar' with the given arguments. You may want to install GNU tar or Free paxutils, or check the command line arguments." exit 1 ;; *) echo 1>&2 "\ WARNING: \`$1' is needed, and is $msg. You might have modified some files without having the proper tools for further handling them. Check the \`README' file, it often tells you about the needed prerequisites for installing this package. You may also peek at any GNU archive site, in case some other package would contain this missing \`$1' program." exit 1 ;; esac exit 0 # Local variables: # eval: (add-hook 'write-file-hooks 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC" # time-stamp-end: "; # UTC" # End: odin-1.8.5/tjutils/0000755000175000017500000000000011735135550011162 500000000000000odin-1.8.5/tjutils/tjlog_code.h0000644000175000017500000000361211322062342013354 00000000000000#include template void Log::register_comp() { if(!registered) { // retry until LogBase:global is initialized registered=register_component(C::get_compName(),&(Log::set_log_level)); if(registered) { const char* env=getenv(C::get_compName()); if(env) set_log_level(logPriority(atoi(env))); } } if(!registered) { // global may not be initialized yet // Disable tracing until global becomes available logLevel=noLog; constrLevel=noLog; } } template Log::Log(const char* objectLabel, const char* functionName, logPriority level) : LogBase(C::get_compName(),objectLabel,0,functionName), constrLevel(level) { register_comp(); ODINLOG(*this,constrLevel) << "START" << STD_endl; } template Log::Log(const Labeled* labeledObject, const char* functionName, logPriority level) : LogBase(C::get_compName(),0,labeledObject,functionName), constrLevel(level) { register_comp(); ODINLOG(*this,constrLevel) << "START" << STD_endl; } template Log::~Log() { ODINLOG(*this,constrLevel) << "END" << STD_endl; } template logPriority Log::set_log_level(logPriority level) { if(level!=ignoreArgument) logLevel=level; return logLevel; } ///////////////////////////////////////////////////////////////////////////////////////////////////////// // unregister logging component by local static object if shared library is unloaded template class LogUnregister { public: LogUnregister() {} ~LogUnregister() {LogBase::unregister_component(C::get_compName());} }; #define LOGGROUNDWORK(COMPONENT) \ template class Log; \ EMPTY_TEMPL_LIST logPriority Log::logLevel=RELEASE_LOG_LEVEL; \ EMPTY_TEMPL_LIST bool Log::registered=false; \ static LogUnregister COMPONENT ## _unregister; odin-1.8.5/tjutils/tjstring.cpp0000644000175000017500000003275111322062342013450 00000000000000#include "tjstring.h" #include "tjarray.h" #include "tjtools.h" #include "tjlist.h" #include "tjlog.h" #include "tjcstd.h" #include "tjtest.h" #include "tjlog_code.h" const char* StringComp::get_compName() {return "string";} LOGGROUNDWORK(StringComp) /////////////////////////////////////////////////////////////////////////////////////////////// STD_string replaceStr(const STD_string& s, const STD_string& searchstring,const STD_string& replacement,whichOccurences mode) { Log odinlog("","replaceStr"); if(searchstring=="") return s; STD_string::size_type pos=0; int times=0; STD_string concat; STD_string result(s); ODINLOG(odinlog,normalDebug) << "trying to replace >" << searchstring << "< with >" << replacement << "< with mode " << mode << STD_endl; while( (pos=result.find(searchstring,pos)) != STD_string::npos) { concat = result.substr(0,pos); concat += replacement; unsigned int remainingstart=pos+searchstring.length(); unsigned int length2end=result.length()-remainingstart; ODINLOG(odinlog,normalDebug) << "pos/remainingstart/length2end=" << pos << "/" << remainingstart << "/" << length2end << STD_endl; concat += result.substr(remainingstart,length2end); result=concat; // re-feed temporary result into this loop ODINLOG(odinlog,normalDebug) << "result(" << times << ")=" << result << STD_endl; pos+=replacement.length(); // Set to new position: Right after replacement times++; if(pos>=result.length()) break; if(mode==firstOccurence) break; } ODINLOG(odinlog,normalDebug) << "replacing " << times << " time(s) successful" << STD_endl; return result; } //////////////////////////////////////// STD_string extract(const STD_string& s, const STD_string& blockbegin,const STD_string& blockend,bool hierachical,int beginpos) { Log odinlog("","extract"); int startpos,nextbegin,nextend,nocc,tmppos; STD_string tt; if(blockbegin=="") { startpos=beginpos; nextbegin=startpos+1; } else { STD_string::size_type startpos_st = s.find(blockbegin,beginpos); STD_string::size_type nextbegin_st= s.find(blockbegin,beginpos+1); if(startpos_st==STD_string::npos) startpos=-1; else startpos= startpos_st; if(nextbegin_st==STD_string::npos) nextbegin=-1; else nextbegin=nextbegin_st; } if(blockend=="") nextend=s.length(); else { STD_string::size_type nextend_st=s.find(blockend,startpos+1); if(nextend_st==STD_string::npos) nextend=-1; else nextend=nextend_st; } ODINLOG(odinlog,normalDebug) << "startpos/nextbegin/nextend=" << startpos << "/" << nextbegin << "/" << nextend << STD_endl; if (hierachical) { unsigned int remainingstart=startpos+blockbegin.length(); tt=s.substr(remainingstart,nextend-remainingstart); nocc=noccur(tt,blockbegin); while(nocc>0) { tmppos=nextend; for(int i=0;imin && absval odinlog("","justificate"); STD_string result; if(indention>=linewidth) { ODINLOG(odinlog,errorLog) << "indention>=linewidth !" << STD_endl; return result; } STD_string blank(" "); svector tokenvector=tokens(s); STD_list linetokens; unsigned int linesize=0; unsigned int linewidthindent=linewidth-indention; bool firstline=true; for(unsigned int itoken=0; itoken linewidthindent ) { int rest=linewidthindent-linesize; ivector blankvector; if(ntokens>1) { blankvector.resize(ntokens-1); while(rest>0) { for(unsigned int i=0; i<(ntokens-1); i++) { if(rest>0) blankvector[i]++; rest--; } } } if(firstline) { if(!ignore_firstline) result+=n_times(blank,indention); firstline=false; } else result+=n_times(blank,indention); unsigned int iblank=0; for(STD_list::iterator it=linetokens.begin(); it!=linetokens.end(); ++it) { result+=(*it); if(iblank<(ntokens-1)) result+=n_times(blank,blankvector[iblank]); iblank++; } result+="\n"; linetokens.erase(linetokens.begin(),linetokens.end()); linetokens.push_back(tokenvector[itoken]); linesize=tokenlength; } else { linetokens.push_back(tokenvector[itoken]); linesize+=tokenlength; } } if(linetokens.size()) { if(firstline) { if(!ignore_firstline) result+=n_times(blank,indention); } else result+=n_times(blank,indention); for(STD_list::iterator it=linetokens.begin(); it!=linetokens.end(); ++it) { result+=(*it); result+=blank; } result+="\n"; } return result; } //////////////////////////////////////// int textbegin(const STD_string& s, int startpos, const char custom_separator) { // Log odinlog("","textbegin"); int n=s.length(); int pos=startpos; if( startpos<0 || startpos>=n) { // ODINLOG(odinlog,normalDebug) << "index(" << startpos << ") out of range(" << n << ")" << STD_endl; return -1; } else { if(custom_separator) { while(pos odinlog("","sepbegin"); int n=s.length(); int pos=startpos; if( startpos<0 || startpos>=n) { // ODINLOG(odinlog,normalDebug) << "index(" << startpos << ") out of range(" << n << ")" << STD_endl; return -1; } else { if(custom_separator) { while(pos odinlog("","load"); #ifndef NO_FILEHANDLING LONGEST_INT file_size=filesize(filename.c_str()); if(file_size<=0) { ODINLOG(odinlog,warningLog) << "file >" << filename << "< not found or is empty" << STD_endl; return -1; } FILE* file_ptr=FOPEN(filename.c_str(),modestring(readMode)); if(file_ptr==NULL) { ODINLOG(odinlog,errorLog) << "unable to open file >" << filename << "< - " << lasterr() << STD_endl; return -1; } char* s = new char [file_size+1]; int i=fread(s,1,file_size,file_ptr); s[i]='\0'; str=STD_string((const char*)s); if(file_ptr!=NULL) fclose(file_ptr); if(s) delete[] s; #endif return 0; } //////////////////////////////////////// int write(const STD_string& str, const STD_string& filename, fopenMode mode) { Log odinlog("","write"); #ifndef NO_FILEHANDLING FILE* file_ptr=FOPEN(filename.c_str(),modestring(mode)); if(file_ptr==NULL) { ODINLOG(odinlog,errorLog) << "unable to create file: >" << filename << "< - " << lasterr() << STD_endl; return -1; } fwrite(str.c_str(),sizeof(char),str.length(),file_ptr); if(file_ptr!=NULL) fclose(file_ptr); #endif return 0; } ///////////////////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class StringTest : public UnitTest { public: StringTest() : UnitTest(StringComp::get_compName()) {} private: bool check() const { Log odinlog(this,"check"); STD_string printed, expected; expected="a"; printed=replaceStr("abb","b",""); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "replaceStr failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="a"; printed=shrink("\n\n \n\ta "); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "shrink failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="00123"; printed=itos(123,10000); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "itos(1) failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } printed=itos(123,99999); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "itos(2) failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="bb"; printed=extract("aaa[bb]cc", "[", "]"); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "extract failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="a(b)c"; printed=extract("g(a(b)c)", "(", ")", true); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "extract(hierachical) failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } return true; } }; void alloc_StringTest() {new StringTest();} // create test instance #endif odin-1.8.5/tjutils/tjheap.cpp0000644000175000017500000001614111322062342013052 00000000000000#include "tjheap.h" #include "tjstring.h" // for ftos #ifdef CUSTOM_HEAP #define MYHEAP_SIZE CUSTOM_HEAP_SIZE*0x100000 void custom_heap_error(const char* txt) { if(Heap::tracefunc) Heap::tracefunc(txt); else fprintf(stderr,"%s\n",txt); abort(); } //#define USE_TRIVIAL_ALGORITM #ifdef USE_TRIVIAL_ALGORITM //////////////////////////////////// START of Trivial Algoritm ///////////////////////////// #define TRIVIAL_HEAP_SIZE 100*MYHEAP_SIZE // Use large heap since it is never freed static char myheap[TRIVIAL_HEAP_SIZE]; static unsigned int heapcount=0; void* trivial_alloc(size_t size) { if((heapcount+size)>=TRIVIAL_HEAP_SIZE) { custom_heap_error("Out of memory"); } void* result=myheap+heapcount; heapcount+=size; return result; } //#ifndef STL_REPLACEMENT //void* operator new(size_t size) throw (std::bad_alloc) {return trivial_alloc(size);} //#else void* operator new(size_t size) {return trivial_alloc(size);} //#endif //void* operator new(size_t size) {return qf_malloc(size);} void* operator new[](size_t size) {return trivial_alloc(size);} void operator delete(void* mptr) {} void operator delete[](void* mptr) {} //////////////////////////////////// END of Trivial Algoritm ///////////////////////////// #else // USE_TRIVIAL_ALGORITM /////////////////////////////////// START of List Allocator Algoritm ///////////////////// #define ALIGNMENT 8 static char la_heap[MYHEAP_SIZE]; static bool la_init_done=false; inline size_t la_downalign(size_t ptr) { return (ptr/ALIGNMENT)*ALIGNMENT; } inline size_t la_upalign(size_t ptr) { if(ptr%ALIGNMENT) return (ptr/ALIGNMENT+1)*ALIGNMENT; return (ptr/ALIGNMENT)*ALIGNMENT; } struct la_cell { inline void set_used() {next=(la_cell*)((size_t)next | 1);} // Set least significant bit inline void set_unused() {next=(la_cell*)((size_t)next & ~1);} // Clear least significant bit inline bool is_used() const { return (size_t)next & 1; // Read least significant bit } inline size_t size() const { if(nextaligned_next(); la_cell* prev=cell->aligned_prev(); // Exclude from check if(next==la_begin || next==la_end) return; if(prev==la_begin || prev==la_end) return; if(cell==la_begin || cell==la_end) return; if(prev>=cell) {fprintf(stderr,"%s: prev>=cell\n",caller); custom_heap_error("check_integrity failed");} if(cell>=next) {fprintf(stderr,"%s: cell>=next\n",caller); custom_heap_error("check_integrity failed");} } void la_dump() { la_cell* iter=la_begin; while(1) { fprintf(stdout,"size(%p)=%i\t\t prev=%p\t\t next=%p\t\t used=%i\n",iter,iter->size(),iter->aligned_prev(),iter->aligned_next(),iter->is_used()); iter=iter->aligned_next(); if(iter==la_begin) { break; } } } */ inline void la_init() { // some checks for implicit assumptions if(la_upalign(sizeof(la_cell))!=sizeof(la_cell)) custom_heap_error("la_cell does not align"); if(sizeof(la_cell)!=(2*sizeof(la_cell*))) custom_heap_error("sizeof(la_cell) exceeds"); // Place begin cell la_begin=(la_cell*)la_upalign((size_t)la_heap); // Place end cell char* offset=la_heap+MYHEAP_SIZE-2*(ALIGNMENT+sizeof(la_cell)); // leave enough space for un-aligned memory and both cells la_end=(la_cell*)la_downalign((size_t)offset); // Connect both cells cyclically la_begin->prev=la_begin->next=la_end; la_end->prev=la_end->next=la_begin; la_begin->set_unused(); // This will hold all of the free memory upon startup la_end->set_used(); // So last cell will never be modified la_rovptr=la_begin; // set to begin of list la_init_done=true; } inline void* list_alloc(size_t size) { if(!la_init_done) la_init(); size=la_upalign(size); // Iterate to next free cell la_cell* iter=la_rovptr; while(iter->is_used() || iter->size()aligned_next(); if(iter==la_rovptr) { // la_dump(); custom_heap_error("Out of memory"); } } // To split a cell is only useful if it can accomodate // some data (i.e. ALIGNMENT) plus one extra cell header bool split_cell = ( iter->size() >= (size+ALIGNMENT+sizeof(la_cell)) ); if(split_cell) { la_cell* next=iter->aligned_next(); // Create new header to hold remainder of cell la_cell* remainder= (la_cell*)( (size_t)iter + sizeof(la_cell) + size ); // Connect cells remainder->next=next; remainder->prev=iter; next->prev=remainder; iter->next=remainder; remainder->set_unused(); iter->set_used(); la_rovptr=remainder; // Set to the (free) remainder return iter->memptr(); } else { // Use entire cell iter->set_used(); la_rovptr=iter->aligned_next(); // Set to the cell after the exact match return iter->memptr(); } } inline void delete_cell(la_cell* cell) { // check_integrity("delete_cell:cell",cell); la_cell* next=cell->aligned_next(); la_cell* prev=cell->aligned_prev(); // Connect ends prev->next=next; next->prev=prev; // Alternative: Just jump to freed space if sufficiently large // However, this seems to have a somewhat arbitray maximum in // performance depending on the threshold, so we will not use it // if(prev->size()>16*ALIGNMENT) la_rovptr=prev; // else la_rovptr=next; la_rovptr=prev; // Set roving pointer to free space. (Found out empirically that this gives a great performance boost) } inline void list_free(void *ptr) { // Convert pointer to header la_cell* freecell = (la_cell*) ( (size_t)ptr - sizeof(la_cell) ); // Try to join with next la_cell* nextcell=freecell->aligned_next(); if(!nextcell->is_used()) delete_cell(nextcell); // Try to join with previous if(!freecell->aligned_prev()->is_used()) delete_cell(freecell); else freecell->set_unused(); // Otherwise, just reset used bit } //#ifndef STL_REPLACEMENT //void* operator new(size_t size) throw (std::bad_alloc) {return list_alloc(size);} //#else void* operator new(size_t size) {return list_alloc(size);} //#endif //void* operator new(size_t size) {return qf_malloc(size);} void* operator new[](size_t size) {return list_alloc(size);} void operator delete(void* mptr) {list_free(mptr);} void operator delete[](void* mptr) {list_free(mptr);} /////////////////////////////////// END of List Allocator Algoritm ///////////////////// #endif // USE_TRIVIAL_ALGORITM #endif // CUSTOM_HEAP heaptracefunction Heap::tracefunc=0; void Heap::malloc_stats() { #ifdef CUSTOM_HEAP #ifndef USE_TRIVIAL_ALGORITM if(la_end) { float used_mb=float(MYHEAP_SIZE-la_end->aligned_prev()->size())/float(0x100000); // Estimate by size of last cell if(Heap::tracefunc) Heap::tracefunc(("Memory used: "+ftos(used_mb)+"/"+ftos(CUSTOM_HEAP_SIZE)+" MB").c_str()); } #endif #endif // CUSTOM_HEAP } odin-1.8.5/tjutils/tjtest.h0000644000175000017500000000332211322062342012556 00000000000000/*************************************************************************** tjtest.h - description ------------------- begin : Mon Dec 12 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJTEST_H #define TJTEST_H #include #include /** * @addtogroup tjutils * @{ */ #ifndef NO_UNIT_TEST /** * Base class for unit tests. Derive from this, implement * the check() function and place a static instanve in the * source file to register it for the test run. */ class UnitTest : public StaticHandler, public Labeled { public: static int check_all(); static void init_static(); static void destroy_static(); static const char* get_compName(); protected: UnitTest(const char* label); virtual ~UnitTest() {} private: virtual bool check() const = 0; static STD_list* tests; }; #endif /** @} */ #endif odin-1.8.5/tjutils/tjhandler.h0000644000175000017500000001267511322062342013227 00000000000000/*************************************************************************** tjhandler.h - description ------------------- begin : Mon Aug 19 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJHANDLER_H #define TJHANDLER_H #include #include /** * @addtogroup tjutils * @{ */ class HandlerComponent { public: static const char* get_compName(); }; ////////////////////////////////////////////////////////////// template class Handled; // forawrd declaration ///////////////////////////////////////////// template class Handler { public: Handler(); Handler(const Handler& handler); Handler& operator = (const Handler& handler); ~Handler(); const Handler& clear_handledobj() const; const Handler& set_handled(I handled) const; I get_handled() const; private: friend class Handled; const Handler& handled_remove(Handled* handled) const; mutable I handledobj; }; ///////////////////////////////////////////// template class Handled { public: Handled(); ~Handled(); bool is_handled() const {return bool(handlers.size());} private: friend class Handler; const Handled& set_handler(const Handler& handler) const; const Handled& erase_handler(const Handler& handler) const; mutable STD_list< const Handler* > handlers; }; //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// class SingletonBase; // forward declaration // mapping between singletons and labels typedef STD_map SingletonMap; class SingletonBase { public: virtual void* get_ptr() const = 0; static SingletonMap* get_singleton_map(); static void set_singleton_map_external(SingletonMap* extmap); protected: SingletonBase(); virtual ~SingletonBase() {} static STD_string get_singleton_label(SingletonBase* sing_ptr); static void* get_external_map_ptr(const STD_string& sing_label); static SingletonMap* singleton_map; static SingletonMap* singleton_map_external; }; //////////////////////////////////////////////////////////////////// /** * Helper class to enable locking of resources while accessing them with pointer-like syntax. */ template class LockProxy { public: LockProxy(volatile T* r, Mutex* m) : presource(const_cast(r)), pmutex(m) {if(pmutex) pmutex->lock();} ~LockProxy() {if(pmutex) pmutex->unlock();} T* operator -> () {return presource;} private: T* presource; Mutex* pmutex; }; //////////////////////////////////////////////////////////////////// /** * Template class to manage singleton objects of type T, * i.e. those objects which are exist only once in the * program. The instantiation must be a static field of * of a certain class. The init/destroy member functions * are used to create/destroy the singleton. * If 'thread_safe' is set to 'true', use a mutex to manage multi-threaded * access to the singleton object. * * Its main purpose is to * share singletons across DLL boundaries on Windows * and/or thread-safe access to global resources. * This class has an pointer-to-T-like interface. */ template // VxWorks does not support default-template args class SingletonHandler : public SingletonBase { public: SingletonHandler() { // do nothing because members are already initialized by init() } /** * Initialize the singleton with the unique identifier 'unique_label'. * The singleton object will be allocated if it does not already exist * somewhere in the program. */ void init (const char* unique_label); /** * Deletes the singleton */ void destroy (); /** * Copies this to 'destination' */ void copy(T& destination) const; /** * Returns unlocked ptr to object (know what you are doing) */ T* unlocked_ptr() {return get_map_ptr();} // emulate pointer syntax: /** * Returns mutex-locked pointer to handled singleton */ LockProxy operator -> () {return LockProxy(get_map_ptr(),mutex);} /** * Returns read-only pointer to handled singleton */ const T* operator -> () const {return get_map_ptr();} /** * Returns whether singleton is already initialized */ operator bool () const {return (bool)get_map_ptr();} private: // implement virtual function of SingletonBase void* get_ptr() const {return ptr;} T* get_map_ptr() const; // Use pointers to avoid the need for static initialization mutable T* ptr; STD_string* singleton_label; Mutex* mutex; }; /** @} */ #endif odin-1.8.5/tjutils/tjprocess.h0000644000175000017500000000671611322062342013267 00000000000000/*************************************************************************** tjprocess.h - description ------------------- begin : Sat May 5 2007 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJPROCESS_H #define TJPROCESS_H #include #include /** * @addtogroup tjutils * @{ */ //////////////////////////////////////////////////////////////////// // for debugging class ProcessComponent { public: static const char* get_compName(); }; //////////////////////////////////////////////////////////////////// /** * Class to for process abstraction. */ class Process { public: /** * Create non-running process. */ Process() {reset();} /** * Start new process with by executing 'cmdline'. If 'block_till_finished' is true, * return only after process has terminated. * If 'log_std_streams' is true, the output of stdout/stderr is catched and can * be queried later by finished(). * Returns 'true' if no error occured. */ bool start(const STD_string& cmdline, bool block_till_finished=false, bool log_std_streams=true); /** * Return whether process has terminated, returns return value and stdout/stderr * output in 'proc_return_value' and 'stdout_result/stderr_result', respectively. * If 'block_till_finished' is true return only after process has terminated. */ bool finished(int& proc_return_value, STD_string& stdout_result, STD_string& stderr_result, bool block_till_finished=false); /** * Return whether process has terminated, returns return value in 'proc_return_value'. * Writes stdout/stderr of child process to the log. * If 'block_till_finished' is true return only after process has terminated. */ bool finished(int& proc_return_value, bool block_till_finished=false); /** * Kill process. Additionlly, kill child processes whose program name is in 'extra_kill'. */ bool kill(const svector& extra_kill=svector()); /** * Start process by executing 'cmdline'. Return after process has terminated with * stdout/stderr output in 'stdout_result/stderr_result'. Returns return code of the process. */ static int system(const STD_string& cmdline, STD_string& stdout_result, STD_string& stderr_result); // Comparison operators for list of processes with STL replacement bool operator == (const Process& op) const {return pid==op.pid;} bool operator < (const Process& op) const {return pid!=op.pid;} bool operator != (const Process& op) const {return !(*this==op);} private: static bool read_pipe(int fd, STD_string& result); void reset() {pid=0; stdout_child=-1; stderr_child=-1;} int pid; int stdout_child; int stderr_child; }; /** @} */ #endif odin-1.8.5/tjutils/tjtypes.h0000644000175000017500000001027111322062342012744 00000000000000/*************************************************************************** tjtypes.h - description ------------------- begin : Thu Jul 24 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJTYPES_H #define TJTYPES_H #include #include /** * @addtogroup tjutils * @{ */ // Get appropriate data types for signed/unsigned 8, 16 and 32 bit data on this platform #if SIZEOF_CHAR == 1 typedef char s8bit; typedef unsigned char u8bit; #else #error "sizeof(char)!=1" #endif #if SIZEOF_SHORT == 2 typedef short s16bit; typedef unsigned short u16bit; #else #error "sizeof(short)!=2" #endif #if SIZEOF_INT == 4 typedef int s32bit; typedef unsigned int u32bit; #else #if SIZEOF_LONG == 4 typedef long s32bit; typedef unsigned long u32bit; #else #error "sizeof(int)!=4 and sizeof(long)!=4" #endif #endif /** * Class to manage string conversions and properties of * simple (i.e. atomic) types. To be used in higher level * template classes to dispatch functionality according * to type. */ class TypeTraits { public: // Convert a type's value to a string static STD_string type2string(s8bit v) {return itos(v);} static STD_string type2string(u8bit v) {return itos(v);} static STD_string type2string(s16bit v) {return itos(v);} static STD_string type2string(u16bit v) {return itos(v);} static STD_string type2string(s32bit v) {return itos(v);} static STD_string type2string(u32bit v) {return itos(v);} static STD_string type2string(float v) {return ftos(v);} static STD_string type2string(double v) {return ftos(float(v));} static STD_string type2string(const STD_complex& v) {return ctos(v);} static STD_string type2string(const STD_string& v) {return v;} // Parses type's value from string static void string2type(const STD_string& s, s8bit& v) {v=(s8bit)atoi(s.c_str());} static void string2type(const STD_string& s, u8bit& v) {v=(u8bit)atoi(s.c_str());} static void string2type(const STD_string& s, s16bit& v) {v=(s16bit)atoi(s.c_str());} static void string2type(const STD_string& s, u16bit& v) {v=(u16bit)atoi(s.c_str());} static void string2type(const STD_string& s, s32bit& v) {v=(s32bit)atoi(s.c_str());} static void string2type(const STD_string& s, u32bit& v) {v=(u32bit)atoi(s.c_str());} static void string2type(const STD_string& s, float& v) {v=(float)atof(s.c_str());} static void string2type(const STD_string& s, double& v) {v=atof(s.c_str());} static void string2type(const STD_string& s, STD_complex& v) {v=stoc(s);} static void string2type(const STD_string& s, STD_string& v) {v=s;} // Type label (identifier) as string static const char* type2label(s8bit) {return "s8bit";} static const char* type2label(u8bit) {return "u8bit";} static const char* type2label(s16bit) {return "s16bit";} static const char* type2label(u16bit) {return "u16bit";} static const char* type2label(s32bit) {return "s32bit";} static const char* type2label(u32bit) {return "u32bit";} static const char* type2label(float) {return "float";} static const char* type2label(double) {return "double";} static const char* type2label(const STD_complex&) {return "complex";} static const char* type2label(const STD_string&) {return "string";} /** * Returns size of data type */ static unsigned int typesize(const STD_string& typelabel); }; /** @} */ #endif odin-1.8.5/tjutils/tjstream.h0000644000175000017500000001451011322062342013073 00000000000000/*************************************************************************** tjstream.h - description ------------------- begin : Sun Jun 13 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJSTREAM_H #define TJSTREAM_H #include // Macros, includes and typedefs are handled in tjstd.h to avoid circular dependencies typedef STD_ostream& (*streammanipulator)(STD_ostream&); /** * @addtogroup tjutils * @{ */ #ifdef STREAM_REPLACEMENT class tjstd_ostream { public: tjstd_ostream() {} virtual ~tjstd_ostream() {} inline tjstd_ostream& operator<<(char v) {append2buff(STD_string(1,v)); return *this;} inline tjstd_ostream& operator<<(unsigned char v) {append2buff(STD_string(1,v)); return *this;} inline tjstd_ostream& operator<<(signed char v) {append2buff(STD_string(1,v)); return *this;} inline tjstd_ostream& operator<<(const char* v) {append2buff(v); return *this;} inline tjstd_ostream& operator<<(int v) {buff_int(v); return *this;} inline tjstd_ostream& operator<<(unsigned int v) {buff_int(v); return *this;} inline tjstd_ostream& operator<<(long v) {buff_int(v); return *this;} inline tjstd_ostream& operator<<(unsigned long v) {buff_int(v); return *this;} #ifdef HAVE_LONG_LONG inline tjstd_ostream& operator<<(long long v) {buff_int(v); return *this;} #endif inline tjstd_ostream& operator<<(short v) {buff_int(v); return *this;} inline tjstd_ostream& operator<<(unsigned short v){buff_int(v); return *this;} inline tjstd_ostream& operator<<(bool v) {if(v) append2buff("true"); else append2buff("false"); return *this;} inline tjstd_ostream& operator<<(double v) {buff_float(v); return *this;} inline tjstd_ostream& operator<<(float v) {buff_float(v); return *this;} inline tjstd_ostream& operator<<(streammanipulator v) {v(*this); return *this;} private: // disable copying tjstd_ostream(const tjstd_ostream&) {} tjstd_ostream& operator = (const tjstd_ostream&) {return *this;} virtual void append2buff(const STD_string& str) {} // do nothing by default, i.e. for cout/cerr void buff_float(float f); void buff_int(int i); }; //////////////////////////////////////////////////////////////////////////// class tjstd_ostringstream : public tjstd_ostream { public: tjstd_ostringstream() {} ~tjstd_ostringstream() {} const STD_string& str() const {return buff;} private: // disable copying tjstd_ostringstream(const tjstd_ostringstream&) {} tjstd_ostringstream& operator = (const tjstd_ostringstream&) {return *this;} // overloaded from tjstd_ostream void append2buff(const STD_string& str) {buff+=str;} STD_string buff; }; //////////////////////////////////////////////////////////////////////////// class tjstd_ofstream : public tjstd_ostream { public: tjstd_ofstream(const char* filename=""); ~tjstd_ofstream() {close();} void close(); bool bad() {return !file_ptr;} private: // disable default construction and copying tjstd_ofstream(const tjstd_ofstream&) {} tjstd_ofstream& operator = (const tjstd_ofstream&) {return *this;} // overloaded from tjstd_ostream void append2buff(const STD_string& str); void* file_ptr; }; //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// class tjstd_istream { public: tjstd_istream() {} inline tjstd_istream& operator>>(char) {return *this;} inline tjstd_istream& operator>>(unsigned char) {return *this;} inline tjstd_istream& operator>>(signed char) {return *this;} inline tjstd_istream& operator>>(const char *) {return *this;} inline tjstd_istream& operator>>(int) {return *this;} inline tjstd_istream& operator>>(unsigned int) {return *this;} inline tjstd_istream& operator>>(long) {return *this;} inline tjstd_istream& operator>>(unsigned long) {return *this;} #ifdef HAVE_LONG_LONG inline tjstd_istream& operator>>(long long) {return *this;} #endif inline tjstd_istream& operator>>(short) {return *this;} inline tjstd_istream& operator>>(unsigned short){return *this;} inline tjstd_istream& operator>>(bool) {return *this;} inline tjstd_istream& operator>>(double) {return *this;} inline tjstd_istream& operator>>(float) {return *this;} inline tjstd_istream& get(char&) {return *this;} inline tjstd_istream& putback(char) {return *this;} operator void* () const {return 0;} // stream is always empty }; inline tjstd_istream& tjstd_getline(tjstd_istream& is, STD_string&) {return is;} //////////////////////////////////////////////////////////////////////////// class tjstd_ifstream : public tjstd_istream { public: tjstd_ifstream(const char* ="") {} void close() {} bool bad() {return false;} }; //////////////////////////////////////////////////////////////////////////// static tjstd_ostream tjstd_cout; static tjstd_ostream tjstd_cerr; static tjstd_istream tjstd_cin; inline STD_ostream& tjstd_endl(STD_ostream& os) {return os << "\n";} inline STD_ostream& tjstd_flush(STD_ostream& os) {return os;} inline const char* tjstd_setprecision(unsigned int) {return "";} #endif /** @} */ #endif odin-1.8.5/tjutils/tjprocess.cpp0000644000175000017500000002767611322062342013632 00000000000000#include "tjprocess.h" #include "tjtest.h" #include "tjlog_code.h" #ifdef USING_WIN32 // Win-style process handling #include #include #include #include #else #if defined(HAVE_SYS_WAIT_H) && defined(HAVE_SYS_TYPES_H) && defined(HAVE_UNISTD_H) && defined(HAVE_SIGNAL_H) // Unix-style process handling #include #include #include #include #define USING_UNIX_PROCESSES #else #warning "no process handling style selected" #endif #endif /////////////////////////////////////////////////////////// const char* ProcessComponent::get_compName() {return "Process";} LOGGROUNDWORK(ProcessComponent) /////////////////////////////////////////////////////////// // quick hack to kill pending cc1plus process void kill_additional_procs(const svector& extra_kill) { Log odinlog("","kill_additional_procs"); #ifdef USING_UNIX_PROCESSES if(!extra_kill.size()) return; STD_string pslist; STD_string stderrstr; Process ps; if(!ps.start("ps")) return; int retval; if(!ps.finished(retval, pslist, stderrstr, true)) return; ODINLOG(odinlog,normalDebug) << "pslist=" << pslist << STD_endl; svector toks(tokens(pslist)); if(toks.size()<8) return; for(unsigned int i=4; i odinlog("Process","start"); svector cmdtoks(tokens(cmdline)); unsigned int ntoks=cmdtoks.size(); if(!ntoks) { ODINLOG(odinlog,errorLog) << "empty cmdline" << STD_endl; return false; } // kill previously started process kill(); // will reset pid, stdout/stderr_child #ifndef HAVE_READ if(log_std_streams) { ODINLOG(odinlog,errorLog) << "Cannot log_std_streams without read" << STD_endl; return false; } #endif int pipefd_stdout[2]; // pair of file descriptors for stdout pipe int pipefd_stderr[2]; // pair of file descriptors for stderr pipe if(log_std_streams) { bool pipeerror=false; #ifdef USING_UNIX_PROCESSES if(pipe(pipefd_stdout)==-1) pipeerror=true; if(pipe(pipefd_stderr)==-1) pipeerror=true; #endif #ifdef USING_WIN32 if(_pipe( pipefd_stdout, 10000, O_NOINHERIT | O_BINARY)==-1) pipeerror=true; if(_pipe( pipefd_stderr, 10000, O_NOINHERIT | O_BINARY)==-1) pipeerror=true; #endif if(pipeerror) { ODINLOG(odinlog,errorLog) << "pipe: " << lasterr() << STD_endl; return false; } } #ifdef USING_UNIX_PROCESSES pid = ::fork(); #endif #ifdef USING_WIN32 const char* args[100]; if(ntoks>=100) { ODINLOG(odinlog,errorLog) << "too many args" << STD_endl; return false; } STD_string prog(replaceStr(cmdtoks[0],"\"","")); ODINLOG(odinlog,normalDebug) << "prog=" << prog << STD_endl; for(unsigned int itok=0; itok odinlog("Process","finished"); bool console_log= ( stdout_child==-1 || stderr_child==-1 ); // Check before calling finish() STD_string coutstr; STD_string cerrstr; bool result=Process::finished(proc_return_value,coutstr,cerrstr,block_till_finished); if(console_log) { // We are logging directly to the console STD_cout << coutstr; STD_cerr << cerrstr; } else { if(coutstr.length()) ODINLOG(odinlog,infoLog) << coutstr; // dump stdout result of child process if(cerrstr.length()) ODINLOG(odinlog,errorLog) << cerrstr; // dump stderr result of child process } return result; } bool Process::read_pipe(int fd, STD_string& result) { Log odinlog("Process","read_pipe"); char buff[ODIN_MAXCHAR+1]; result=""; while(true) { int nbytes=0; #ifdef HAVE_READ nbytes=read(fd, (void*)buff, ODIN_MAXCHAR); #else ODINLOG(odinlog,errorLog) << "read missing"<< STD_endl; return false; #endif if(nbytes<0) { ODINLOG(odinlog,errorLog) << "read: " << lasterr() << STD_endl; return false; } if(!nbytes) break; buff[nbytes]='\0'; result+=buff; } #if defined(USING_UNIX_PROCESSES) || defined(USING_WIN32) close(fd); #endif return true; } bool Process::kill(const svector& extra_kill) { Log odinlog("Process","kill"); ODINLOG(odinlog,normalDebug) << "pid=" << pid << STD_endl; if(pid) { ODINLOG(odinlog,normalDebug) << "Sending SIGKILL to process " << pid << STD_endl; #ifdef USING_UNIX_PROCESSES ::kill(pid,SIGKILL); #endif #ifdef USING_WIN32 TerminateProcess((HANDLE)int(pid),0); #endif } kill_additional_procs(extra_kill); reset(); return true; } int Process::system(const STD_string& cmdline, STD_string& stdout_result, STD_string& stderr_result) { Process proc; if(!proc.start(cmdline)) return -1; int proc_return_value=-1; if(!proc.finished(proc_return_value, stdout_result, stderr_result, true)) return -1; return proc_return_value; } //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class ProcessTest : public UnitTest { public: ProcessTest() : UnitTest("process") {} private: bool check() const { Log odinlog(this,"check"); //#ifdef USING_UNIX_PROCESSES // stdout_result not implemented yet for win32 Process proc; // STD_string cmd("ping -c 1 localhost"); STD_string cmd("echo teststring"); #ifdef USING_WIN32 // cmd=STD_string(secure_getenv("WINDIR"))+SEPARATOR_STR+"system32"+SEPARATOR_STR+"ping.exe -n 1 localhost"; cmd=STD_string(secure_getenv("WINDIR"))+SEPARATOR_STR+"system32"+SEPARATOR_STR+"cmd.exe /C \"echo teststring\""; #endif if(!proc.start(cmd)) { ODINLOG(odinlog,errorLog) << "start failed, cmd=" << cmd << STD_endl; return false; } int proc_return_value; STD_string stdout_result; STD_string stderr_result; if(!proc.finished(proc_return_value, stdout_result, stderr_result, true)) { ODINLOG(odinlog,errorLog) << "finished failed" << STD_endl; return false; } if(proc_return_value) { ODINLOG(odinlog,errorLog) << "proc_return_value=" << proc_return_value << STD_endl; return false; } // if(stdout_result.find("127.0.0.1")==STD_string::npos) { if(stdout_result.find("teststring")==STD_string::npos) { ODINLOG(odinlog,errorLog) << "stdout_result=>" << stdout_result << "<"; return false; } //#endif return true; } }; void alloc_ProcessTest() {new ProcessTest();} // create test instance #endif odin-1.8.5/tjutils/tjstring.h0000644000175000017500000001467211322062342013117 00000000000000/*************************************************************************** tjstring.h - description ------------------- begin : Mon Mar 10 2003 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJSTRING_H #define TJSTRING_H #include //#include #include /** * @addtogroup tjutils * @{ */ #define _DEFAULT_DIGITS_ 5 #define _DEFAULT_LINEWIDTH_ 74 #ifdef USING_WIN32 #define SEPARATOR_STR "\\" #define SEPARATOR_CHAR '\\' #else #define SEPARATOR_STR "/" #define SEPARATOR_CHAR '/' #endif ////////////////////////////////////////////////////////////// // class for debugging string component class StringComp { public: static const char* get_compName(); }; ////////////////////////////////////////////////////////////// /** * Enum to flag replacement policy: * - allOccurences: All occurences will be replaced * - firstOccurence: Only the first occurence is replaced */ enum whichOccurences {allOccurences,firstOccurence}; /////////////////////////////////////////////////////////////////////////////// // String helper functions /** * * Returns a string where occurences of 'searchstring' are replaced by 'replacement' in s. * The 'mode' parameter determines whether only the first or all occurences should be replaced. */ STD_string replaceStr(const STD_string& s, const STD_string& searchstring, const STD_string& replacement, whichOccurences mode=allOccurences); /** * * returns a block of characters within s that is enclosed by 'blockbegin' and * 'blockend'; the delimiters itself are not returned; If hierachical * is true the nesting is considered, e.g. extract("(a(b)c)", "(", ")", true) * will return "a(b)c" and not "a(b" ; beginpos is the position * to start searching; * If 'blockbegin' is a zero-length string, extraction will start at the beginning of the string; * If 'blockend' is a zero-length string, extraction will stop at the end of the string; */ STD_string extract(const STD_string& s, const STD_string& blockbegin, const STD_string& blockend, bool hierachical=false, int beginpos=0); /** * * Returns s whereby a block of characters that is enclosed by 'blockbegin' and * 'blockend' is removed; the flags rmbegin/rmend specify whether the delimiters * itself should be removed. * If 'rmall' is true, the last possible end delimiter will be used, otherwise the first. * If 'hierachical' is true the nesting is considered, e.g. extract("(",")",true) applied * to "(a(b)c)" will return "a(b)c" and not "a(b" */ STD_string rmblock(const STD_string& s, const STD_string& blockbegin, const STD_string& blockend, bool rmbegin=true, bool rmend=true, bool rmall=true, bool hierachical=false); /** * * returns s, but with all lowercase characters transformed to uppercase */ STD_string toupperstr(const STD_string& s); /** * * returns s, but with all uppercase characters transformed to lowercase */ STD_string tolowerstr(const STD_string& s); /** * Enum to flag exponential printing of floating point numbers: * - autoExp: Automatic * - alwaysExp: Always use exponential format * - neverExp: Never use exponential format */ enum expFormat {autoExp, alwaysExp, neverExp}; /** * * returns a string that contains the formatted floating point number 'f' with precision 'digits' and exponential usage 'eformat' */ STD_string ftos (float f,unsigned int digits=_DEFAULT_DIGITS_, expFormat eformat=autoExp); /** * * returns a string that contains the formatted integer 'i'. * If 'maxabs' is non-zero, the string will be formatted to * have the same number of (possibly zero-padded) digits as 'maxabs'. */ STD_string itos (int i, unsigned int maxabs=0); /** * * returns a string that contains the address of pointer 'p' */ STD_string ptos (const void* p); /** * * Returns n times s, e.g. n_times("3",3) ---> "333" */ STD_string n_times(const STD_string& s, unsigned int n); /** * * returns a justification of s with the specified indention and linewidth */ STD_string justificate(const STD_string& s, unsigned int indention=0,bool ignore_firstline=false, unsigned int linewidth=_DEFAULT_LINEWIDTH_); /** * * Gives the position of the first non-speparator character in s. * Search starts at 'startpos'. * Blanks, tabs and newlines or 'custom_separator' if non-zero are considered as separators. */ int textbegin(const STD_string& s, int startpos=0, const char custom_separator=0); /** * * Gives the position of the first speparator character in s. * Search starts at 'startpos'. * Blanks, tabs and newlines or 'custom_separator' if non-zero are considered as separators. */ int sepbegin(const STD_string& s, int startpos=0, const char custom_separator=0); /** * * Remove all blanks, tabs and newlines from the string s */ STD_string shrink(const STD_string& s); /** * * searches for number of occurences of 'searchstring' in s, returns number of matches * otherwise 0 */ int noccur(const STD_string& s, const STD_string& searchstring); /** * * Replaces all '0d0a' sequences by '0a' in the string */ STD_string dos2unix(const STD_string& s); /** * * Loads 'str' from the ASCII-file 'filename'. * Returns 0 on success, -1 otherwise. */ int load (STD_string& str, const STD_string& filename); /** * * Writes 'str' to the ASCII-file 'filename', the 'mode' determines * whether data will be appended/overwritten if the file already exists. * Returns 0 on success, -1 otherwise. */ int write (const STD_string& str, const STD_string& filename, fopenMode mode=overwriteMode); /** @} */ #endif odin-1.8.5/tjutils/tjstate.cpp0000644000175000017500000000021211322062342013245 00000000000000#include "tjstate.h" #include "tjlog_code.h" const char* StateComponent::get_compName() {return "State";} LOGGROUNDWORK(StateComponent) odin-1.8.5/tjutils/tjutils.h0000644000175000017500000000253211322062342012741 00000000000000/*************************************************************************** tjutils.h - description ------------------- begin : Thu Dec 5 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJUTILS_H #define TJUTILS_H #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif // boilerplate includes for a clean C++ environment #include #include #include //////////////////////////////////////////////////////////////////////////// #endif odin-1.8.5/tjutils/tjarray.h0000644000175000017500000002312511322062342012720 00000000000000 /*************************************************************************** tjvector.h - description ------------------- begin : Thu Feb 22 2001 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJARRAY_H #define TJARRAY_H #include #include /** * @addtogroup tjutils * @{ */ /** * * This class is an extent vector for arrays, i.e. it is used to hold * dimension information of multidimensional arrays. * It is a vector of integer numbers which describe the extent of the * array in each direction/dimension. * It can also be used to index a certain element in the multidimensional array. */ class ndim : public STD_vector { public: /** * * Constructs an extent vector of size 'd'. */ ndim (unsigned long d=0); /** * * Copy constructor. */ ndim (const ndim& mm) : STD_vector(mm) {} /** * * Constructs an extent vector by parsing the string 's'. The string * must have the syntax (i,j,...) e.g. (3,2,5) to describe a 3-dimensional array. */ ndim (const STD_string& s); /** * * The number of dimensions, i.e. the length of the extent vector. */ unsigned long dim() const {return size();} /** * * Returns the extent vector as a formatted string, e.g. (3,2,5). */ operator STD_string () const; /** * Stream operator */ friend STD_ostream& operator << (STD_ostream& s,const ndim& nn) { return s << STD_string(nn);} /** * * Prefix -- operator: Strips of the first dimension/index. */ ndim& operator -- ( ); /** * * Postfix -- operator: Strips of the last dimension/index. */ ndim& operator -- (int); /** * * Add new dimension with extent 'e' either as last * or first dim, depending on 'first' */ ndim& add_dim ( unsigned long e, bool first=false ); /** * * Returns the total product of the vector. */ unsigned long total() const; /** * * Converts an index vector to the linear index in the array. */ unsigned long extent2index(const ndim& mm) const; /** * * Converts the linear index in the array to an index vector. */ ndim index2extent(unsigned long index) const; /** * * Returns true if nn and this are equal, otherwise false. */ bool operator == (const ndim& nn) const; /** * * Returns true if nn and this are unequal, otherwise false. */ bool operator != (const ndim& nn) const; /** * * Reduce to dimension dim, e.g. ( 3, 4, 7).reduce(2) -> ( 12, 7 ) */ ndim& reduce ( unsigned long dim ); /** * * Resize to essential dims, e.g. ( 1, 3, 1, 7).autosize() -> ( 3, 7 ) */ ndim& autosize (); }; ///////////////////////////////////////////////////////////////////////////// /** * * This class represents a multidimensional array. * It is implemented by deriving it from a one dimensional * vector which holds the data and adding a member of type 'ndim' * that contains the information about the extent in each dimension. */ template class tjarray : public V { public: /** * * default constructor */ tjarray (); /** * * constructs an array of dimensionality 'dim' and allocates memory for i,j,... values */ tjarray (unsigned long n1); tjarray (unsigned long n1, unsigned long n2); tjarray (unsigned long n1, unsigned long n2, unsigned long n3); tjarray (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4); tjarray (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5); /** * * copy constructor */ tjarray (const tjarray &ta); /** * * conversion from fvector to 1-dim array */ tjarray (const V& sv); /** * * constructs an array according to an extent 'nn' */ tjarray (const ndim &nn); /** * Copy assignment */ tjarray& operator = (const tjarray& ta); /** * * assigns 'value' to all elements */ tjarray& operator = (const T& value); /** * * Resize the array, that is create a 1-dim array with the given new size (virtual) */ V& resize(unsigned int newsize); /** * * Redimensionalize and resize the array according to the given extent vector. * If the total number of values does not change, the array is simply reshaped * but the values are preserved. */ tjarray& redim (const ndim &nn); /** * * Redimensionalize and resize the array according to the given extent vector * If the total number of values does not change, the array is simply reshaped * but the values are preserved. */ tjarray& redim (unsigned long n1); tjarray& redim (unsigned long n1, unsigned long n2); tjarray& redim (unsigned long n1, unsigned long n2, unsigned long n3); tjarray& redim (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4); tjarray& redim (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5); /** * * Remove all dimensions with a size of 1 from the extent vector */ tjarray& autosize () {extent.autosize(); return *this;} /** * * Get the extent vector, i.e. the information about the dimensions */ const ndim& get_extent () const; /** * * returns the element indexed by the extent vector ii */ T& operator () (const ndim& ii); /** * * returns the readonly element indexed by the extent vector ii */ const T& operator () (const ndim& ii) const; /** * * returns the element with index firstIndex,... */ T& operator () (unsigned long n1); T& operator () (unsigned long n1, unsigned long n2); T& operator () (unsigned long n1, unsigned long n2, unsigned long n3); T& operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4); T& operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5); /** * * returns the readonly element with index firstIndex,... */ const T& operator () (unsigned long n1) const; const T& operator () (unsigned long n1, unsigned long n2) const; const T& operator () (unsigned long n1, unsigned long n2, unsigned long n3) const; const T& operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) const; const T& operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) const; /** * * returns the dimensionality */ unsigned long dim() const; /** * * returns the extent in the i'th dimension */ unsigned long size(unsigned long i) const; /** * * returns the total number of elements */ unsigned long total() const; /** * * returns the total number of elements */ unsigned long length() const; /** * * returns the size of each element in bytes */ unsigned int elementsize() const; /** * * If the size of the given array 'ta' matches this object, all values from 'ta' will be assigned to this */ tjarray& assignValues(const tjarray &ta) ; /** * * The array will be resized to the size of ta and all values from 'ta' will be assigned to this */ tjarray& copy(const tjarray &ta) ; /** * * returns the elements of the array as a formatted string */ STD_string printbody() const; /** * * Converts a linear index to a tuple of indices in the array */ ndim create_index(unsigned long index) const; protected: STD_ostream& printbody2stream(STD_ostream& s) const; // required for JDX arrays private: static ndim create_extent(unsigned long n1); static ndim create_extent(unsigned long n1,unsigned long n2); static ndim create_extent(unsigned long n1,unsigned long n2,unsigned long n3); static ndim create_extent(unsigned long n1,unsigned long n2,unsigned long n3,unsigned long n4); static ndim create_extent(unsigned long n1,unsigned long n2,unsigned long n3,unsigned long n4,unsigned long n5); ndim extent; T element_dummy; }; ///////////////////////////////////////////////////////////////////////////// // Aliases: /** * An array of floating point numbers */ typedef tjarray farray; /** * An array of double precision floating point numbers */ typedef tjarray darray; /** * An array of integer numbers */ typedef tjarray iarray; /** * An array of complex numbers */ typedef tjarray carray; /** * An array of strings */ typedef tjarray sarray; ///////////////////////////////////////////////////////////////////////////// // Helper functions: /** * * Prints the 2-dimensional array 'table' (rows x cols) with the column widths * adjusted to the maximum width (string length) in each column. */ STD_string print_table(const sarray& table); /** * * Parses the string 'str' as a table and returns result as a 2-dim array (rows x cols). */ sarray parse_table(const STD_string& str); /** @} */ #endif odin-1.8.5/tjutils/tjlist.cpp0000644000175000017500000000372111322062342013110 00000000000000#include "tjlist.h" #include "tjlist_code.h" #include "tjtest.h" #include "tjlog_code.h" const char* ListComponent::get_compName() {return "List";} LOGGROUNDWORK(ListComponent) #ifndef NO_UNIT_TEST class ListTest : public UnitTest { public: ListTest() : UnitTest(ListComponent::get_compName()) {} private: class StrItem : public ListItem, public STD_string {}; typedef List StrList; bool check() const { Log odinlog(this,"check"); StrItem* item0=new StrItem; item0->STD_string::operator = ("item0"); StrItem* item1=new StrItem; item1->STD_string::operator = ("item1"); StrItem* item2=new StrItem; item2->STD_string::operator = ("item2"); StrList* slist=new StrList; slist->append(*item0); slist->append(*item1); slist->append(*item2); if(slist->size()!=3) { ODINLOG(odinlog,errorLog) << "size()!=3" << STD_endl; return false; } int index=0; for(StrList::constiter it=slist->get_const_begin(); it!=slist->get_const_end(); ++it) { STD_string expected="item"+itos(index); if((**it)!=expected) { ODINLOG(odinlog,errorLog) << "expected=" << expected << STD_endl; return false; } index++; } delete item0; if(slist->size()!=2) { ODINLOG(odinlog,errorLog) << "size()!=2" << STD_endl; return false; } delete item1; if(slist->size()!=1) { ODINLOG(odinlog,errorLog) << "size()!=1" << STD_endl; return false; } if(item2->numof_references()!=1) { ODINLOG(odinlog,errorLog) << "references(pre)=" << item2->numof_references() << STD_endl; return false; } delete slist; if(item2->numof_references()!=0) { ODINLOG(odinlog,errorLog) << "references(post)=" << item2->numof_references() << STD_endl; return false; } delete item2; return true; } }; void alloc_ListTest() {new ListTest();} // create test instance #endif odin-1.8.5/tjutils/tjstream.cpp0000644000175000017500000000146311322062342013431 00000000000000#include "tjstream.h" #include "tjstring.h" #ifdef STREAM_REPLACEMENT void tjstd_ostream::buff_float(float f) {append2buff(ftos(f));} void tjstd_ostream::buff_int(int i) {append2buff(itos(i));} //////////////////////////////////////////////////////////////// tjstd_ofstream::tjstd_ofstream(const char* filename) : file_ptr(0) { #ifndef NO_FILEHANDLING if(STD_string(filename)!="") { FILE* fp=FOPEN(filename, modestring(overwriteMode)); if(fp!=NULL) { file_ptr=(void*)fp; } } #endif } void tjstd_ofstream::close() { #ifndef NO_FILEHANDLING if(file_ptr) fclose((FILE*)file_ptr); file_ptr=0; #endif } void tjstd_ofstream::append2buff(const STD_string& str) { #ifndef NO_FILEHANDLING if(file_ptr) fwrite(str.c_str(), sizeof(char), str.length(), (FILE*)file_ptr); #endif } #endif odin-1.8.5/tjutils/tjstatic.cpp0000644000175000017500000000117511322062342013425 00000000000000#include "tjstatic.h" void Static::append_to_destructor_list(Static* sp) { if(!destructor_list) { destructor_list=new STD_list; } destructor_list->push_front(sp); } void Static::destroy_all() { if(destructor_list) { for(STD_list::iterator it=destructor_list->begin(); it!=destructor_list->end(); ++it) { // STD_cout << "Static::destroy_all(): destructing " << typeid(*(*it)).name() << "<" << STD_endl; delete *it; // STD_cout << "Static::destroy_all(): done" << STD_endl; } delete destructor_list; } destructor_list=0; } STD_list* Static::destructor_list=0; odin-1.8.5/tjutils/tjfeedback.h0000644000175000017500000000664311322062342013334 00000000000000/*************************************************************************** tjfeedback.h - description ------------------- begin : Fri Jun 6 2003 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJFEEDBACK_H #define TJFEEDBACK_H #include #include /** * @addtogroup tjutils * @{ */ /** * * Base class for all display drivers of a progress, e.g. console, widget, ... */ class ProgressDisplayDriver { public: virtual ~ProgressDisplayDriver() {} /** * Initializes the driver to display to expect 'nsteps' calls to 'increase()'. * The message 'txt' will be displayed prior to the progress report. */ virtual void init(unsigned int nsteps, const char* txt) = 0; /** * Increments progress display. * The message 'subj', if non-null, will be displayed. */ virtual void increase(const char* subj) = 0; /** * Refreshes display without increasing progress. * Returns true if cancel is requested by the driver. */ virtual bool refresh() = 0; }; ////////////////////////////////////////////////////// /** * * Class to preset the progress of an operation to the user. * The implementation is thread-safe. */ class ProgressMeter { public: /** * Creates progress meter using display driver 'disp' which should * exist for the whole life time of the progress meter. */ ProgressMeter(ProgressDisplayDriver& disp) : display(&disp) {} /** * Initialize new task with 'total_steps' increments. * The message 'txt' will be displayed prior to the progress report. */ ProgressMeter& new_task(unsigned int total_steps, const char* txt = 0); /** * Increments progress display. * The message 'subj', if non-null, will be displayed. */ bool increase_counter(const char* subj = 0); /** * Refreshes display without increasing progress. * Returns true if cancel is requested by the driver. */ bool refresh_display(); private: // disable copy construction and copying ProgressMeter(const ProgressMeter&) {} ProgressMeter& operator = (const ProgressMeter&) {return *this;} ProgressDisplayDriver* display; Mutex mutex; }; ////////////////////////////////////////////////////// #ifndef NO_CMDLINE class ProgressDisplayConsole : public virtual ProgressDisplayDriver { public: ProgressDisplayConsole() : counter(0), nsteps_cache(0), done(false) {} // Implementing virtual functions of ProgressDisplayDriver void init(unsigned int nsteps, const char* txt); void increase(const char*); bool refresh() {return false;} private: unsigned int counter, nsteps_cache, old_perc; bool done; }; #endif /** @} */ #endif odin-1.8.5/tjutils/tjnumeric.cpp0000644000175000017500000001205511735132611013604 00000000000000#include "tjnumeric.h" #include "tjvector.h" #include "tjtest.h" #include "tjlog_code.h" class NumericsComp { public: static const char* get_compName() {return "numerics";} }; LOGGROUNDWORK(NumericsComp) /////////////////////////////////////////////////////////////////// // copy & pasted from the GSL library int solve_cubic (double a, double b, double c, double *x0, double *x1, double *x2) { double q = (a * a - 3 * b); double r = (2 * a * a * a - 9 * a * b + 27 * c); double Q = q / 9; double R = r / 54; double Q3 = Q * Q * Q; double R2 = R * R; double CR2 = 729 * r * r; double CQ3 = 2916 * q * q * q; if (R == 0 && Q == 0) { *x0 = - a / 3 ; *x1 = - a / 3 ; *x2 = - a / 3 ; return 3 ; } else if (CR2 == CQ3) { /* this test is actually R2 == Q3, written in a form suitable for exact computation with integers */ /* Due to finite precision some double roots may be missed, and considered to be a pair of complex roots z = x +/- epsilon i close to the real axis. */ double sqrtQ = sqrt (Q); if (R > 0) { *x0 = -2 * sqrtQ - a / 3; *x1 = sqrtQ - a / 3; *x2 = sqrtQ - a / 3; } else { *x0 = - sqrtQ - a / 3; *x1 = - sqrtQ - a / 3; *x2 = 2 * sqrtQ - a / 3; } return 3 ; } else if (CR2 < CQ3) /* equivalent to R2 < Q3 */ { double sqrtQ = sqrt (Q); double sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; double theta = acos (R / sqrtQ3); double norm = -2 * sqrtQ; *x0 = norm * cos (theta / 3) - a / 3; *x1 = norm * cos ((theta + 2.0 * PII) / 3) - a / 3; *x2 = norm * cos ((theta - 2.0 * PII) / 3) - a / 3; /* Sort *x0, *x1, *x2 into increasing order */ if (*x0 > *x1) STD_swap(*x0, *x1) ; if (*x1 > *x2) { STD_swap(*x1, *x2) ; if (*x0 > *x1) STD_swap(*x0, *x1) ; } return 3; } else { double sgnR = (R >= 0 ? 1 : -1); double A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0); double B = Q / A ; *x0 = A + B - a / 3; return 1; } } //////////////////////////////////////////////////////////////////////////////////////// #ifdef HAVE_LIBGSL #include #include #endif RandomDist::RandomDist() { #ifdef HAVE_LIBGSL rng = (gsl_rng*)gsl_rng_alloc(gsl_rng_tt800); // rng = (gsl_rng*)gsl_rng_alloc(gsl_rng_default); gsl_rng_set ((gsl_rng*)rng, time(NULL)); #endif } RandomDist::~RandomDist() { #ifdef HAVE_LIBGSL gsl_rng_free((gsl_rng*)rng); #endif } double RandomDist::gaussian(double stdev) const { #ifdef HAVE_LIBGSL return gsl_ran_gaussian ((gsl_rng*)rng, stdev); #else STD_cerr << "ERROR: RandomDist::gaussian: libgsl missing" << STD_endl; return 0.0; #endif } double RandomDist::uniform() const { #ifdef HAVE_LIBGSL return gsl_rng_uniform ((gsl_rng*)rng); #else STD_cerr << "ERROR: RandomDist::uniform: libgsl missing" << STD_endl; return 0.0; #endif } //////////////////////////////////////////////////////////////////////////////////////// fvector bruteforce_minimize1d(const MinimizationFunction& f, float low, float upp) { Log odinlog("","bruteforce_minimize1d"); if(f.numof_fitpars()!=1) { ODINLOG(odinlog,errorLog) << "rank of minimization function != 1" << STD_endl; return 0.0; } int nvals=10; int niter=10; fvector xvals(nvals); fvector yvals(nvals); fvector funcarg(1); for(int iter=0; iter odinlog(this,"check"); MinimizationTestFunction mtf; float min=bruteforce_minimize1d(mtf, -12.45, 9.77)[0]; float expected=2.0; if( fabs(expected-min)>1.0e-3 ) { ODINLOG(odinlog,errorLog) << "minimize failed, got " << min << " but expected " << expected << STD_endl; return false; } return true; } }; void alloc_NumericsTest() {new NumericsTest();} // create test instance #endif odin-1.8.5/tjutils/tjcstd.cpp0000644000175000017500000000722611322062342013076 00000000000000#include "tjcstd.h" #include "tjutils.h" #include "tjstring.h" #ifdef USING_WIN32 #include #include #include #endif #ifndef HAVE_CTYPE_H int isdigit (int c) { if(c>='0' && c<='9') return true; else return false; } int isspace (int c) { if(c==' ' || c=='\n' || c=='\r' || c=='\t') return true; else return false; } int islower (int c) { return (c>='a' && c<='z'); } int tolower (int c) { if(isupper(c)) c+=32; return c; } int isupper (int c) { return (c>='A' && c<='Z'); } int toupper (int c) { if(islower(c)) c-=32; return c; } #endif #ifndef HAVE_J1 double j1(double x) { double xa=fabs(x); double result=0.0; static double a1[] = { 0.1171875, -0.1441955566406250, 0.6765925884246826, -6.883914268109947, 1.215978918765359e2, -3.302272294480852e3, 1.276412726461746e5, -6.656367718817688e6, 4.502786003050393e8, -3.833857520742790e10, 4.011838599133198e12, -5.060568503314727e14, 7.572616461117958e16, -1.326257285320556e19}; static double b1[] = { -0.1025390625, 0.2775764465332031, -1.993531733751297, 2.724882731126854e1, -6.038440767050702e2, 1.971837591223663e4, -8.902978767070678e5, 5.310411010968522e7, -4.043620325107754e9, 3.827011346598605e11, -4.406481417852278e13, 6.065091351222699e15, -9.833883876590679e17, 1.855045211579828e20}; if(xa==0.0) return result; double x2=xa*xa; if(xa<=12.0) { // simple series expansion for small numbers result=1.0; double r=1.0; for(int i=1;i<=30;i++) { r *= -0.25*x2/(i*(i+1)); result += r; if (fabs(r) < fabs(result)*1e-15) break; } result *= 0.5*xa; } else { int n; if (xa >= 50.0) n = 8; else if (xa >= 35.0) n = 10; else n = 12; double t2 = xa-0.75*PII; double p1 = 1.0; double q1 = 0.375/xa; for (int i=0; i 1.0 / GSL_SQRT_DBL_EPSILON) { return log (x) + GSL_M_LN2; } else if (x > 2) { return log (2 * x - 1 / (sqrt (x * x - 1) + x)); } else if (x > 1) { double t = x - 1; return gsl_log1p (t + sqrt (2 * t + t * t)); } else if (x == 1) { return 0; } else { return 0; // GSL_NAN; } } #endif #ifdef VXWORKS double exp4vxworks(double x) { if(x<-50.0) return 0.0; // otherwise the C-library on VxWorks throws an exception (no comment ;-) #undef exp else return exp(x); #define exp exp4vxworks } #endif //////////////////////////////////////////////////////////////////// #ifndef HAVE_DL void *dlopen (const char *filename, int flag) { #ifdef USING_WIN32 HINSTANCE inst=LoadLibraryA(filename); return (void*)inst; #else return 0; #endif } const char *dlerror(void) { return lasterr(); } void *dlsym(void *handle, char *symbol) { #ifdef USING_WIN32 FARPROC fp=GetProcAddress((HMODULE)handle,symbol); return (void*)fp; #else return 0; #endif } int dlclose (void *handle) { #ifdef USING_WIN32 BOOL b=FreeLibrary((HMODULE)handle); return (int)!b; #else return 0; #endif } #endif odin-1.8.5/tjutils/tjindex.h0000644000175000017500000000751711322062342012720 00000000000000/*************************************************************************** tjindex.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJINDEX_H #define TJINDEX_H #include #include #include #include /** * @addtogroup tjutils * @{ */ class Index { public: static const char* get_compName(); }; ////////////////////////////////////////////////////////// // mapping between UniquIndex types and typenames struct UniqueIndexMap : public STD_map >, public Labeled { unsigned int get_index(STD_list::iterator& index, const STD_string& type, unsigned int max_instances); void remove_index(const STD_list::iterator& index, const STD_string& type); private: bool contiguous; // cache whether list of indices is contiguous for fast assignment of indices unsigned int assign_index(STD_list::iterator& index, const STD_string& type); // Get the next lowest index which is available }; ////////////////////////////////////////////////////////// // keeps track of all index lists class UniqueIndexBase : public StaticHandler { public: // for StaticHandler static void init_static() {indices_map.init("indices_map");} static void destroy_static() {indices_map.destroy();} protected: UniqueIndexBase() {} // Use only as base class static SingletonHandler indices_map; // global lists of indices }; ////////////////////////////////////////////////////////// /** * This template class provides a unique index, i.e. an unique * unsigned integer number for all instances of the (derived) class. * A new index for the object is created whenever a call to 'get_index()' * is issued the first time. The assigned index is removed from the list * of assigned indices if the object is destroyed. * Please note that the index of temporary objects is deleted from * the list of indices, even it is assigned to another object. * The class T must have two static member functions, 'get_typename()' * and 'get_max_instances()' to return a unique label and the * maximum number of instances per class, respectively. */ template class UniqueIndex : public UniqueIndexBase { public: UniqueIndex() {init();} UniqueIndex(const UniqueIndex&) {init();} UniqueIndex& operator = (const UniqueIndex&) {erase(); init(); return *this;} ~UniqueIndex() {erase();} /** * Returns a unique index for this object. */ unsigned int get_index() const { return indices_map->get_index(index, T::get_typename(), T::get_max_instances()); } private: void init() { // Start with unassigned index (pointing to end()) index=indices_map->operator[](T::get_typename()).end(); } void erase() { // Remove index indices_map->remove_index(index, T::get_typename()); } mutable STD_list::iterator index; }; /** @} */ #endif odin-1.8.5/tjutils/tjnumeric.h0000644000175000017500000000517211735132611013253 00000000000000/*************************************************************************** tjnumeric.h - description ------------------- begin : Mon May 5 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJNUMERIC_H #define TJNUMERIC_H #include #include /** * @addtogroup tjutils * @{ */ /** * * Solve cubic equation x^3 + a x^2 + b x + c = 0 , copied from the GSL-lib */ int solve_cubic (double a, double b, double c, double *x0, double *x1, double *x2); //////////////////////////////////////////////////////////////////////////////////////// /** * Calculate random number distributions, the generator is seeded once upon construction * using the system time. */ class RandomDist { public: RandomDist(); ~RandomDist(); /** * Calculate Gaussian distribution with given standard deviation, uses GSL random number generator */ double gaussian(double stdev) const; /** * Calculate uniformly distributed random number in range [0,1), uses GSL random number generator */ double uniform() const; private: void* rng; }; //////////////////////////////////////////////////////////////////////////////////////// /** * Function which is used for optimization */ class MinimizationFunction { public: /** * Returns the number of independent fitting parameters */ virtual unsigned int numof_fitpars() const = 0; /** * Multi-dimensional function to be minimized */ virtual float evaluate(const fvector&) const = 0; }; //////////////////////////////////////////////////////////////////////////////////////// /** * one-dimensional brute-force minimizer in given interval [low,upp]. * Returns coordinates of minimum. */ fvector bruteforce_minimize1d(const MinimizationFunction& f, float low, float upp); /** @} */ #endif odin-1.8.5/tjutils/tjcomplex.cpp0000644000175000017500000000426411322062342013607 00000000000000#include "tjcomplex.h" #include "tjtest.h" #include "tjlog.h" STD_string ctos (const STD_complex& z) { STD_string s; s=ftos(z.real()); if(z.imag()>=0.0) s+="+"; s+=ftos(z.imag())+"i"; return s; } STD_complex stoc(const STD_string& s) { char value[250]; unsigned int index=0,i=0; STD_string tt(s); tt=replaceStr(tt,"e-","m"); tt=replaceStr(tt,"E-","m"); tt=replaceStr(tt,"e+","p"); tt=replaceStr(tt,"E+","p"); tt=replaceStr(tt,"e","p"); tt=replaceStr(tt,"E","p"); while(index<249 && tt[index] != '+' && tt[index] != '-' && tt[index] != '.' && (tt[index] < '0' || tt[index] > '9') ) index++; if (tt[index] == '+' || tt[index] == '-') { value[0]=tt[index]; i=1;index++; } else i=0; while(tt[index] != '+' && tt[index] != '-' && index<249) { value[i]=tt[index]; index++; i++; } value[i]='\0'; STD_string valstr_re(value); valstr_re=replaceStr(valstr_re,"m","e-"); valstr_re=replaceStr(valstr_re,"p","e+"); float val_re=atof(valstr_re.c_str()); i=0; while(tt[index] != 'i' && tt[index] != 'I' && index<249) { value[i]=tt[index]; index++; i++; } value[i]='\0'; STD_string valstr_im(value); valstr_im=replaceStr(valstr_im,"m","e-"); valstr_im=replaceStr(valstr_im,"p","e+"); float val_im=atof(valstr_im.c_str()); i=0; return STD_complex(val_re,val_im); } #ifndef NO_UNIT_TEST class ComplexTest : public UnitTest { public: ComplexTest() : UnitTest("complex") {} private: bool check() const { Log odinlog(this,"check"); // making sure complex type contains only re/im member int expected_size=2*sizeof(float); int complex_size=sizeof(STD_complex); if(expected_size!=complex_size) { ODINLOG(odinlog,errorLog) << "complex type has NOT twice the size of float" << STD_endl; return false; } // check memory alignment float re=1.2; float im=3.4; STD_complex c(re,im); float* f=(float*)&c; if(f[0]!=re || f[1]!=im) { ODINLOG(odinlog,errorLog) << "wrong alignment of complex type" << STD_endl; return false; } return true; } }; void alloc_ComplexTest() {new ComplexTest();} // create test instance #endif odin-1.8.5/tjutils/tjprofiler.cpp0000644000175000017500000000470511322062342013762 00000000000000#include "tjprofiler.h" #include "tjstring.h" #include "tjtools.h" #include "tjarray.h" #include "tjhandler_code.h" #include "tjlog_code.h" #ifdef HAVE_UNISTD_H #include #endif //#ifdef ODIN_DEBUG #define ENABLE_PROFILER //#endif const char* Profiler::get_compName() {return "Prof";} LOGGROUNDWORK(Profiler) Profiler::Profiler(const STD_string& func_name) : func_label(func_name) { #ifdef ENABLE_PROFILER starttime=current_time_s(); #endif } Profiler::~Profiler() { #ifdef ENABLE_PROFILER func_map->operator [] (func_label).time_spent+=(current_time_s()-starttime); #endif } void Profiler::reset() { #ifdef ENABLE_PROFILER if(func_map) func_map->clear(); #endif } void Profiler::dump_final_result() { #ifdef ENABLE_PROFILER Log odinlog("Profiler","dump_final_result"); if(!func_map) return; if(!func_map->size()) return; unsigned int maxlen=0; STD_map::const_iterator it; for(it=func_map->begin(); it!=func_map->end(); ++it) maxlen=STD_max(maxlen,(unsigned int)it->first.length()); for(it=func_map->begin(); it!=func_map->end(); ++it) { ODINLOG(odinlog,infoLog) << it->first << ": " << STD_string(maxlen-it->first.length(),' ') << it->second.time_spent << STD_endl; } reset(); #endif } STD_string Profiler::get_memory_usage() { STD_string result; #ifdef ENABLE_PROFILER #ifndef NO_FILEHANDLING FILE* file_ptr=FOPEN("/proc/self/statm",modestring(readMode)); if(file_ptr==NULL) { return "Profiler::get_memory_usage: Memory usage not available"; } char* cstr = new char [ODIN_MAXCHAR+1]; int i=fread(cstr,1,ODIN_MAXCHAR,file_ptr); if(i<=ODIN_MAXCHAR) cstr[i]='\0'; fclose(file_ptr); svector toks=tokens(cstr); delete[] cstr; if(toks.size()!=7) return result; float psize_mb=1.0; #ifdef HAVE_UNISTD_H // MinGW does not have getpagesize #ifndef USING_WIN32 psize_mb=float(getpagesize())/1048576.0; #endif #endif float total=atof(toks[0].c_str())*psize_mb; float shared=atof(toks[2].c_str())*psize_mb; float ram=total-shared; result+="total="+ftos(total)+"MB "; result+="shared="+ftos(shared)+"MB "; result+="ram="+ftos(ram)+"MB"; #endif #endif return result; } void Profiler::init_static() {func_map.init("func_map");} void Profiler::destroy_static() {func_map.destroy();} template class SingletonHandler; SingletonHandler Profiler::func_map; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/tjutils/tjlog.h0000644000175000017500000002070111322062342012360 00000000000000/*************************************************************************** tjlog.h - description ------------------- begin : Fri Aug 2 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJLOG_H #define TJLOG_H #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #include #include #include #include #include #include #include /** * @addtogroup tjutils * @{ */ #define MAX_COMPONENT_SIZE 10 #define MAX_LOG_STRINGSIZE 25 /** * This enum is used to assign a priority to the log messages * If a given logging level is selected by the user (via GUI or command * line argument), all messages with an equal or lesser priority are * shown. */ enum logPriority { noLog=0, errorLog, warningLog, infoLog, significantDebug, normalDebug, verboseDebug, numof_log_priorities, ignoreArgument}; static const char* logPriorityLabel[]={"noLog", "errorLog", "warningLog", "infoLog", "significantDebug", "normalDebug", "verboseDebug"}; ////////////////////////////////////////////////////////////////////////////////////// /** * Message token which is passed to the trace function */ struct LogMessage { /** * The priority level of the message */ logPriority level; /** * Component, i.e. subsystem, from which message originates */ STD_string comp; /** * Object (label) from which message originates */ STD_string obj; /** * Function (name) from which message originates */ STD_string func; /** * Message text */ STD_string txt; /** * Produce single string from message with at most 'maxwidth' characters * including the component label if 'include_comp' is 'true'. * If 'maxwidth' is zero, the length is unlimited. */ STD_string str(unsigned int maxwidth=0, bool include_comp=true) const; }; ////////////////////////////////////////////////////////////////////////////////////// /** * Trace function signature */ typedef void (*tracefunction)(const LogMessage& msg); /** * Default trace function */ void default_tracefunction(const LogMessage& msg); ////////////////////////////////////////////////////////////////////////////////////// // function pointer to get/set log levels in global map of logLevels typedef logPriority (*log_component_fptr) (logPriority); ////////////////////////////////////////////////////////////////////////////////////// /** * Base class for all Log-component types which manages global settings */ class LogBase : public virtual StaticHandler { public: LogBase() {} // for LogBaseoc LogBase(const char* component, const char* object, const Labeled* labeledObject, const char* function) : compLabel(component), objLabel(object), namedObj(labeledObject), funcName(function) {} /** * Set the log output level of component 'compname' to 'level' */ static void set_log_level(const char* compname, logPriority level); /** * Set uniform log output level for all components */ static void set_uniform_log_level(logPriority level); #ifndef NO_CMDLINE /** * Set log levels from command line */ static bool set_log_levels(int argc, char *argv[], bool trigger_error=true); #endif /** * Get command line usage for setting log levels */ static STD_string get_usage(); // Functions to used by Log-component types static bool register_component(const char*,log_component_fptr); static void unregister_component(const char*); /** * Serialize log-level settings to string */ static const char* get_levels(); /** * Set log levels from string */ static void set_levels(const char* str); /** * Set trace function */ static void set_log_output_function(tracefunction func); // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); protected: friend class LogOneLine; // Cache only plain pointers for efficiency const char* compLabel; const char* objLabel; // Cache either the string const Labeled* namedObj; // or the object to retrieve the label from const char* funcName; void flush_oneline(const STD_string& txt, logPriority level); #ifndef NO_CMDLINE static void parse_log_cmdline_options(int argc, char *argv[], const char* opt, logPriority base); #endif // global (singleton) data struct Global : public Labeled { Global() : tracefunc(default_tracefunction), uniform_init_level(ignoreArgument) {} tracefunction tracefunc; STD_map components; STD_map init_level; logPriority uniform_init_level; }; static SingletonHandler global; // Thread-safe singleton for global data private: friend class DebugDialog; }; ////////////////////////////////////////////////////////////////////////////////////// /** * Logging class to store logging information of the current scope (object, function, ...). * The template parameter specifies the component in which * logging is placed, e.g. Log for tracing sequence code. */ template class Log : public virtual LogBase { public: /** * Constructs a logging stream for object 'objectLabel' and function 'functionName'. * Both strings will precede the actual message in the log. The third argument specifies * a uniform logging priority for the constructor and destructor. * This constructor will automatically generate a START tag in the log for the function * it is used in. */ Log(const char* objectLabel, const char* functionName, logPriority level=verboseDebug); /** * Constructs a logging stream for labeled object 'labeledObject' and function 'functionName'. * Both the label and the function name will precede the actual message in the log. The third argument specifies * a uniform logging priority for the constructor and destructor. * This constructor will automatically generate a START tag in the log for the function * it is used in. */ Log(const Labeled* labeledObject, const char* functionName, logPriority level=verboseDebug); /** * This destructor will automatically generate an END tag in the log for the function * its object is used in. */ ~Log(); static logPriority set_log_level(logPriority level); // to be called via log_component_fptr function pointer inline static logPriority get_log_level() {return logLevel;} // to be used by LogOneLine private: logPriority constrLevel; void register_comp(); static logPriority logLevel; static bool registered; // call register_component only in 1st constructor }; ////////////////////////////////////////////////////////////////////////////////////// // Temporary object to log one line via ostringstream // This ingenious technique was presented by Petru Marginean in Dr.Dobb's under the title 'Logging in C++' struct LogOneLine { public: LogOneLine(LogBase& logobj, logPriority level) : log(logobj), lev(level) {} ~LogOneLine() {log.flush_oneline(oss.str(),lev);} STD_ostream& get_stream() {return oss;} private: LogBase& log; logPriority lev; STD_ostringstream oss; }; ////////////////////////////////////////////////////////////////////////////////////// // Min level which is included in release compilation #define RELEASE_LOG_LEVEL infoLog #ifdef ODIN_DEBUG #define ODINLOG(logobj,level) \ if ((level) > (logobj).get_log_level()) ; \ else LogOneLine(logobj,level).get_stream() #else #define ODINLOG(logobj,level) \ if ((level) > RELEASE_LOG_LEVEL) ; \ else if ((level) > (logobj).get_log_level()) ; \ else LogOneLine(logobj,level).get_stream() #endif /** @} */ #endif odin-1.8.5/tjutils/tjstd.h0000644000175000017500000005603611322062342012403 00000000000000/*************************************************************************** tjstd.h - description ------------------- begin : Thu Dec 5 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJSTD_H #define TJSTD_H ///////////////////////////////////////////////////////////////// #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #include // memory management #include // C standard lib ///////////////////////////////////////////////////////////////// // Macros for stream replacement // Must be placed here to avoid circular dependencies #ifdef STREAM_REPLACEMENT #define STD_ostream tjstd_ostream #define STD_istream tjstd_istream #define STD_ostringstream tjstd_ostringstream #define STD_ofstream tjstd_ofstream #define STD_ifstream tjstd_ifstream #define STD_cout tjstd_cout #define STD_cerr tjstd_cerr #define STD_cin tjstd_cin #define STD_endl tjstd_endl #define STD_flush tjstd_flush #define STD_setprecision tjstd_setprecision #define STD_getline tjstd_getline #define STD_make_pair tjstd_make_pair class tjstd_ostream; // forward declaration class tjstd_istream; // forward declaration class tjstd_string; // forward declaration #else #define STD_ostream std::ostream #define STD_istream std::istream #define STD_ostringstream std::ostringstream #define STD_ofstream std::ofstream #define STD_ifstream std::ifstream #define STD_cout std::cout #define STD_cerr std::cerr #define STD_cin std::cin #define STD_endl std::endl #define STD_flush std::flush #define STD_setprecision std::setprecision #define STD_getline std::getline #define STD_make_pair std::make_pair #include #include #include #endif // STREAM_REPLACEMENT ///////////////////////////////////////////////////////////////// #ifdef STL_REPLACEMENT #define STD_list tjstd_list #define STD_find tjstd_find #define STD_pair tjstd_pair #define STD_map tjstd_map #define STD_vector tjstd_vector #define STD_complex tjstd_complex #define STD_back_inserter tjstd_back_inserter #define STD_unique_copy tjstd_unique_copy #define STD_swap tjstd_swap #define STD_max tjstd_max #define STD_min tjstd_min // complex math funcs #define STD_abs tjstd_abs #define STD_arg tjstd_arg #define STD_log tjstd_log #define STD_exp tjstd_exp #define STD_conj tjstd_conj #else // STL_REPLACEMENT #include #include #include #include #include #include #include #include // For Visual Studio 2005 #define STD_list std::list #define STD_find std::find #define STD_pair std::pair #define STD_map std::map #define STD_vector std::vector #define STD_complex std::complex #define STD_back_inserter std::back_inserter #define STD_unique_copy std::unique_copy #define STD_swap std::swap #define STD_max std::max #define STD_min std::min // complex math funcs #define STD_abs std::abs #define STD_arg std::arg #define STD_log std::log #define STD_exp std::exp #define STD_conj std::conj #endif // STL_REPLACEMENT /////////////////////////////////////////////// #ifdef STRING_REPLACEMENT #define STD_string tjstd_string #else // STRING_REPLACEMENT #include #define STD_string std::string #endif // STRING_REPLACEMENT /** * @addtogroup tjutils * @{ */ ///////////////////// STL replacement follows ///////////////////////////// #ifdef STL_REPLACEMENT template class tjnode { public: tjnode() : value(0), next(0), prev(0) {} tjnode (const I& newval) : value(new I(newval)), next(0), prev(0) {} ~tjnode() {if(value) delete value;} I* value; tjnode* next; tjnode* prev; private: // make these member functions private to prevent their usage tjnode(const tjnode&) {} tjnode& operator = (const tjnode&) {return *this;} }; ///////////////////////// template class tjiterator { public: tjiterator(tjnode* itemptr=0) : current(itemptr) {} operator I* () { if(current) return (current->value); else return 0; } operator const I* () const { if(current) return (current->value); else return 0; } I& operator * () {return *(operator I* ());} const I& operator * () const {return *(operator const I* ());} I* operator -> () {return operator I* ();} const I* operator -> () const {return operator const I* ();} tjiterator operator ++ () { if(current && current->next) current=current->next; return *this; } tjiterator operator ++ (int) { // postfix tjnode* old=current; if(current && current->next) current=current->next; return tjiterator(old); } tjiterator operator -- () { if(current && current->prev) current=current->prev; return *this; } tjiterator operator -- (int) { // postfix tjnode* old=current; if(current && current->prev) current=current->prev; return tjiterator(old); } bool operator == (const tjiterator& i2) const { return (current==i2.current); } bool operator != (const tjiterator& i2) const { return (current!=i2.current); } tjnode* current; }; //////////////////////////// template class tjstd_list { public: typedef tjiterator iterator; typedef tjiterator const_iterator; tjstd_list() : first(&end_node), size_cache(0) {} tjstd_list(unsigned int n, const I& value) : first(&end_node), size_cache(0) { for(unsigned int i=0; i begin() {return tjiterator(first);} tjiterator end() {return tjiterator(&end_node);} tjiterator begin() const {return tjiterator(first);} tjiterator end() const {return tjiterator(&end_node);} tjiterator push_back(const I& newval) { check("push_back(pre)"); tjnode* newnode=new tjnode(newval); push_back_node(newnode); check("push_back(post)"); return tjiterator(newnode); } tjiterator push_front(const I& newval) { check("push_front(pre)"); tjnode* newnode=new tjnode(newval); push_front_node(newnode); check("push_front(post)"); return tjiterator(newnode); } tjiterator insert(const tjiterator& pos, const I& newval) { check("insert(pre)"); tjnode* newnode=new tjnode(newval); insert_node(pos.current, newnode); return tjiterator(newnode); } void remove(const I& remval) { check("remove(pre)"); I value2Bremoved(remval); //create copy in the case it is an element of the list itself iterator it=begin(); while(it!=end()) { if((*it)==value2Bremoved) { tjnode* toberemoved=it.current; ++it; remove_node(toberemoved); delete toberemoved; } else ++it; } check("remove(post)"); } tjiterator erase(const tjiterator& b,const tjiterator& e) { check("erase2(pre)"); iterator it=b; while(it!=e) { tjnode* toberemoved=it.current; it.current=toberemoved->next; // iterate to next node remove_node(toberemoved); delete toberemoved; } check("erase2(post)"); return e; } tjiterator erase(const tjiterator& p) { check("erase1(pre)"); tjiterator result=p; result++; tjnode* toberemoved=p.current; remove_node(toberemoved); delete toberemoved; check("erase1(post)"); return result; } void clear() {erase(begin(),end());} unsigned int size() const {return size_cache;} bool empty() const {return !size_cache;} void sort() { check("sort(pre)"); // make list_unsrt a shallow copy of this tjstd_list list_unsrt; if(first!=(&end_node)) { list_unsrt.first=first; list_unsrt.end_node.prev=end_node.prev; list_unsrt.end_node.prev->next=&(list_unsrt.end_node); list_unsrt.size_cache=size_cache; } // reset me first=&end_node; end_node.prev=0; size_cache=0; while(list_unsrt.begin()!=list_unsrt.end()) { tjnode* node2sort=list_unsrt.first; list_unsrt.remove_node(node2sort); iterator it=begin(); while(it!=end() && (*it)<(*(node2sort->value))) ++it; insert_node(it.current,node2sort); } list_unsrt.check("sort::list_unsrt"); check("sort(post)"); } void unique() { check("unique(pre)"); for(iterator it=begin(); it!=end(); ++it) { while(it.current->next && it.current->next->value && (*(it.current->value))==(*(it.current->next->value)) ) { tjnode* toberemoved=it.current->next; remove_node(toberemoved); delete toberemoved; } } check("unique(post)"); } private: void push_back_node(tjnode* newnode) { check("push_back_node(pre)"); newnode->next=0; newnode->prev=0; if(first==(&end_node)) { first=end_node.prev=newnode; newnode->next=&end_node; } else { end_node.prev->next=newnode; newnode->prev=end_node.prev; end_node.prev=newnode; newnode->next=&end_node; } size_cache++; check("push_back_node(post)"); } void push_front_node(tjnode* newnode) { check("push_front_node(pre)"); newnode->next=0; newnode->prev=0; if(first==(&end_node)) { first=end_node.prev=newnode; newnode->next=&end_node; } else { first->prev=newnode; newnode->next=first; first=newnode; } size_cache++; check("push_front_node(post)"); } void remove_node(tjnode* toberemoved) { check("remove_node(pre)"); if(toberemoved->prev) toberemoved->prev->next=toberemoved->next; if(toberemoved->next) toberemoved->next->prev=toberemoved->prev; if(toberemoved==first) first=toberemoved->next; if(toberemoved==end_node.prev) end_node.prev= toberemoved->prev; toberemoved->next=0; toberemoved->prev=0; size_cache--; check("remove_node(post)"); } // Insert before posnode void insert_node(tjnode* posnode, tjnode* newnode) { check("insert_node(pre)"); newnode->next=0; newnode->prev=0; if(posnode==(&end_node)) { push_back_node(newnode); } else { if(posnode==first) push_front_node(newnode); else { // in the following the order is important posnode->prev->next=newnode; newnode->prev=posnode->prev; newnode->next=posnode; posnode->prev=newnode; size_cache++; } } check("insert_node(post)"); } void check(const char* /*caller*/) const { #ifdef ODIN_DEBUG /* if(!first) STD_cerr << "ERROR: tjstd_list::" << caller << " !first " << STD_endl; int size=0; for(const_iterator it=begin(); it!=end(); ++it) size++; if(size!=size_cache) STD_cerr << "ERROR: tjstd_list::" << caller << " size(" << size << ") != size_cache(" << size_cache << ")" << STD_endl; */ #endif } tjnode* first; mutable tjnode end_node; int size_cache; }; template tjiterator tjstd_find(const tjiterator& b,const tjiterator& e, const I& findval) { tjiterator it=b; while(it!=e) { if((*it)==findval) return it; ++it; } return e; } //////////////////////////////////////////////////////////////////////////// template class tjstd_pair { public: tjstd_pair() {} tjstd_pair(const K& key, const V& value) : first(key), second(value) {} bool operator == (const tjstd_pair& i2) const { // do not use == operator of K, otherwise it has to be defined if( (first& i2) const { return (first tjstd_pair tjstd_make_pair(const K& k, const V& v) { return tjstd_pair(k,v); } ////////////////////////////// template class tjstd_map : public tjstd_list< tjstd_pair > { public: V& operator [] (const K& key) { typename tjstd_map::iterator it=find(key); if(it==tjstd_list< tjstd_pair >::end()) { it=push_back(tjstd_pair(key,V())); tjstd_list< tjstd_pair >::sort(); } return it->second; } typename tjstd_map::iterator find(const K& key) { for(typename tjstd_map::iterator it=tjstd_list< tjstd_pair >::begin(); it!=tjstd_list< tjstd_pair >::end(); ++it) { if( !( (key<(it->first)) || ((it->first) >::end(); } typename tjstd_map::iterator find(const K& key) const { for(typename tjstd_map::const_iterator it=tjstd_list< tjstd_pair >::begin(); it!=tjstd_list< tjstd_pair >::end(); ++it) { if( !( (key<(it->first)) || ((it->first) >::end(); } void insert(const tjstd_pair& pair) { if(find(pair.first)==tjstd_list< tjstd_pair >::end()) { (*this)[pair.first]=pair.second; } } typename tjstd_map::iterator insert(typename tjstd_map::iterator, const tjstd_pair& pair) { if(find(pair.first)==tjstd_list< tjstd_pair >::end()) { (*this)[pair.first]=pair.second; } return find(pair.first); } }; //////////////////////////////////////////////////////////////////////////// // Extra type for vector size to avoid type-conversion problems in arithmetic expressions on VxWorks // which occur if a simple 'unsigned int' is used in the constructor of tjstd_vector struct tjstd_vector_size { tjstd_vector_size(unsigned int size) : s(size) {} unsigned int s; }; template class tjstd_vector { public: tjstd_vector() : data(0), nelements(0), cap(0) {} tjstd_vector(tjstd_vector_size size, const E& initval=E()) : data(0), nelements(0), cap(0) { resize(size.s); for(unsigned int i=0; i& v) : data(0), nelements(0), cap(0) { tjstd_vector::operator = (v); } ~tjstd_vector() { if(data) delete[] data; } tjstd_vector& operator = (const tjstd_vector& v) { if(data) delete[] data; nelements=cap=v.nelements; data=new E[nelements]; for(unsigned int i=0; i=nelements) { // STD_cerr << "ERROR: tjstd_vector: operator[" << i << "] exceeds size=" << nelements << STD_endl; return retdummy; } else return data[i]; } const E& operator [] (unsigned long i) const { if(i>=nelements) { // STD_cerr << "ERROR: tjstd_vector: operator[" << i << "] exceeds size=" << nelements << STD_endl; return retdummy; } else return data[i]; } void clear() { resize(0);} void resize(unsigned long newsize) { if(newsize>cap) { cap=newsize*2; E* newdata=new E[cap]; if(data) { for(unsigned int i=0; icap) { cap=newcap; E* newdata=new E[cap]; if(data) { for(unsigned int i=0; i bool operator == (const tjstd_vector& v1, const tjstd_vector& v2) { if(v1.size()!=v2.size()) return false; bool result=true; for(unsigned int i=0; i bool operator != (const tjstd_vector& v1, const tjstd_vector& v2) { return !(v1==v2); } template bool operator < (const tjstd_vector& v1, const tjstd_vector& v2) { unsigned int v1size=v1.size(); unsigned int v2size=v2.size(); if(v1size!=v2size) return (v1size void tjstd_swap(T& a1, T& a2){ T temp=a1; a1=a2; a2=temp; } template T tjstd_max(const T& a1, const T& a2){ if(a1>a2) return a1; else return a2; } template T tjstd_min(const T& a1, const T& a2){ if(a1 (const tjstd_string& s, const tjstd_string& t); friend STD_ostream& operator << (STD_ostream& s,const tjstd_string& t); friend STD_istream& operator >> (STD_istream& s, tjstd_string& t); tjstd_string substr(unsigned int begin,unsigned int sublength) const; void erase(unsigned int begin,unsigned int end); unsigned int find(const tjstd_string& searchstring, int startpos=0) const; typedef unsigned int size_type; static unsigned int npos; private: void concat2strings(const tjstd_string& srcstring1, const tjstd_string& srcstring2); static bool compare2strings(const char* str1, const char* str2); char* sdata; unsigned int length_cache; static char nullchar; }; #endif // STRING_REPLACEMENT //////////////////////////////////////////////////////////////////////////// /** @} */ #endif odin-1.8.5/tjutils/tjvallist.cpp0000644000175000017500000003035111455553536013633 00000000000000#include "tjvallist.h" #include "tjlog.h" #include "tjtypes.h" #include "tjtest.h" template ValList::ValList(const STD_string& object_label, unsigned int repetitions) : Labeled(), data(new ValListData) { set_label(object_label); data->times=repetitions; data->references=1; } template ValList::ValList(T value) : Labeled(), data(new ValListData) { data->val=new T(value); data->elements_size_cache=1; data->references=1; } template ValList::ValList(const ValList& svl) : Labeled(svl), data(svl.data) { data->references++; } template ValList::~ValList() { clear(); data->references--; if(!(data->references)) delete data; } template ValList& ValList::operator = (const ValList& svl) { Labeled::operator = (svl); set_label(svl.get_label()); data->references--; if(!(data->references)) delete data; data=svl.data; data->references++; return *this; } template bool ValList::operator == (const ValList& vl) const { return ( (get_elements_flat()==vl.get_elements_flat()) && (data->times==vl.data->times) ); } template bool ValList::operator < (const ValList& vl) const { bool result=true; if(! (get_elements_flat()timestimes) ) result=false; return result; } template bool ValList::equalelements (const ValList& svl) const { Log odinlog(this,"equalelements"); ODINLOG(odinlog,normalDebug) << "comparing with " << svl.get_label() << STD_endl; unsigned int thissize=data->elements_size_cache; unsigned int svlsize=svl.data->elements_size_cache; ODINLOG(odinlog,normalDebug) << "thissize/svlsize=" << thissize << "/" << svlsize << STD_endl; if(thissize!=svlsize) return false; if(thissize==0 && svlsize==0) return false; ODINLOG(odinlog,normalDebug) << "getting elements of this" << STD_endl; STD_vector thiselements=get_elements_flat(); ODINLOG(odinlog,normalDebug) << "getting elements of " << svl.get_label() << STD_endl; STD_vector svlelements=svl.get_elements_flat(); ODINLOG(odinlog,normalDebug) << "comparing vectors" << STD_endl; if(thiselements.size()==0 && svlelements.size()==0) return false; return (thiselements==svlelements); } template ValList& ValList::set_value(T value) { copy_on_write(); if(data->sublists) delete data->sublists; data->sublists=0; if(data->val) *(data->val)=value; else data->val=new T(value); data->elements_size_cache=1; return *this; } template ValList& ValList::add_sublist(const ValList& svl) { Log odinlog(this,"add_sublist"); copy_on_write(); if( !(svl.data->val || svl.data->sublists) ) { ODINLOG(odinlog,normalDebug) << "discarding empty list" << STD_endl; return *this; } ODINLOG(odinlog,normalDebug) << "checking for equal elements" << STD_endl; if(equalelements(svl)) { increment_repetitions(svl.get_repetitions()); ODINLOG(odinlog,normalDebug) << "incrementing repetitions" << STD_endl; return *this; } if(data->sublists && data->val) { ODINLOG(odinlog,errorLog) << "sublists and value allocated" << STD_endl; return *this; } if(!data->sublists && !data->val) { ODINLOG(odinlog,normalDebug) << "assigning" << STD_endl; if(svl.data->val) ODINLOG(odinlog,normalDebug) << "svl has val" << STD_endl; if(svl.data->sublists) ODINLOG(odinlog,normalDebug) << "svl has sublists" << STD_endl; STD_string label_cache(get_label()); (*this)=svl; set_label(label_cache); return *this; } if(!data->sublists && data->val) { ODINLOG(odinlog,normalDebug) << "allocating new sublists" << STD_endl; data->sublists=new STD_list< ValList >; for(unsigned int i=0; itimes; i++) data->sublists->push_back(ValList(*data->val)); // add element by element data->elements_size_cache=data->times; delete data->val; data->val=0; data->times=1; data->sublists->push_back(svl); data->elements_size_cache+=svl.size(); return *this; } if(data->sublists && !data->val) { ODINLOG(odinlog,normalDebug) << "appending" << STD_endl; if(data->times!=1) flatten_sublists(); data->sublists->push_back(svl); data->elements_size_cache+=svl.size(); return *this; } return *this; } template void ValList::flatten_sublists() { Log odinlog(this,"flatten_sublists"); copy_on_write(); STD_vector vals_flat=get_values_flat(); if(data->sublists) data->sublists->clear(); else data->sublists=new STD_list< ValList >; for(unsigned int i=0; isublists->push_back(ValList(vals_flat[i])); data->times=1; data->elements_size_cache=vals_flat.size(); } template STD_vector ValList::get_elements_flat() const { STD_list vallist; if(data->val) vallist.push_back(*data->val); if(data->sublists) { for(typename STD_list< ValList >::const_iterator it=data->sublists->begin(); it!=data->sublists->end(); ++it) { STD_vector subelements=it->get_values_flat(); for(unsigned int i=0; i result; result.resize(listsize); unsigned int index=0; for(typename STD_list::const_iterator valit=vallist.begin(); valit!=vallist.end(); ++valit) { result[index]=(*valit); index++; } return result; } template STD_vector ValList::get_values_flat() const { STD_vector elements=get_elements_flat(); unsigned int listsize=elements.size(); STD_vector result; result.resize(listsize*data->times); for(unsigned int itimes=0; itimestimes; itimes++) { for(unsigned int i=0; i T ValList::operator [] (unsigned int i) const { if(data->val) { if(i==0) return (*data->val); else i--; } if(data->sublists) { for(unsigned j=0; jtimes; j++) { for(typename STD_list< ValList >::const_iterator it=data->sublists->begin(); it!=data->sublists->end(); ++it) { unsigned int subsize=it->ValList::size(); if(ioperator [] (i); else i-=subsize; } } } return 0; } /* template unsigned int ValList::elements_size() const { unsigned int result=0; if(data->val) result++; if(data->sublists) { for(typename STD_list< ValList >::const_iterator it=data->sublists->begin(); it!=data->sublists->end(); ++it) { result+=it->ValList::size(); } } return result; } */ template STD_string ValList::printvallist() const { Log odinlog(this,"printvallist"); STD_string result; if(data->val) { result+=TypeTraits::type2string(*data->val)+" "; } if(data->sublists) { for(typename STD_list< ValList >::const_iterator it=data->sublists->begin(); it!=data->sublists->end(); ++it) { result+=it->printvallist(); } } if(data->times>1) result="{"+itos(data->times)+"| "+result+"} "; return result; } template STD_ostream& ValList::print2stream(STD_ostream& os) const { if(data->times>1) os << "{" << itos(data->times) << "| "; if(data->val) os << (*data->val) << " "; if(data->sublists) { for(typename STD_list< ValList >::const_iterator it=data->sublists->begin(); it!=data->sublists->end(); ++it) { it->print2stream(os); } } if(data->times>1) os << "} "; return os; } template bool ValList::parsevallist(const STD_string& str) { Log odinlog(this,"parsevallist"); copy_on_write(); svector toks(tokens(str)); unsigned int ntoks=toks.size(); ODINLOG(odinlog,normalDebug) << "ntoks=" << ntoks << STD_endl; unsigned int itok=0; while(itok=1) slist.increment_repetitions(rep-1); } else { T valdummy; TypeTraits::string2type(toks[itok],valdummy); ODINLOG(odinlog,normalDebug) << "valdummy=" << valdummy << STD_endl; slist.set_value(T(valdummy)); itok++; } add_sublist(slist); } return true; } template void ValList::clear() { copy_on_write(); if(data->sublists) delete data->sublists; data->sublists=0; if(data->val) delete data->val; data->val=0; data->elements_size_cache=0; } template void ValList::copy_on_write() { Log odinlog(this,"copy_on_write"); ODINLOG(odinlog,normalDebug) << "references=" << data->references << STD_endl; if(data->references>1) { data->references--; data=new ValListData(*data); data->references++; } } // instantiations reuired for ODIN template class ValList; template class ValList; ///////////////////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST typedef ValList ValListInt; class ValListTest : public UnitTest { public: ValListTest() : UnitTest("vallist") {} private: bool check() const { Log odinlog(this,"check"); ValListInt v1(1); ValListInt v2; v2.set_value(2); ValListInt vl; vl.add_sublist(v1); vl.add_sublist(v2); STD_string expected="1 2 "; STD_string printed=vl.printvallist(); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "add_sublist(v1,v2) failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } ///////////////////////////////////////// ValListInt vl2; vl2.add_sublist(vl); vl2.add_sublist(vl); vl2.add_sublist(vl); expected="{3| 1 2 } "; printed=vl2.printvallist(); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "add_sublist(3*vl) failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="1 2 1 2 1 2"; printed=ivector(vl2.get_values_flat()).printbody(); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "get_values_flat failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } expected="3"; printed=itos(vl2.get_repetitions()); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "get_repetitions failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } ///////////////////////////////////////// vl2.clear(); vl.multiply_repetitions(7); vl2.add_sublist(vl); vl.multiply_repetitions(9); vl2.add_sublist(vl); vl2.multiply_repetitions(2); expected="{140| 1 2 } "; // (7 + 7*9)*2=140 printed=vl2.printvallist(); if( expected!=printed ) { ODINLOG(odinlog,errorLog) << "multiply_repetitions failed, got >" << printed << "< but expected >" << expected << "<" << STD_endl; return false; } ///////////////////////////////////////// v1.clear(); v1.parsevallist("{3| 1 2 {3| 4 5 } }"); unsigned int expected_size=24; unsigned int calculated_size=v1.size(); if( expected_size!=calculated_size ) { ODINLOG(odinlog,errorLog) << "size() failed, got >" << calculated_size << "< but expected >" << expected_size << "<" << STD_endl; return false; } v1.clear(); expected_size=0; calculated_size=v1.size(); if( expected_size!=calculated_size ) { ODINLOG(odinlog,errorLog) << "size() failed, got >" << calculated_size << "< but expected >" << expected_size << "<" << STD_endl; return false; } return true; } }; void alloc_ValListTest() {new ValListTest();} // create test instance #endif odin-1.8.5/tjutils/tjhandler_code.h0000644000175000017500000000752011322062342014212 00000000000000#include #include ////////////////////////////////////////////////////////////// template Handled::Handled() {} template Handled::~Handled() { Log odinlog("Handled","~Handled"); for(typename STD_list< const Handler* >::const_iterator it=handlers.begin(); it!=handlers.end(); ++it) { (*it)->handled_remove(this); // do not call L::remove here because it will modify handlers list } } template const Handled& Handled::set_handler(const Handler& handler) const { handlers.push_back(&handler); return *this; } template const Handled& Handled::erase_handler(const Handler& handler) const { handlers.remove(&handler); return *this; } ///////////////////////////////////////////// template Handler::Handler() { handledobj=0; } template Handler::Handler(const Handler& handler) { Handler::operator = (handler); } template Handler& Handler::operator = (const Handler& handler) { clear_handledobj(); I hd=handler.get_handled(); if(hd) set_handled(hd); return *this; } template Handler::~Handler() { Log odinlog("Handler","~Handler"); clear_handledobj(); } template const Handler& Handler::clear_handledobj() const { Log odinlog("Handler","clear_handledobj"); ODINLOG(odinlog,normalDebug) << "handledobj=" << (void*)handledobj << STD_endl; if(handledobj) handledobj->Handled::erase_handler(*this); handledobj=0; return *this; } template const Handler& Handler::set_handled(I handled) const { Log odinlog("Handler","set_handled"); ODINLOG(odinlog,normalDebug) << "handled=" << (void*)handled << STD_endl; clear_handledobj(); handled->Handled::set_handler(*this); handledobj=handled; return *this; } template I Handler::get_handled() const { return handledobj; } template const Handler& Handler::handled_remove(Handled* handled) const { Log odinlog("Handler","handled_remove"); I handledtype=static_cast(handled); ODINLOG(odinlog,normalDebug) << "handledtype=" << (void*)handledtype << STD_endl; if(handledtype) handledobj=0; else ODINLOG(odinlog,errorLog) << "Unable to remove handled!" << STD_endl; return *this; } //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// template void SingletonHandler::init (const char* unique_label) { // NOTE: Debug uses SingletonHandler -> do not use Debug in here singleton_label=new STD_string; mutex=0; if(thread_safe) mutex=new Mutex(); (*singleton_label)=unique_label; if(!get_external_map_ptr(unique_label)) { ptr=new T; ptr->set_label(unique_label); (*get_singleton_map())[unique_label]=this; // make sure singleton_map is allocated } else { ptr=0; } } template void SingletonHandler::destroy () { if(ptr) delete ptr; ptr=0; delete singleton_label; if(mutex) delete mutex; } template void SingletonHandler::copy(T& destination) const { T* p=get_map_ptr(); if(p) destination=(*p); } template T* SingletonHandler::get_map_ptr() const { if(ptr) return ptr; // fast return without touching the map if(singleton_map_external) { T* ext_ptr=(T*)get_external_map_ptr(*singleton_label); if(ext_ptr) ptr=ext_ptr; } return ptr; } odin-1.8.5/tjutils/Makefile.am0000644000175000017500000000253311322062342013127 00000000000000 INCLUDES = $(all_includes) lib_LTLIBRARIES = libtjutils.la libtjutils_la_LDFLAGS = -no-undefined -release $(VERSION) $(BASELIBS) library_includedir=$(includedir)/tjutils library_include_HEADERS = \ tjarray.h \ tjcomplex.h \ tjcstd.h \ tjembed.h \ tjfeedback.h \ tjhandler.h tjhandler_code.h \ tjheap.h \ tjindex.h \ tjlabel.h \ tjlist.h tjlist_code.h \ tjlog.h tjlog_code.h \ tjnumeric.h \ tjprocess.h \ tjprofiler.h \ tjstate.h \ tjstatic.h \ tjstd.h \ tjstream.h \ tjstring.h \ tjtest.h \ tjthread.h tjthread_code.h \ tjtools.h \ tjtypes.h \ tjutils.h \ tjvallist.h \ tjvector.h tjutils_configdir = $(includedir)/tjutils tjutils_config_DATA = config.h libtjutils_la_SOURCES = \ tjarray.h tjarray.cpp \ tjcomplex.h tjcomplex.cpp \ tjcstd.h tjcstd.cpp \ tjlog.h tjlog.cpp tjlog_code.h \ tjembed.h tjembed.cpp \ tjfeedback.h tjfeedback.cpp \ tjhandler.h tjhandler.cpp tjhandler_code.h \ tjheap.h tjheap.cpp \ tjindex.h tjindex.cpp \ tjlabel.h \ tjlist.h tjlist.cpp tjlist_code.h \ tjnumeric.h tjnumeric.cpp \ tjprocess.h tjprocess.cpp \ tjprofiler.h tjprofiler.cpp \ tjstate.h tjstate.cpp \ tjstatic.h tjstatic.cpp \ tjstd.h tjstd.cpp \ tjstream.h tjstream.cpp \ tjstring.h tjstring.cpp \ tjtest.h tjtest.cpp \ tjthread.h tjthread.cpp tjthread_code.h \ tjtools.h tjtools.cpp \ tjtypes.h tjtypes.cpp \ tjutils.h \ tjvallist.h tjvallist.cpp \ tjvector.h tjvector.cpp odin-1.8.5/tjutils/Makefile.in0000644000175000017500000005521611734622602013156 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = tjutils DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(srcdir)/config.h.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(tjutils_configdir)" \ "$(DESTDIR)$(library_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libtjutils_la_LIBADD = am_libtjutils_la_OBJECTS = tjarray.lo tjcomplex.lo tjcstd.lo tjlog.lo \ tjembed.lo tjfeedback.lo tjhandler.lo tjheap.lo tjindex.lo \ tjlist.lo tjnumeric.lo tjprocess.lo tjprofiler.lo tjstate.lo \ tjstatic.lo tjstd.lo tjstream.lo tjstring.lo tjtest.lo \ tjthread.lo tjtools.lo tjtypes.lo tjvallist.lo tjvector.lo libtjutils_la_OBJECTS = $(am_libtjutils_la_OBJECTS) libtjutils_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libtjutils_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libtjutils_la_SOURCES) DIST_SOURCES = $(libtjutils_la_SOURCES) DATA = $(tjutils_config_DATA) HEADERS = $(library_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = $(all_includes) lib_LTLIBRARIES = libtjutils.la libtjutils_la_LDFLAGS = -no-undefined -release $(VERSION) $(BASELIBS) library_includedir = $(includedir)/tjutils library_include_HEADERS = \ tjarray.h \ tjcomplex.h \ tjcstd.h \ tjembed.h \ tjfeedback.h \ tjhandler.h tjhandler_code.h \ tjheap.h \ tjindex.h \ tjlabel.h \ tjlist.h tjlist_code.h \ tjlog.h tjlog_code.h \ tjnumeric.h \ tjprocess.h \ tjprofiler.h \ tjstate.h \ tjstatic.h \ tjstd.h \ tjstream.h \ tjstring.h \ tjtest.h \ tjthread.h tjthread_code.h \ tjtools.h \ tjtypes.h \ tjutils.h \ tjvallist.h \ tjvector.h tjutils_configdir = $(includedir)/tjutils tjutils_config_DATA = config.h libtjutils_la_SOURCES = \ tjarray.h tjarray.cpp \ tjcomplex.h tjcomplex.cpp \ tjcstd.h tjcstd.cpp \ tjlog.h tjlog.cpp tjlog_code.h \ tjembed.h tjembed.cpp \ tjfeedback.h tjfeedback.cpp \ tjhandler.h tjhandler.cpp tjhandler_code.h \ tjheap.h tjheap.cpp \ tjindex.h tjindex.cpp \ tjlabel.h \ tjlist.h tjlist.cpp tjlist_code.h \ tjnumeric.h tjnumeric.cpp \ tjprocess.h tjprocess.cpp \ tjprofiler.h tjprofiler.cpp \ tjstate.h tjstate.cpp \ tjstatic.h tjstatic.cpp \ tjstd.h tjstd.cpp \ tjstream.h tjstream.cpp \ tjstring.h tjstring.cpp \ tjtest.h tjtest.cpp \ tjthread.h tjthread.cpp tjthread_code.h \ tjtools.h tjtools.cpp \ tjtypes.h tjtypes.cpp \ tjutils.h \ tjvallist.h tjvallist.cpp \ tjvector.h tjvector.cpp all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tjutils/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu tjutils/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): config.h: stamp-h1 @if test ! -f $@; then \ rm -f stamp-h1; \ $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \ else :; fi stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status @rm -f stamp-h1 cd $(top_builddir) && $(SHELL) ./config.status tjutils/config.h $(srcdir)/config.h.in: $(am__configure_deps) ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) rm -f stamp-h1 touch $@ distclean-hdr: -rm -f config.h stamp-h1 install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libtjutils.la: $(libtjutils_la_OBJECTS) $(libtjutils_la_DEPENDENCIES) $(libtjutils_la_LINK) -rpath $(libdir) $(libtjutils_la_OBJECTS) $(libtjutils_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjarray.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjcomplex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjcstd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjembed.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjfeedback.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjhandler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjheap.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjindex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjlog.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjnumeric.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjprocess.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjprofiler.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjstate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjstatic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjstd.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjstream.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjstring.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjthread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjtools.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjtypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjvallist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tjvector.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-tjutils_configDATA: $(tjutils_config_DATA) @$(NORMAL_INSTALL) test -z "$(tjutils_configdir)" || $(MKDIR_P) "$(DESTDIR)$(tjutils_configdir)" @list='$(tjutils_config_DATA)'; test -n "$(tjutils_configdir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(tjutils_configdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(tjutils_configdir)" || exit $$?; \ done uninstall-tjutils_configDATA: @$(NORMAL_UNINSTALL) @list='$(tjutils_config_DATA)'; test -n "$(tjutils_configdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(tjutils_configdir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(tjutils_configdir)" && rm -f $$files install-library_includeHEADERS: $(library_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(library_includedir)" || $(MKDIR_P) "$(DESTDIR)$(library_includedir)" @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(library_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(library_includedir)" || exit $$?; \ done uninstall-library_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(library_includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(library_includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(DATA) $(HEADERS) config.h installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(tjutils_configdir)" "$(DESTDIR)$(library_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-library_includeHEADERS \ install-tjutils_configDATA install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS uninstall-tjutils_configDATA .MAKE: all install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-hdr \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES \ install-library_includeHEADERS install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ install-tjutils_configDATA installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS uninstall-tjutils_configDATA # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/tjutils/tjlist_code.h0000644000175000017500000001012111322062342013537 00000000000000#include #include #ifdef HAVE_TYPEINFO #include #endif template ListItem::~ListItem() { Log odinlog("ListItem","~ListItem"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "deleting object of type >" << typeid(I).name() << "<" << STD_endl; #endif for(STD_list::iterator it=objhandlers.begin(); it!=objhandlers.end(); ++it) { (*it)->objlist_remove(this); } } template const ListItemBase& ListItem::append_objhandler(ListBase& objhandler) const { Log odinlog("ListItem","append_objhandler"); objhandlers.push_back(&objhandler); return *this; } template const ListItemBase& ListItem::remove_objhandler(ListBase& objhandler) const { Log odinlog("ListItem","remove_objhandler"); objhandlers.remove(&objhandler); return *this; } /////////////////////////////////////////////////////////////////////////////////////////// template List::List() { Log odinlog("List","List()"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "constructing list of >" << typeid(I).name() << "<" << STD_endl; #endif } template List::~List() { Log odinlog("List","~List()"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "destructing list of >" << typeid(I).name() << "<" << STD_endl; #endif clear(); } template List& List::operator = (const List& l) { clear(); for(typename STD_list

    ::const_iterator it=l.objlist.begin(); it!=l.objlist.end(); ++it) { append(**it); } return *this; } template List& List::clear() { Log odinlog("List","clear"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "Clearing list of type >" << typeid(I).name() << "<" << STD_endl; #endif for(typename STD_list

    ::iterator it=objlist.begin(); it!=objlist.end(); ++it) { ODINLOG(odinlog,normalDebug) << "Unlinking " << (*it) << STD_endl; unlink_item(*it); ODINLOG(odinlog,normalDebug) << "Unlinking done" << STD_endl; } objlist.erase(objlist.begin(),objlist.end()); return *this; } template List& List::append(R item) { Log odinlog("List","append"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "appending object of type >" << typeid(I).name() << "<" << STD_endl; #endif link_item(&item); objlist.push_back(&item); return *this; } template List& List::remove(R item) { Log odinlog("List","remove"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "removing object of type >" << typeid(I).name() << "<" << STD_endl; #endif unlink_item(&item); objlist.remove(&item); return *this; } template void List::objlist_remove(ListItemBase* item) { Log odinlog("List","objlist_remove"); #ifdef HAVE_TYPEINFO ODINLOG(odinlog,normalDebug) << "deleting object of type >" << typeid(I).name() << "<" << STD_endl; #endif P itemItype=static_cast

    (item); if(itemItype) { objlist.remove(itemItype); } else { ODINLOG(odinlog,errorLog) << "static_cast failed" << STD_endl; } } template void List::link_item(P ptr) { Log odinlog("List","link_item"); const ListItem* item=static_cast*>(ptr); if(item) { item->append_objhandler(*this); } else { ODINLOG(odinlog,errorLog) << "static_cast failed" << STD_endl; } } template void List::unlink_item(P ptr) { Log odinlog("List","unlink_item"); const ListItem* item=static_cast*>(ptr); if(item) { item->remove_objhandler(*this); } else { ODINLOG(odinlog,errorLog) << "static_cast failed" << STD_endl; } } odin-1.8.5/tjutils/tjvector.h0000644000175000017500000003222611322062342013106 00000000000000 /*************************************************************************** tjvector.h - description ------------------- begin : Thu Feb 22 2001 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJVECTOR_H #define TJVECTOR_H #include #include #include #include #include /** * @addtogroup tjutils * @{ */ class VectorComp { public: static const char* get_compName(); }; /** * * This class represents a basic vector which is derived * from the Standard Template Library (STL) vector class. * it adds some useful functionality to the STL base class, * for example element-wise arithmetics and reading/writing. */ template class tjvector : public STD_vector { public: /** * * constructs a vector and allocates memory for n values * which are initialised to zero. */ tjvector(unsigned int n=0); /** * * constructs a vector of length n and gets n values from array * No bounds checking possible, so take care that the pointer array * has memory allocated which is in fact n values long. */ tjvector(const T *array, unsigned int n); /** * * constructs a copy from std::vector */ tjvector(const STD_vector& v); /** * * Copy constructor */ tjvector(const tjvector& tv); /** * * destructor */ virtual ~tjvector(); /** * * assign value to all elements of vector */ tjvector& operator = (const T& value); /** * * assignment from std::vector */ tjvector& operator = (const STD_vector& vec); /** * * copy assignment */ tjvector& operator = (const tjvector& tv); /** * * returns the element-wise sum of two tjvectors */ tjvector operator + (const STD_vector& w) const { tjvector result(*this); for(unsigned int i=0; i operator - (const STD_vector& w) const { tjvector result(*this); for(unsigned int i=0; i operator * (const STD_vector& w) const { tjvector result(*this); for(unsigned int i=0; i operator / (const STD_vector& w) const { tjvector result(*this); for(unsigned int i=0; i operator - () const { tjvector result(*this); for(unsigned int i=0; i operator + (const T& s, const STD_vector& v) { tjvector result(v); for(unsigned int i=0; i operator + (const T& s) const { return s+(*this); } /** * * returns the element-wise difference of a tjvector with a scalar */ friend tjvector operator - (const T& s, const STD_vector& v) { tjvector result(v); for(unsigned int i=0; i operator - (const T& s) const { return -s+(*this); } /** * * returns the element-wise product of a tjvector with a scalar */ friend tjvector operator * (const T& s, const STD_vector& v) { tjvector result(v); for(unsigned int i=0; i operator * (const T& s) const { return s*(*this); } /** * * returns the element-wise division of a tjvector with a scalar */ friend tjvector operator / (const T& s, const STD_vector& v) { tjvector result(v); for(unsigned int i=0; i operator / ( const T& s) const { return (T(1)/s)*(*this); } /** * Equivalent to: this = this + v */ tjvector& operator += ( const STD_vector& v) { (*this)=(*this)+v; return (*this); } /** * Equivalent to: this = this + s */ tjvector& operator += ( const T& s) { (*this)=(*this)+s; return (*this); } /** * Equivalent to: this = this - v */ tjvector& operator -= ( const STD_vector& v) { (*this)=(*this)-v; return (*this); } /** * Equivalent to: this = this - s */ tjvector& operator -= ( const T& s) { (*this)=(*this)-s; return (*this); } /** * Equivalent to: this = this * v */ tjvector& operator *= ( const STD_vector& v) { (*this)=(*this)*v; return (*this); } /** * Equivalent to: this = this * s */ tjvector& operator *= ( const T& s) { (*this)=(*this)*s; return (*this); } /** * Equivalent to: this = this / v */ tjvector& operator /= ( const STD_vector& v) { (*this)=(*this)/v; return (*this); } /** * Equivalent to: this = this / s */ tjvector& operator /= ( const T& s) { (*this)=(*this)/s; return (*this); } /** * * Resizes the vector to 'newsize'. * If the 'newsize' is smaller than the actual size, * the starting values will be preserved in the smaller vector. * If the 'newsize' is larger than the actual size, * the vector will be zero padded. */ virtual tjvector& resize(unsigned int newsize); /** * * returns the length */ unsigned int length () const; /** * * fill the array linearly from value min to value max, return number of fills */ unsigned int fill_linear(const T& min,const T& max); /** * * Returns the sum of all elements */ T sum() const; /** * * Returns the given range of elements starting at startindex and ending at endindex-1 */ tjvector range(unsigned int startindex, unsigned int endindex) const; /** * * Return the greatest value */ T maxvalue() const; /** * * Return the smallest value */ T minvalue() const; /** * * Maximum absolute value */ T maxabs() const; /** * * Returns an allocated C-style array of Ts with the values of this vector. * The array is deleted automatically at the next call of c_array() or if * this vector is destroyed. */ const T* c_array() const; /** * * Gets n values from 'array' (raw memory), no resizing is done * prior to assignment, this has to be manually beforehand. * No bounds checking possible, so take care that the pointer array * has memory allocated which is in fact n values long. */ tjvector& set_c_array(const unsigned char* array, unsigned int n); /** * * Normalize the vector, i.e. make its smallest/largest non-zero value become -1 or 1. * Returns the maximum absolute value which was used to achieve the normalization. */ T normalize(); /** * * interpolate values to new size 'newsize'. Add extra shift 'subpixel_shift' * in units of pixels on the destination grid. */ tjvector& interpolate(unsigned int newsize, float subpixel_shift=0.0); /** * * Loads the values from disk, the file is expected * to contain the same data type as the array. * Returns 0 on success, -1 otherwise. */ int load(const STD_string& fname); /** * * Writes the first 'nelements' values to disk as raw data, the 'mode' determines * whether data will be appended/overwritten if the file already exists. * If 'nelements' is negative, the whole vector will we written. * Returns 0 on success, -1 otherwise. */ int write(const STD_string& fname, fopenMode mode=overwriteMode, LONGEST_INT nelements=-1) const; /** * * returns the elements of the vector as a formatted string */ STD_string printbody() const; /** * * prints v to the stream s */ friend STD_ostream& operator << (STD_ostream& s,const tjvector& v) { return s << "(" << v.size() << ")=" << v.printbody(); } protected: // allocate aligned memory for type T (to avoid bus errors) static T* allocate_memory(unsigned int nelements) {return new T[nelements];} private: mutable T* c_array_cache; }; ///////////////////////////////////////////////////////////////////////////// // Aliases: /** * A vector of floating point numbers */ typedef tjvector fvector; /** * A vector of double precision floating point numbers */ typedef tjvector dvector; /** * A vector of integer numbers */ typedef tjvector ivector; /** * A vector of complex numbers */ typedef tjvector cvector; /** * A vector of strings */ struct svector : public STD_vector { // some extra stuff to be compatible with STD_vector svector() {} svector(const STD_vector& sv) {svector::operator = (sv);} svector& operator = (const STD_vector& sv) {STD_vector::operator = (sv); return *this;} // interface functions for JDXarray unsigned char* c_array() const {return 0;} svector& set_c_array(const unsigned char*, unsigned int) {return *this;} static unsigned char* allocate_memory(unsigned int) {return 0;} // other useful functions, imitating a tjvector STD_string printbody() const; }; ///////////////////////////////////////////////////////////////////////////// // Stuff to re-used in odindata STD_complex* interpolate1D(const STD_complex* data,unsigned int oldsize,unsigned int newsize, float subpixel_shift); float* interpolate1D(const float* olddata,unsigned int oldsize,unsigned int newsize, float subpixel_shift); double* interpolate1D(const double* olddata,unsigned int oldsize,unsigned int newsize, float subpixel_shift); int* interpolate1D(const int* olddata,unsigned int oldsize,unsigned int newsize, float subpixel_shift); ///////////////////////////////////////////////////////////////////////////// // Specialised helper functions: /** * * Converts a list into a vector */ template STD_vector list2vector(const STD_list& src) { STD_vector result; result.resize(src.size()); unsigned int i=0; for(typename STD_list::const_iterator it=src.begin(); it!=src.end(); ++it) { result[i]=(*it); i++; } return result; } /** * * Returns the real portion of a complex array */ fvector real(const cvector& cv); /** * * Returns the imaginary portion of a complex array */ fvector imag(const cvector& cv); /** * * Returns the amplitude of a complex array */ fvector amplitude(const cvector& cv); /** * * Returns the phase of a complex array */ fvector phase(const cvector& cv); /** * * Returns a complex array with 'fv' in the real component */ cvector real2complex(const fvector& fv); /** * * Converts a vector of floats to a vector of doubles */ dvector fvector2dvector(const fvector& fv); /** * * Converts a vector of doubles to a vector of floats */ fvector dvector2fvector(const dvector& dv); /** * * Splits the string into tokens, which are substrings separated by blanks, * tabs and newlines or custom_separator (if custom_separator!=0) and returns them as a vector of strings. * Parts of the string enclosed by 'escape_begin' and 'escape_end' will not be decomposed into tokens. */ svector tokens(const STD_string& tokenstring, char custom_separator=0, char escape_begin='"', char escape_end='"'); /** * * Produces a string with linebreaks if width exceeds 'linewidth' from a vector of single strings. * A 'linewidth' of zero will produce no linebreaks. */ STD_string tokenstring(const svector& tokens,unsigned int linewidth=_DEFAULT_LINEWIDTH_); /** * * Returns all entries in the given directory, if 'only_dirs' is 'true' * only subdirectories will be reported. Files starting with a dot * are discarded when setting 'discard_dotfiles' to 'true'. * The resulting vector is sorted alphanumerically according to the file names. */ svector browse_dir(const STD_string& dirname,bool only_dirs=false, bool discard_dotfiles=false); /** @} */ #endif odin-1.8.5/tjutils/tjtest.cpp0000644000175000017500000000207311322062342013113 00000000000000#include "tjtest.h" #include "tjlog_code.h" #ifndef NO_UNIT_TEST const char* UnitTest::get_compName() {return "UnitTest";} void UnitTest::init_static() { tests=new STD_list; } void UnitTest::destroy_static() { for(STD_list::const_iterator it=tests->begin(); it!=tests->end(); ++it) { delete (*it); } delete tests; } UnitTest::UnitTest(const char* label) { set_label(label); tests->push_back(this); } int UnitTest::check_all() { Log odinlog("","check_all"); if(!tests) return 0; for(STD_list::const_iterator it=tests->begin(); it!=tests->end(); ++it) { ODINLOG(odinlog,infoLog) << "Testing " << (*it)->get_label() << " ..." << STD_endl; if(!(*it)->check()) { ODINLOG(odinlog,errorLog) << "Test of " << (*it)->get_label() << " failed" << STD_endl; return -1; } } ODINLOG(odinlog,infoLog) << "All tests passed" << STD_endl; return 0; } STD_list* UnitTest::tests=0; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; LOGGROUNDWORK(UnitTest) #endif odin-1.8.5/tjutils/config.h.in0000644000175000017500000001547611734622601013137 00000000000000/* tjutils/config.h.in. Generated from configure.in by autoheader. */ /* Third-party libraries used by all ODIN components */ #undef BASELIBS /* Preprocessor flags */ #undef CPPFLAGS /* "Using custom heap" */ #undef CUSTOM_HEAP /* Size of Custom Heap in MB */ #undef CUSTOM_HEAP_SIZE /* Compiler */ #undef CXX /* Compiler flags */ #undef CXXFLAGS /* Initial default browser */ #undef DEFAULT_BROWSER /* Initial default editor */ #undef DEFAULT_EDITOR /* "DICOM support" */ #undef DICOMSUPPORT /* define for empty template list */ #undef EMPTY_TEMPL_LIST /* "Compile EPIC drivers" */ #undef EPIC_PLUGIN /* "Graphical User Interface enabled" */ #undef GUISUPPORT /* Define to 1 if you have the `acosh' function. */ #undef HAVE_ACOSH /* Define to 1 if you have the header file. */ #undef HAVE_CTYPE_H /* Define to 1 if you have the header file. */ #undef HAVE_DIRECT_H /* Define to 1 if you have the header file. */ #undef HAVE_DIRENT_H /* "Using dynamic linking loader" */ #undef HAVE_DL /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have the `erfc' function. */ #undef HAVE_ERFC /* Define to 1 if you have the `fopen64' function. */ #undef HAVE_FOPEN64 /* Define to 1 if you have the `fseeko' function. */ #undef HAVE_FSEEKO /* Define to 1 if you have the `fseeko64' function. */ #undef HAVE_FSEEKO64 /* Define to 1 if you have the `ftello' function. */ #undef HAVE_FTELLO /* Define to 1 if you have the `ftello64' function. */ #undef HAVE_FTELLO64 /* "Using gdb/xterm" */ #undef HAVE_GDB_XTERM /* Define to 1 if you have the `gettimeofday' function. */ #undef HAVE_GETTIMEOFDAY /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_IO_H /* Define to 1 if you have the `j1' function. */ #undef HAVE_J1 /* "Using LAPACK" */ #undef HAVE_LAPACK /* "GSL support" */ #undef HAVE_LIBGSL /* "libz support" */ #undef HAVE_LIBZ /* Define to 1 if you have the header file. */ #undef HAVE_LOCALE_H /* compiler understands long long */ #undef HAVE_LONG_LONG /* Define to 1 if you have the header file. */ #undef HAVE_MEMORY_H /* Define to 1 if you have the `mmap64' function. */ #undef HAVE_MMAP64 /* Define to 1 if you have the `nanosleep' function. */ #undef HAVE_NANOSLEEP /* Define to 1 if you have the `open64' function. */ #undef HAVE_OPEN64 /* "Using POSIX threads" */ #undef HAVE_PTHREAD /* Define to 1 if you have the header file. */ #undef HAVE_QWT_QT4_QWT_GLOBAL_H /* Define to 1 if you have the header file. */ #undef HAVE_QWT_QWT_GLOBAL_H /* Define to 1 if you have the `read' function. */ #undef HAVE_READ /* Define to 1 if you have the header file. */ #undef HAVE_SETJMP_H /* Define to 1 if you have the header file. */ #undef HAVE_SIGNAL_H /* Define to 1 if you have the `snprintf' function. */ #undef HAVE_SNPRINTF /* Define to 1 if you have the `srand' function. */ #undef HAVE_SRAND /* Define to 1 if you have the `stat' function. */ #undef HAVE_STAT /* Define to 1 if you have the `stat64' function. */ #undef HAVE_STAT64 /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strftime' function. */ #undef HAVE_STRFTIME /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strptime' function. */ #undef HAVE_STRPTIME /* Define to 1 if you have the `sysconf' function. */ #undef HAVE_SYSCONF /* Define to 1 if you have the header file. */ #undef HAVE_SYS_MMAN_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_WAIT_H /* "Thread-safe LAPACK" */ #undef HAVE_THREADSAFE_LAPACK /* Define to 1 if you have the header file. */ #undef HAVE_TIME_H /* Define to 1 if you have the header file. */ #undef HAVE_TYPEINFO /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have the header file. */ #undef HAVE_VTKARROWSOURCE_H /* Define to 1 if you have the header file. */ #undef HAVE_VTKSTRUCTUREDPOINTS_H /* Define to 1 if you have the header file. */ #undef HAVE_WINDOWS_H /* "Compile IDEA drivers" */ #undef IDEA_PLUGIN /* Installation prefix */ #undef INSTALL_PREFIX /* Linker */ #undef LD /* Linker flags */ #undef LDFLAGS /* libdir of configure */ #undef LIBDIR_CONFIGURE /* Define to the sub-directory in which libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* "MacOS support" */ #undef MACOS /* "NIFTI support" */ #undef NIFTISUPPORT /* "Not using command line" */ #undef NO_CMDLINE /* "No file handling" */ #undef NO_FILEHANDLING /* "Multithreading disabled" */ #undef NO_THREADS /* "Unit test disabled" */ #undef NO_UNIT_TEST /* "IDEA support" */ #undef ODIN4IDEA /* "Debug compilation" */ #undef ODIN_DEBUG /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* "Compile Paravision drivers" */ #undef PARAVISION_PLUGIN /* Plugin-Libraries */ #undef PLUGIN_LIBS /* "PNG support" */ #undef PNGSUPPORT /* "self-friend class possible/required" */ #undef SELF_FRIEND_CLASS /* The number of bytes in type char */ #undef SIZEOF_CHAR /* The number of bytes in type int */ #undef SIZEOF_INT /* The number of bytes in type long */ #undef SIZEOF_LONG /* The number of bytes in type short */ #undef SIZEOF_SHORT /* "Compile Standalone drivers" */ #undef STANDALONE_PLUGIN /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS /* "Using STL replacement" */ #undef STL_REPLACEMENT /* "Using stream replacement" */ #undef STREAM_REPLACEMENT /* "Using string replacement" */ #undef STRING_REPLACEMENT /* "Using the GNU compiler collection" */ #undef USING_GCC /* "Using Win32-API" */ #undef USING_WIN32 /* Version number of package */ #undef VERSION /* "Vista support" */ #undef VISTASUPPORT /* "VTK support" */ #undef VTKSUPPORT odin-1.8.5/tjutils/tjthread.cpp0000644000175000017500000003376411712547771013437 00000000000000#include "tjthread.h" #include "tjtools.h" #include "tjtest.h" #include "tjindex.h" #include "tjthread_code.h" #include "tjlog_code.h" #ifndef NO_THREADS #ifdef HAVE_PTHREAD #include #define USE_PTHREADS #endif #ifdef USING_WIN32 #include #define USE_WINTHREADS #endif #endif const char* ThreadComponent::get_compName() {return "Thread";} LOGGROUNDWORK(ThreadComponent) //////////////////////////////////////////////////////////////////// #ifdef USE_PTHREADS const char* pthread_err(int code) { if(code==EAGAIN) return "not enough system resources to create a process for the new thread."; if(code==ESRCH) return "No thread could be found corresponding to that specified by |th|."; if(code==EINVAL) return "The |th| thread has been detached./the mutex has not been properly initialized."; if(code==EINVAL) return "Another thread is already waiting on termination of |th|."; if(code==EDEADLK) return "The |th| argument refers to the calling thread./the mutex is already locked by the calling thread."; if(code==EBUSY) return "the mutex could not be acquired because it was currently locked./some threads are currently waiting on |cond|"; if(code==EPERM) return "the calling thread does not own the mutex."; if(code==ETIMEDOUT) return "the condition variable was not signaled until the timeout specified by |abstime|"; if(code==EINTR) return "!pthread_cond_timedwait! was interrupted by a signal"; if(code==ENOMEM) return "Out of memory"; return "Unknown error"; } #endif //////////////////////////////////////////////////////////////////// Mutex::Mutex() : id(0) { // Do not use Log in here since SingletonHandler uses Mutex #ifdef USE_PTHREADS #ifdef MACOS // the Mac OS way of creating recursive threads pthread_mutexattr_t pma_recursive; int errcode=pthread_mutexattr_init(&pma_recursive); if(errcode) { STD_cerr << "ERROR: Mutex: " << pthread_err(errcode) << STD_endl; return; } errcode=pthread_mutexattr_settype(&pma_recursive, PTHREAD_MUTEX_RECURSIVE); if(errcode) { STD_cerr << "ERROR: Mutex: " << pthread_err(errcode) << STD_endl; return; } id=(void*)new pthread_mutex_t; errcode=pthread_mutex_init((pthread_mutex_t*)id, &pma_recursive); if(errcode) { STD_cerr << "ERROR: Mutex: " << pthread_err(errcode) << STD_endl; return; } #else // the Linux way of creating recursive threads pthread_mutex_t pm_recursive=PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; id=(void*)new pthread_mutex_t(pm_recursive); #endif #endif #ifdef USE_WINTHREADS CRITICAL_SECTION* cs=new CRITICAL_SECTION; InitializeCriticalSection(cs); id=(void*)cs; #endif } Mutex::~Mutex() { // Do not use Log in here since SingletonHandler uses Mutex if(id) { #ifdef USE_PTHREADS int errcode=pthread_mutex_destroy((pthread_mutex_t*)id); if(errcode) STD_cerr << "ERROR: ~Mutex: " << pthread_err(errcode) << STD_endl; delete (pthread_mutex_t*)id; #endif #ifdef USE_WINTHREADS DeleteCriticalSection((CRITICAL_SECTION*)id); delete (CRITICAL_SECTION*)id; #endif } } void Mutex::lock() { // Do not use Log in here since SingletonHandler uses Mutex if(id) { #ifdef USE_PTHREADS int errcode=pthread_mutex_lock((pthread_mutex_t*)id); if(errcode) STD_cerr << "ERROR: Mutex::lock: " << pthread_err(errcode) << STD_endl; #endif #ifdef USE_WINTHREADS EnterCriticalSection((CRITICAL_SECTION*)id); #endif } } void Mutex::unlock() { // Do not use Log in here since SingletonHandler uses Mutex if(id) { #ifdef USE_PTHREADS int errcode=pthread_mutex_unlock((pthread_mutex_t*)id); if(errcode) STD_cerr << "ERROR: Mutex::unlock: " << pthread_err(errcode) << STD_endl; #endif #ifdef USE_WINTHREADS LeaveCriticalSection((CRITICAL_SECTION*)id); #endif } } //////////////////////////////////////////////////////////////////// Event::Event() : id(0), active(false) { Log odinlog("Event","Event"); #ifdef USE_PTHREADS pthread_cond_t cond=PTHREAD_COND_INITIALIZER; id=(void*)new pthread_cond_t(cond); #endif #ifdef USE_WINTHREADS id=(void*)new HANDLE; *((HANDLE*)id)=CreateEvent(NULL,TRUE,FALSE,NULL); #endif } Event::~Event() { Log odinlog("Event","~Event"); if(id) { #ifdef USE_PTHREADS int errcode=pthread_cond_destroy((pthread_cond_t*)id); if(errcode) ODINLOG(odinlog,errorLog) << pthread_err(errcode) << STD_endl; delete (pthread_cond_t*)id; #endif #ifdef USE_WINTHREADS CloseHandle(*((HANDLE*)id)); delete (HANDLE*)id; #endif } } void Event::wait() { Log odinlog("Event","wait"); #ifdef USE_PTHREADS MutexLock lock(mutex); while(!active) { int errcode=pthread_cond_wait((pthread_cond_t*)id, (pthread_mutex_t*)(mutex.id)); if(errcode) { ODINLOG(odinlog,errorLog) << pthread_err(errcode) << STD_endl; break; } } #endif #ifdef USE_WINTHREADS WaitForSingleObject(*((HANDLE*)id), INFINITE); #endif } void Event::signal() { Log odinlog("Event","signal"); #ifdef USE_PTHREADS MutexLock lock(mutex); active=true; int errcode=pthread_cond_broadcast((pthread_cond_t*)id); if(errcode) ODINLOG(odinlog,errorLog) << pthread_err(errcode) << STD_endl; #endif #ifdef USE_WINTHREADS SetEvent(*((HANDLE*)id)); #endif } void Event::reset() { Log odinlog("Event","reset"); #ifdef USE_PTHREADS MutexLock lock(mutex); active=false; #endif #ifdef USE_WINTHREADS ResetEvent(*((HANDLE*)id)); #endif } //////////////////////////////////////////////////////////////////// // pthread_t cannot be converted to an integer on all platforms (e.g. Darwin) so we need a separate map #ifdef USE_PTHREADS static STD_map pthreadindexmap; static Mutex pthreadindexmutex; struct ThreadIndex : public UniqueIndex { // functions for UniqueIndex static const char* get_typename() {return "ThreadIndex";} static unsigned int get_max_instances() {return 0;} }; #endif ////////////////////////// #ifdef USE_WINTHREADS DWORD WINAPI start_thread(LPVOID t) { #else void* start_thread(void* t) { #endif ((Thread*)t)->run(); return 0; } ////////////////////////// Thread::Thread() : id(0) { #ifdef USE_PTHREADS index=new ThreadIndex; #endif } Thread::~Thread() { clear_id(); #ifdef USE_PTHREADS delete index; #endif } void Thread::clear_id() { if(id) { #ifdef USE_PTHREADS delete ((pthread_t*)id); #endif #ifdef USE_WINTHREADS delete ((HANDLE*)id); #endif } id=0; } bool Thread::start(unsigned int stack_size) { Log odinlog("Thread","start"); wait(); // will clear id #ifdef USE_PTHREADS id=(void*)new pthread_t; pthread_attr_t pt_attr; int errcode=pthread_attr_init (&pt_attr); if(errcode) { ODINLOG(odinlog,errorLog) << "pthread_attr_init: " << pthread_err(errcode) << STD_endl; return false; } if(stack_size) { errcode=pthread_attr_setstacksize (&pt_attr, stack_size); if(errcode) { ODINLOG(odinlog,errorLog) << "pthread_attr_setstacksize: " << pthread_err(errcode) << STD_endl; return false; } } errcode=pthread_create((pthread_t*)id, &pt_attr, &start_thread, this); if(errcode) { ODINLOG(odinlog,errorLog) << "pthread_create: " << pthread_err(errcode) << STD_endl; #ifdef HAVE_SYSCONF ODINLOG(odinlog,errorLog) << "PTHREAD_THREADS_MAX=" << sysconf(_SC_THREAD_THREADS_MAX) << STD_endl; #endif return false; } pthreadindexmutex.lock(); // lock because other threads might already be running pthreadindexmap[index->get_index()]=*((pthread_t*)id); pthreadindexmutex.unlock(); #else #ifdef USE_WINTHREADS HANDLE* handle=new HANDLE; (*handle)=CreateThread(NULL,stack_size,&start_thread,this,0,NULL); id=(void*)handle; if(*handle==NULL) { ODINLOG(odinlog,errorLog) << "CreateThread: " << lasterr() << STD_endl; return false; } #else this->run(); // no threads #endif #endif return true; } bool Thread::wait() { Log odinlog("Thread","wait"); #ifdef USE_PTHREADS int errcode=0; if(id) { void* returnval; errcode=pthread_join(*((pthread_t*)id), &returnval); ODINLOG(odinlog,normalDebug) << "errcode=" << errcode << STD_endl; } clear_id(); if(errcode) { ODINLOG(odinlog,errorLog) << pthread_err(errcode) << STD_endl; return false; } #endif #ifdef USE_WINTHREADS if(id) { DWORD errcode=WaitForSingleObject(*((HANDLE*)id),INFINITE); clear_id(); if(errcode==WAIT_FAILED) { ODINLOG(odinlog,errorLog) << lasterr() << STD_endl; return false; } } #endif return true; } int Thread::self() { Log odinlog("Thread","self"); int result=-1; // the master thread gets this id #ifdef USE_PTHREADS pthread_t ptself=pthread_self(); pthreadindexmutex.lock(); for(STD_map::const_iterator it=pthreadindexmap.begin(); it!=pthreadindexmap.end(); ++it) { if(pthread_equal(ptself, it->second)) result=it->first; } pthreadindexmutex.unlock(); #endif #ifdef USE_WINTHREADS result=GetCurrentThreadId(); #endif return result; } //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST #include "tjvector.h" #define VECSIZE 256 #define NITER 10000 #define NTHREADS 16 class TestThread : public Thread { public: void init(int* v, Mutex* m) { vec=v; mutex=m; } protected: void run() { for(int i=0; isignal(); } private: double* res; Event* event; int delay; }; ////////////////////////////////////////////// class TestEventThread2 : public Thread { public: void init(double* r, Event* e, int d) { res=r; event=e; delay=d; } protected: void run() { sleep_ms(delay); (*res)=123.4; event->wait(); } private: double* res; Event* event; int delay; }; ////////////////////////////////////////////// class ThreadedLoopTest : public ThreadedLoop { private: bool kernel(const STD_string& in, STD_string& out, int&, unsigned int begin, unsigned int end) { out=""; for(unsigned int i=begin; i odinlog(this,"check"); /////////////////////////////////// // Testing Thread / MutexLock TestThread thread[NTHREADS]; Mutex mutex; int vec[VECSIZE]; for(int ivec=0; ivec /** * @addtogroup tjutils * @{ */ /** * This is the base class for all classes which can have a (unique) label */ class Labeled { public: /** * Constructor with initialization of label */ Labeled(const STD_string& label="unnamed") : objlabel(label) {} /** * Assigns a label to the object */ Labeled& set_label(const STD_string& label) {objlabel=label; return *this;} /** * Returns the label of the object */ const STD_string& get_label() const {return objlabel;} /** * Assignment operator */ Labeled& operator = (const Labeled& l) { objlabel=l.objlabel; return *this; } private: STD_string objlabel; }; /** @} */ #endif odin-1.8.5/tjutils/tjtools.cpp0000644000175000017500000004707611322062342013310 00000000000000#include "tjtools.h" #include "tjutils.h" #include "tjcstd.h" #include "tjlog.h" #include "tjlog_code.h" #include "tjstring.h" #include "tjtest.h" #include "tjvector.h" // for testing browse_dir #include #ifdef HAVE_UNISTD_H #include #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_DIRENT_H #include #endif #ifdef USING_WIN32 #include #include #include #endif #ifdef HAVE_TIME_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif // for mmap #ifdef HAVE_SYS_MMAN_H #include #include #endif class TjTools { public: static const char* get_compName() {return "tjtools";} }; LOGGROUNDWORK(TjTools) //////////////////////////////////////////////////////////////////// double norm (double x, double y) { double result; result = sqrt (x * x + y * y); return (result); } ///////////////////////////////////////////////////////////// double norm3 (double x, double y, double z) { double result; result = sqrt (x * x + y * y + z * z); return (result); } ///////////////////////////////////////////////////////////// double maxof3(double f1,double f2,double f3) { double result =0.0; if (f1>=f2) result=f1; else result=f2; if (result>=f3) return(result); else return(f3); } ///////////////////////////////////////////////////////////// double secureDivision(double numerator, double denominator) { if(denominator==0.0) return 0.0; return numerator/denominator; } ///////////////////////////////////////////////////////////// const char* secure_getenv(const char* variable_name) { Log odinlog("","secure_getenv"); const char* result=""; const char* env=getenv(variable_name); if(env) result=env; ODINLOG(odinlog,normalDebug) << "result(" << variable_name << ")=" << result << STD_endl; return result; } ///////////////////////////////////////////////////////////// bool little_endian_byte_order() { int one_bit_set_in_least_significant=1; unsigned char* first_byte=(unsigned char*)&one_bit_set_in_least_significant; return (*first_byte)!=0; } ///////////////////////////////////////////////////////////// unsigned int numof_cores() { unsigned int result=1; #ifdef USING_WIN32 SYSTEM_INFO sysinfo; GetSystemInfo( &sysinfo ); result = sysinfo.dwNumberOfProcessors; #else #if defined(HAVE_UNISTD_H) && defined(HAVE_SYSCONF) #ifdef _SC_NPROCESSORS_ONLN result=sysconf(_SC_NPROCESSORS_ONLN); #endif #endif #endif return result; } ///////////////////////////////////////////////////////////// #ifndef NO_FILEHANDLING const char* modestring(fopenMode mode) { if(mode==readMode) return "rb"; if(mode==overwriteMode) return "w+b"; if(mode==appendMode) return "a+b"; return ""; } LONGEST_INT filesize(const char *filename) { Log odinlog("","filesize"); LONGEST_INT result=-1; #ifdef STAT struct STAT st; if(!STAT(filename, &st)) result=st.st_size; else if(errno!=ENOENT) ODINLOG(odinlog,errorLog) << "stat(" << filename << "): " << lasterr() << STD_endl; #else FILE *file_ptr; file_ptr = FOPEN(filename, modestring(readMode)); if(file_ptr == NULL) { if(errno!=ENOENT) ODINLOG(odinlog,errorLog) << "fopen(" << filename << "): " << lasterr() << STD_endl; return result; } if(fgetc(file_ptr) != EOF) { if(fseek(file_ptr, 0, SEEK_END)) { if(errno!=ENOENT) ODINLOG(odinlog,errorLog) << "fseek(" << filename << "): " << lasterr() << STD_endl; } else result=FTELL(file_ptr); } fclose(file_ptr); #endif return result; } ///////////////////////////////////////////////////////////// char getpwd_buff[ODIN_MAXCHAR]; const char* getpwd() { Log odinlog("","getpwd"); const char* result=""; #ifdef USING_WIN32 result=_getcwd(getpwd_buff,ODIN_MAXCHAR); #else #ifdef HAVE_UNISTD_H result=getcwd(getpwd_buff,ODIN_MAXCHAR); #endif #endif if(result==NULL) ODINLOG(odinlog,errorLog) << lasterr() << STD_endl; return result; } ///////////////////////////////////////////////////////////// int chpwd(const char *dirname) { Log odinlog("","chpwd"); int result=0; #ifdef USING_WIN32 result=_chdir(dirname); // will consider drive letter #else #ifdef HAVE_UNISTD_H result=chdir(dirname); #endif #endif if(result<0) ODINLOG(odinlog,errorLog) << "(" << dirname << ")" << lasterr() << STD_endl; return result; } ///////////////////////////////////////////////////////////// int createdir(const char *dirname) { Log odinlog("","createdir"); int result=0; if(checkdir(dirname)) return result; // already there #ifdef USING_WIN32 result=_mkdir(dirname); ODINLOG(odinlog,normalDebug) << "created USING_WIN32 dir" << dirname << STD_endl; #else #if defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_TYPES_H) && defined(HAVE_UNISTD_H) result=mkdir(dirname, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); // permission: 0755 #endif #endif if(result<0) ODINLOG(odinlog,errorLog) << "(" << dirname << ") " << lasterr() << STD_endl; return result; } ///////////////////////////////////////////////////////////// bool checkdir(const char *dirname) { Log odinlog("","checkdir"); #ifdef USING_WIN32 _finddata_t fileinfo; STD_string dirmatch=STD_string(dirname)+"\\*"; long findhandle=_findfirst(dirmatch.c_str(), &fileinfo ); if(findhandle!=-1) { _findclose(findhandle); return true; } else { ODINLOG(odinlog,normalDebug) << "(" << dirname << ") " << lasterr() << STD_endl; } #else #ifdef HAVE_DIRENT_H DIR* dp = opendir(dirname); if (dp != NULL) { closedir(dp); return true; } #endif #endif return false; } ///////////////////////////////////////////////////////////// int movefile(const char *src, const char* dst) { int result=0; #ifdef USING_WIN32 result=rename(src,dst); #else result=system((STD_string("mv ")+src+" "+dst).c_str()); // rename() does not work across filesystems #endif return result; } ///////////////////////////////////////////////////////////// int copyfile(const char *src, const char* dst) { Log odinlog("","copyfile"); int result=0; #ifdef USING_WIN32 if(!CopyFileA(src,dst,FALSE)) result=-1; #else result=system((STD_string("cp ")+src+" "+dst).c_str()); #endif if(result<0) ODINLOG(odinlog,errorLog) << "(" << src << "," << dst << ") " << lasterr() << STD_endl; return result; } ///////////////////////////////////////////////////////////// int rmfile(const char *fname) { Log odinlog("","rmfile"); int result=0; if(filesize(fname)<0) return 0; #ifdef USING_WIN32 if(checkdir(fname)) { result=_rmdir(fname); if(result<0) ODINLOG(odinlog,errorLog) << "_rmdir(" << fname << ") " << lasterr() << STD_endl; } else { result=remove(fname); if(result<0) ODINLOG(odinlog,errorLog) << "remove(" << fname << ") " << lasterr() << STD_endl; } #else result=remove(fname); // Works for both, files and directories if(result<0) ODINLOG(odinlog,errorLog) << "(" << fname << ") " << lasterr() << STD_endl; #endif return result; } ///////////////////////////////////////////////////////////// int chperm(const char *fname, int perm) { #ifdef USING_WIN32 return _chmod(fname,perm); #else #if defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_TYPES_H) && defined(HAVE_UNISTD_H) return chmod(fname,perm); #endif #endif return 0; } ///////////////////////////////////////////////////////////// #define BLOCKSIZE 4096 // constant experession needed for VC++ 6 int create_empty_file(const STD_string& filename, LONGEST_INT nbytes, fopenMode mode) { Log odinlog("","create_empty_file"); LONGEST_INT nblocks=nbytes/BLOCKSIZE; LONGEST_INT rest=nbytes%BLOCKSIZE; char buff[BLOCKSIZE]; LONGEST_INT i; for(i=0; i odinlog("","offset_pagesize"); result_offset=offset; result_rest=0; #ifdef HAVE_UNISTD_H int psize=getpagesize(); if(psize) { result_offset=(offset/psize)*psize; result_rest=offset%psize; } #endif ODINLOG(odinlog,normalDebug) << "offset/result_offset/result_rest=" << offset << "/" << result_offset << "/" << result_rest << STD_endl; } #endif /////////////////////////////////////////////// void* filemap(const STD_string& filename, LONGEST_INT nbytes, LONGEST_INT offset, bool readonly, int& fd) { Log odinlog("","filemap"); void* result=0; fd=-1; LONGEST_INT fsize=filesize(filename.c_str()); LONGEST_INT total=nbytes+offset; ODINLOG(odinlog,normalDebug) << "nbytes/fsize/total/readonly = " << nbytes << "/" << fsize << "/" << total << "/" << readonly << STD_endl; // check size in readonly mode if(readonly) { if(fsize" << filename << "<" << STD_endl; return result; } } } #ifdef HAVE_SYS_MMAN_H // The Unix (mmap) way of file mapping ODINLOG(odinlog,normalDebug) << "Using mmap" << STD_endl; LONGEST_INT offset_psize; int rest_psize; offset_pagesize(offset, offset_psize, rest_psize); int flags=O_RDWR; if(readonly) flags=O_RDONLY; fd = OPEN( filename.c_str(), flags ); ODINLOG(odinlog,normalDebug) << "fd = " << fd << STD_endl; if (fd < 0) { ODINLOG(odinlog,errorLog) << "unable to open file >" << filename << "< - " << lasterr() << STD_endl; return result; } if(filesize(filename.c_str())" << filename << "< to small for filemap" << STD_endl; close(fd); fd=-1; return result; } int prot=PROT_READ | PROT_WRITE; if(readonly) prot=PROT_READ; char* byte_ptr=(char*)MMAP( 0, nbytes+rest_psize, prot, MAP_SHARED, fd, offset_psize ); if ( byte_ptr==MAP_FAILED ) { ODINLOG(odinlog,errorLog) << "Cannot filemap file >" << filename << "< - " << lasterr() << STD_endl; close(fd); fd=-1; return 0; } result=byte_ptr+rest_psize; #else // Emulate mmap by allocating memory and reading it from file ODINLOG(odinlog,normalDebug) << "Using fread" << STD_endl; const char* modeString=modestring(overwriteMode); if(readonly) modeString=modestring(readMode); fd=(int)FOPEN(filename.c_str(), modeString); if(!fd) { ODINLOG(odinlog,errorLog) << "fopen: " << lasterr() << STD_endl; return result; } if(offset>0) { if(FSEEK((FILE*)fd, offset, SEEK_SET)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; fclose((FILE*)fd); return result; } } result=(void*)new char[nbytes]; fread( result, nbytes, sizeof(char), (FILE*)fd); if(readonly) { // We close and reset the file pointer here so that fileunmap() knows that the file is readonly fclose((FILE*)fd); fd=0; // Zero indicates readonly mode } #endif return result; } /////////////////////////////////////////////// void fileunmap(int fd, void* start, LONGEST_INT nbytes, LONGEST_INT offset) { Log odinlog("","fileunmap"); ODINLOG(odinlog,normalDebug) << "fd/start/length=" << fd << "/" << start << "/" << nbytes << STD_endl; #ifdef HAVE_SYS_MMAN_H // The Unix (mmap) way of file mapping LONGEST_INT offset_psize; int rest_psize; offset_pagesize(offset, offset_psize, rest_psize); void* mstart=(char*)start-rest_psize; LONGEST_INT mlength=nbytes+rest_psize; if ( msync(mstart, mlength, MS_SYNC) ) ODINLOG(odinlog,errorLog) << "msync: " << lasterr() << STD_endl; if ( munmap(mstart, mlength) ) ODINLOG(odinlog,errorLog) << "munmap: " << lasterr() << STD_endl; close(fd); #else // Emulate munmap by writing memory to file, de-allocating memory and closing the file if(fd>0) { // File is mapped with read/write access if(offset>0) { if(FSEEK((FILE*)fd, offset, SEEK_SET)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; fclose((FILE*)fd); delete[] (char*)start; return; } } if(!fwrite(start, sizeof(char), nbytes, (FILE*)fd)) { ODINLOG(odinlog,errorLog) << "fwrite: " << lasterr() << STD_endl; } fclose((FILE*)fd); } delete[] (char*)start; #endif } /////////////////////////////////////////////// STD_string tempfile() { STD_string result; const char* ptr=tmpnam(NULL); if(ptr) result=ptr; #ifdef USING_WIN32 result=STD_string(secure_getenv("TEMP"))+SEPARATOR_STR+result; #endif return result; } #endif // #ifndef NO_FILEHANDLING ///////////////////////////////////////////////////////////// const char* lasterr() { #ifdef USING_WIN32 LPVOID msgbuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &msgbuf, 0, NULL); static STD_string result=(const char *)msgbuf; LocalFree(msgbuf); return result.c_str(); #else #ifdef HAVE_UNISTD_H return strerror(errno); #endif #endif return ""; } ///////////////////////////////////////////////////////////// void sleep_ms(unsigned int ms) { if(!ms) return; #ifdef USING_WIN32 Sleep(ms); #else #if defined(HAVE_TIME_H) && defined(HAVE_NANOSLEEP) timespec ts; ts.tv_sec=ms/1000; ts.tv_nsec=(ms%1000)*1000000; nanosleep(&ts,NULL); #endif #endif } ///////////////////////////////////////////////////////////// double current_time_s() { Log odinlog("","current_time_s"); double result=-1; #ifdef USING_WIN32 FILETIME ft; GetSystemTimeAsFileTime(&ft); SYSTEMTIME currenttime; if(!FileTimeToSystemTime(&ft,¤ttime)) { ODINLOG(odinlog,errorLog) << lasterr() << STD_endl; return result; } result=3600.0*double(currenttime.wHour) + 60.0*double(currenttime.wMinute) + double(currenttime.wSecond) + 1e-3*double(currenttime.wMilliseconds); #else #if defined(HAVE_SYS_TIME_H) && defined(HAVE_TIME_H) && defined(HAVE_GETTIMEOFDAY) timeval currenttime; gettimeofday(¤ttime,0); result=double(currenttime.tv_sec) + 1e-6*double(currenttime.tv_usec); #endif #endif return result; } ////////////////////////////////////////////////////////// #ifndef NO_CMDLINE int getCommandlineOption(int argc, char *argv[], const char *option, char *returnvalue, int maxchar,bool modify) { int i,b=0; for (i=1;i1) { /* if( *argv[argc-2]!='-') { */ strncpy(returnvalue,argv[argc-1],maxchar-1);returnvalue[maxchar-1]='\0'; if(modify) argv[argc-1][0]='\0'; return(1); /* } */ } return(0); } int hasHelpOption(int argc, char *argv[]) { if(isCommandlineOption(argc,argv,"--version")) { STD_cout << VERSION << STD_endl; exit(0); // return immediately for help2man } return isCommandlineOption(argc,argv,"-h")+ isCommandlineOption(argc,argv,"--help")+ isCommandlineOption(argc,argv,"-help"); } const char* helpUsage() { return "-h, --help, -help, --version : Print help text or version information"; } #endif ////////////////////////////////////////////////////////////////////////////////////////////// // From GSL, i.e. from gsl_sf_bessel_j0() double sinc(double x) { if(x==0.0) return 1.0; if(fabs(x) < 0.5) { const double y = x*x; const double c1 = -1.0/6.0; const double c2 = 1.0/120.0; const double c3 = -1.0/5040.0; const double c4 = 1.0/362880.0; const double c5 = -1.0/39916800.0; const double c6 = 1.0/6227020800.0; return 1.0 + y*(c1 + y*(c2 + y*(c3 + y*(c4 + y*(c5 + y*c6))))); } else { return sin(x)/x; } } ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class TjToolsTest : public UnitTest { public: TjToolsTest() : UnitTest(TjTools::get_compName()) {} private: bool check() const { Log odinlog(this,"check"); #ifndef NO_FILEHANDLING STD_string dir(tempfile()); if(createdir(dir.c_str())) { ODINLOG(odinlog,errorLog) << "createdir failed" << STD_endl; return false; } STD_string testcont="content"; STD_string srcfile=dir+SEPARATOR_STR+"src"; if(write(testcont, srcfile)) { ODINLOG(odinlog,errorLog) << "write failed" << STD_endl; return false; } int ntestfiles=5; for(int i=0; i #include /** * @addtogroup tjutils * @{ */ /** * Returns the complex number 'z' as a formatted string */ STD_string ctos(const STD_complex& z); /** * Parses an returns string 's' as complex number */ STD_complex stoc(const STD_string& s); //////////////////////////////////////////////////////////// // functions for using complex numbers with Blitz++, // even if the STD_complex class is not std::complex inline STD_complex float2real(float a) {return STD_complex(a,0.0f);} inline STD_complex float2imag(float b) {return STD_complex(0.0f,b);} inline float creal(STD_complex c) {return c.real();} inline float cimag(STD_complex c) {return c.imag();} inline float cabs(STD_complex c) {return float(sqrt(c.real()*c.real()+c.imag()*c.imag()));} //{return STD_abs(c);} // std::abs produces inf with GCC4 on amd64 inline float phase(STD_complex c) {return STD_arg(c);} inline STD_complex logc(STD_complex c) {return STD_log(c);} inline STD_complex expc(STD_complex c) {return STD_exp(c);} inline STD_complex conjc(STD_complex c) {return STD_conj(c);} /** * Comparison operator for the norm of the complex numbers c1 and c2 */ inline bool operator < (const STD_complex& c1, const STD_complex& c2) {return STD_abs(c1) (const STD_complex& c1, const STD_complex& c2) {return STD_abs(c1)>STD_abs(c2);} /** @} */ #endif odin-1.8.5/tjutils/tjvector.cpp0000644000175000017500000005170311712547771013463 00000000000000#include "tjvector.h" #include "tjtypes.h" #include "tjtest.h" #include "tjlog_code.h" // required for interpolation #ifdef HAVE_LIBGSL #include #include #else #include "replacements/gsl_replacement.cpp" #endif #ifdef HAVE_DIRENT_H #include #endif #ifdef USING_WIN32 #include #endif const char* VectorComp::get_compName() {return "vector";} LOGGROUNDWORK(VectorComp) ///////////////////////////////////////////////////////////////////////////////////////////////////////////// fvector real(const cvector& cv) { unsigned int n=cv.size(); fvector result(n); for (unsigned int i=0; i odinlog("","tokens"); svector result; const int n=tokenstring.length(); STD_string sepstr(" "); if(custom_separator) sepstr[0]=custom_separator; // fill the list with the tokens int beginpos=0; int endpos; STD_string onetoken; int beginquote=0; int endquote=0; while(beginpos>=0 && beginpos =0 && endpos>=0) { STD_string substring(tokenstring.substr(beginpos,endpos-beginpos)); beginquote+=noccur(substring,STD_string(1,escape_begin)); endquote+=noccur(substring,STD_string(1,escape_end)); onetoken+=substring; bool token_complete=true; if( (escape_begin==escape_end) && (beginquote%2) ) token_complete=false; if( (escape_begin!=escape_end) && (beginquote>endquote) ) token_complete=false; if(token_complete) { result.push_back(onetoken); onetoken=""; beginquote=endquote=0; } else { onetoken+=sepstr; } } beginpos=endpos; } return result; } //////////////////////////////////////// STD_string tokenstring(const svector& tokens,unsigned int linewidth) { Log odinlog("","tokenstring"); unsigned int stringsize=0; unsigned int n=tokens.size(); ODINLOG(odinlog,normalDebug) << "creating string from " << n << " tokens" << STD_endl; ODINLOG(odinlog,normalDebug) << "linewidth = " << linewidth << STD_endl; unsigned int i; for(i=0;i result; bool success=true; #ifdef USING_WIN32 // browse directory the Windows way _finddata_t fileinfo; STD_string files_match=dirname+"\\*"; long findhandle=_findfirst(files_match.c_str(), &fileinfo ); if(findhandle==-1) { ODINLOG(odinlog,normalDebug) << "(" << dirname << ") " << lasterr() << STD_endl; success=false; } while(findhandle!=-1) { STD_string curr_file(fileinfo.name); bool store=true; if(only_dirs) { if(fileinfo.attrib!=_A_SUBDIR) store=false; } if(discard_dotfiles) { if(curr_file[(unsigned int)0]=='.') store=false; } if(store) result.push_back(curr_file); if(_findnext(findhandle, &fileinfo )==-1) { _findclose(findhandle); findhandle=-1; } } #else #ifdef HAVE_DIRENT_H // browse directory the UNIX way struct dirent *ep; DIR* dp = opendir(dirname.c_str()); if (dp != NULL) { while ( (ep = readdir (dp)) ) { STD_string curr_file(ep->d_name); bool store=true; if(only_dirs && ep->d_type!=DT_DIR) store=false; if(discard_dotfiles) { if(curr_file[(unsigned int)0]=='.') store=false; } if(store) result.push_back(curr_file); } closedir (dp); } else success=false; #endif #endif if(!success) { ODINLOG(odinlog,errorLog) << "Couldn't open directory >" << dirname << "< - " << lasterr() << STD_endl; } result.sort(); return list2vector(result); } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// STD_string svector::printbody() const { STD_string result; for(unsigned int i=0; i odinlog("tjvector","interpolate1D(complex)"); unsigned int i; STD_complex* newdata=new STD_complex[newsize]; for(i=0; i simple adding blocks unsigned int blocksize=oldsize/newsize; ODINLOG(odinlog,normalDebug) << "blocksize=" << blocksize << STD_endl; for(unsigned int inew=0; inew=3) itype=gsl_interp_cspline; // for few points if(oldsize>=5) itype=gsl_interp_akima; // this seems to be the best algorithm for non-smooth data gsl_spline *spline_re = gsl_spline_alloc (itype, oldsize); gsl_spline *spline_im = gsl_spline_alloc (itype, oldsize); gsl_spline_init (spline_re, x, data_re, oldsize); gsl_spline_init (spline_im, x, data_im, oldsize); for(i=0; imaxold) newx=maxold; float re=gsl_spline_eval (spline_re, newx, acc_re); float im=gsl_spline_eval (spline_im, newx, acc_im); newdata[i]=STD_complex(re,im); } gsl_spline_free (spline_re); gsl_spline_free (spline_im); gsl_interp_accel_free(acc_re); gsl_interp_accel_free(acc_im); delete[] x; delete[] data_re; delete[] data_im; // Deal with edge effects, i.e. coordinates outside the old range at the edges if(subpixel_shift==0.0) { int nedge=int(0.5*secureDivision(newsize,oldsize)+0.5); if(nedge>0 && nedge=0 && isrc=0 && idst=0 && isrc=0 && idst odinlog("tjvector","interpolate1D(float)"); STD_complex* oldcomplexdata=new STD_complex[oldsize]; unsigned int i; for(i=0;i odinlog("tjvector","interpolate1D(double)"); STD_complex* oldcomplexdata=new STD_complex[oldsize]; unsigned int i; for(i=0;i odinlog("tjvector","interpolate1D(int)"); STD_complex* oldcomplexdata=new STD_complex[oldsize]; unsigned int i; for(i=0;i tjvector::tjvector(unsigned int n) : STD_vector(n, T(0)) { Log odinlog("tjvector","tjvector(unsigned int)"); ODINLOG(odinlog,normalDebug) << "n=" << n << STD_endl; c_array_cache=0; } template tjvector::tjvector(const T *array, unsigned int n) : STD_vector() { STD_vector::resize(n); set_c_array((unsigned char*)array,n); c_array_cache=0; } template tjvector::tjvector(const STD_vector& v) : STD_vector(v) { c_array_cache=0; } template tjvector::tjvector(const tjvector& tv) : STD_vector(tv) { c_array_cache=0; } template tjvector::~tjvector() { Log odinlog("tjvector","~tjvector"); if(c_array_cache) { ODINLOG(odinlog,normalDebug) << "deleting c_array_cache=" << (void*)c_array_cache << STD_endl; delete[] c_array_cache; } } template tjvector& tjvector::resize(unsigned int newsize) { Log odinlog("tjvector","resize"); unsigned int oldsize=STD_vector::size(); if(newsize==oldsize) return *this; STD_vector old(*this); STD_vector::resize(newsize); for(unsigned int i=0; i unsigned int tjvector::length () const {return STD_vector::size();} template unsigned int tjvector::fill_linear(const T& min,const T& max) { if ((length()-1)==0) tjvector::operator = (min); else { T incr=(max-min)/(T)(length()-1); for(unsigned int i=0;i T tjvector::sum() const { Log odinlog("","sum"); T result=T(0); ODINLOG(odinlog,normalDebug) << "initial value=" << result << STD_endl; for(unsigned int i=0;i::begin(),STD_vector::end(),value); #endif return *this; } template tjvector& tjvector::operator = (const STD_vector& vec) { STD_vector::operator = (vec); return *this; } template tjvector& tjvector::operator = (const tjvector& tv) { Log odinlog("tjvector","operator = (const tjvector&)"); STD_vector::operator = (tv); return *this; } template STD_string tjvector::printbody() const { unsigned int n=length(); svector tokens; tokens.resize(n); for(unsigned int i=0;i T tjvector::maxvalue() const { if(!length()) return T(0); T result=(*this)[0]; for(unsigned int i=1;iresult) result=(*this)[i]; return result; } template T tjvector::minvalue() const { if(!length()) return T(0); T result=(*this)[0]; for(unsigned int i=1;i const T* tjvector::c_array() const { Log odinlog("tjvector","c_array"); if(c_array_cache) { ODINLOG(odinlog,normalDebug) << "deleting c_array_cache=" << (void*)c_array_cache << STD_endl; delete[] c_array_cache; c_array_cache=0; } c_array_cache=new T[length()]; ODINLOG(odinlog,normalDebug) << "allocated c_array_cache=" << (void*)c_array_cache << STD_endl; for(unsigned int i=0;i tjvector& tjvector::set_c_array(const unsigned char* array, unsigned int n) { Log odinlog("tjvector","set_c_array"); if(length()==n) { for(unsigned int i=0;i T tjvector::maxabs() const{ return T(STD_max(cabs(minvalue()),cabs(maxvalue()))); } template T tjvector::normalize() { Log odinlog("tjvector","normalize"); T maxnorn=maxabs(); ODINLOG(odinlog,normalDebug) << "maxnorn=" << maxnorn << STD_endl; if(!(maxnorn==T(0))) (*this)/=maxnorn; return maxnorn; } template tjvector& tjvector::interpolate(unsigned int newsize, float subpixel_shift) { Log odinlog("tjvector","interpolate"); unsigned int oldsize=length(); ODINLOG(odinlog,normalDebug) << "oldsize/newsize/subpixel_shift=" << oldsize << "/" << newsize << "/" << subpixel_shift << STD_endl; T* olddata=new T[oldsize]; unsigned int i; for(i=0;i int tjvector::load(const STD_string& fname) { Log odinlog("tjvector","load"); #ifndef NO_FILEHANDLING if(fname=="") return 0; LONGEST_INT fsize=filesize(fname.c_str()); LONGEST_INT nelements=fsize/sizeof(T); FILE* file_ptr=FOPEN(fname.c_str(),modestring(readMode)); if(file_ptr==NULL) { ODINLOG(odinlog,errorLog) << "unable to open file >" << fname << "<, " << lasterr() << STD_endl; return(-1); } if((LONGEST_INT)STD_vector::size() != nelements) resize(nelements); T* buff=new T[nelements]; if(fread(buff,sizeof(T),nelements,file_ptr)!=nelements) { ODINLOG(odinlog,errorLog) << "unable to read data from file >" << fname << "<, " << lasterr() << STD_endl; } else { (*this)=tjvector(buff,nelements); } if(file_ptr!=NULL) fclose(file_ptr); delete[] buff; #endif return 0; } template int tjvector::write(const STD_string& fname, fopenMode mode, LONGEST_INT nelements) const { Log odinlog("tjvector","write"); #ifndef NO_FILEHANDLING if(fname=="") return 0; if(nelements>(LONGEST_INT)(length()) || nelements<0) { nelements=length(); } FILE* file_ptr=FOPEN(fname.c_str(),modestring(mode)); if(file_ptr==NULL) { ODINLOG(odinlog,errorLog) << "unable to create/open file >" << fname << "<, " << lasterr() << STD_endl; return(-1); } if(fwrite(c_array(),sizeof(T),nelements,file_ptr)!=nelements) { ODINLOG(odinlog,errorLog) << "unable to write data to file >" << fname << "<, " << lasterr() << STD_endl; } if(file_ptr!=NULL) fclose(file_ptr); #endif return 0; } ///////////////////////////////////////////////////////////////////////////////////////////////////////////// template class tjvector; template class tjvector; template class tjvector; template class STD_vector; template class tjvector; #ifndef NO_UNIT_TEST class VectorTest : public UnitTest { public: VectorTest() : UnitTest(VectorComp::get_compName()) {} private: bool check() const { Log odinlog(this,"check"); // Test sum() ivector iv1(2); iv1[0]=1; iv1[1]=3; ivector iv2(2); iv2[0]=2; iv2[1]=4; int calculated=(iv1+iv2).sum(); int expected=10; if(calculated!=expected) { ODINLOG(odinlog,errorLog) << "sum(): calculated/expected=" << calculated << "/" << expected << STD_endl; return false; } // Test interpolation by converting high-res sine to and from low-res version int srcsize=1000; fvector srcvec(srcsize); for(int i=0; i0.005*srcsize) { // No more than 0.5% on average ODINLOG(odinlog,errorLog) << "interpolate(): absdiff=" << absdiff << STD_endl; return false; } // Test tokenizer svector gottoks=tokens("aa_bbb__eee", '_', '<', '>'); svector exptoks; exptoks.resize(4); exptoks[0]="aa"; exptoks[1]="bbb"; exptoks[2]=""; exptoks[3]="eee"; if(gottoks!=exptoks) { ODINLOG(odinlog,errorLog) << "tokens: got/expected=" << gottoks.printbody() << "/" << exptoks.printbody() << STD_endl; return false; } return true; } }; void alloc_VectorTest() {new VectorTest();} // create test instance #endif odin-1.8.5/tjutils/tjtypes.cpp0000644000175000017500000000146311713467630013317 00000000000000#include "tjtypes.h" unsigned int TypeTraits::typesize(const STD_string& typelabel) { if(typelabel==TypeTraits::type2label((u8bit)0)) return 1; if(typelabel==TypeTraits::type2label((s8bit)0)) return 1; if(typelabel==TypeTraits::type2label((u16bit)0)) return 2; if(typelabel==TypeTraits::type2label((s16bit)0)) return 2; if(typelabel==TypeTraits::type2label((u32bit)0)) return 4; if(typelabel==TypeTraits::type2label((s32bit)0)) return 4; if(typelabel==TypeTraits::type2label((float)0)) return sizeof(float); if(typelabel==TypeTraits::type2label((double)0)) return sizeof(double); if(typelabel==TypeTraits::type2label((STD_complex)0)) return sizeof(STD_complex); // if(typelabel==TypeTraits::type2label(STD_string(""))) return sizeof(STD_string); // string does not have fixed size return 0; } odin-1.8.5/tjutils/tjprofiler.h0000644000175000017500000000513711322062342013427 00000000000000/*************************************************************************** tjprofiler.h - description ------------------- begin : Mon Aug 5 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJPROFILER_H #define TJPROFILER_H #include #include #include #include /** * @addtogroup tjutils * @{ */ /** * A class to profile your program, i.e. to see how much time is spent * in each function. Create a local object of this class in each function * you want to analyze with the functions name as the constructors argument. * The function name serves as a key to measure the execution time in * each function if this function is called successively. * the result of can be obtained by the 'dump_final_result()' function. * In addition, a function is provided to retrieve the current memory usage. */ class Profiler : public StaticHandler { public: Profiler(const STD_string& func_name); ~Profiler(); /** * Resets the time counters. */ static void reset(); /** * Dumps the results to the current log and resets the time counters. */ static void dump_final_result(); /** * Returns the current memory usage as a readable string. */ static STD_string get_memory_usage(); // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); // for debugging List static const char* get_compName(); private: STD_string func_label; double starttime; struct elapsed { elapsed() : time_spent(0.0) {} double time_spent; }; struct FuncMap : public STD_map, public Labeled {}; static SingletonHandler func_map; }; /** @} */ #endif odin-1.8.5/tjutils/tjembed.h0000644000175000017500000000473511322062342012664 00000000000000/*************************************************************************** tjembed.h - description ------------------- begin : Tue Mar 11 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJEMBED_H #define TJEMBED_H #include /** * @addtogroup tjutils * @{ */ template class Embed { public: Embed() {} ~Embed() { clear_instances(); } void clear_instances() { for(typename STD_list::iterator it=instances.begin();it!=instances.end();++it) delete (*it); instances.clear(); } T& set_embed_body (const E& embeddedBody) { T* embedptr=static_cast(this); T* newinst; if(embedptr) newinst=new T(*embedptr); else newinst=new T(); newinst->set_body(embeddedBody); newinst->set_label(STD_string(newinst->get_label())+itos(instances.size())); instances.push_back(newinst); return *newinst; } T& set_embed_body (E& embeddedBody) { T* embedptr=static_cast(this); T* newinst; if(embedptr) newinst=new T(*embedptr); else newinst=new T(); newinst->set_body(embeddedBody); newinst->set_label(STD_string(newinst->get_label())+itos(instances.size())); instances.push_back(newinst); return *newinst; } typedef typename STD_list::iterator institer; institer get_inst_begin() {return instances.begin();} institer get_inst_end() {return instances.end();} typedef typename STD_list::const_iterator constinstiter; constinstiter get_const_inst_begin() const {return instances.begin();} constinstiter get_const_inst_end() const {return instances.end();} private: STD_list instances; }; /** @} */ #endif odin-1.8.5/tjutils/tjlog.cpp0000644000175000017500000001570711322062342012725 00000000000000#include "tjlog.h" #include "tjvector.h" #include "tjhandler_code.h" STD_string LogMessage::str(unsigned int maxwidth, bool include_comp) const { // crop beginning of strings if too long STD_string objCrop; unsigned int len=obj.length(); if(len>MAX_LOG_STRINGSIZE) objCrop=obj.substr(len-MAX_LOG_STRINGSIZE, MAX_LOG_STRINGSIZE); else objCrop=obj; STD_string funcCrop; len=func.length(); if(len>MAX_LOG_STRINGSIZE) funcCrop=func.substr(len-MAX_LOG_STRINGSIZE, MAX_LOG_STRINGSIZE); else funcCrop=func; const char* member_separator=""; if(obj.length()) member_separator="."; STD_string line; if(include_comp) line+=comp+STD_string(MAX_COMPONENT_SIZE-comp.length(),' ')+"|"; if(level==errorLog) line+="ERROR: "; if(level==warningLog) line+="WARNING: "; line+=objCrop; if(obj.length()) line+="."; line+=funcCrop+" : "+txt; if( maxwidth && (line.length()>maxwidth) ) { // zero linewidth indicates infinite length line=line.substr(0,maxwidth); line+=STD_string("..."); } return line; } ////////////////////////////////////////////////////////////////////////////////////////////////// void default_tracefunction(const LogMessage& msg) { fprintf(stderr,msg.str().c_str()); // Use stderr because 'real' cerr is not available with STREAM_REPLACEMENT fflush(stderr); // print immediately } ////////////////////////////////////////////////////////////////////////////////////////////////// struct LogBaseAlloc : public LogBase {}; void LogBase::set_log_level(const char* compname, logPriority level) { LogBaseAlloc alloc; // allocate global // modify level of component already registered STD_map::const_iterator it=global->components.find(compname); if(it!=global->components.end()) { log_component_fptr fp=it->second; fp(level); } // store initialization level global->init_level[compname]=level; // disable uniform initialization level global->uniform_init_level=ignoreArgument; } void LogBase::set_uniform_log_level(logPriority level) { LogBaseAlloc alloc; // allocate global // modify levels of components already registered for(STD_map::const_iterator it=global->components.begin();it!=global->components.end();++it) { log_component_fptr fp=it->second; if(fp) fp(level); } // set all initialization levels to the uniform level for(STD_map::iterator it2=global->init_level.begin();it2!=global->init_level.end();++it2) { it2->second=level; } global->uniform_init_level=level; } #ifndef NO_CMDLINE void LogBase::parse_log_cmdline_options(int argc, char *argv[], const char* opt, logPriority base) { char value[ODIN_MAXCHAR]; // parse cmdline opts while(getCommandlineOption(argc,argv,opt,value,ODIN_MAXCHAR)) { STD_string arg(value); STD_string::size_type pos=arg.find(":"); if(pos==STD_string::npos) { set_uniform_log_level(logPriority(base+atoi(arg.c_str()))); } else { STD_string compname=extract(arg,"",":"); STD_string levelstr=extract(arg,":",""); set_log_level(compname.c_str(),logPriority(base+atoi(levelstr.c_str()))); } } } bool LogBase::set_log_levels(int argc, char *argv[], bool trigger_error) { LogBaseAlloc alloc; // allocate global if(trigger_error && global && global->components.size()) { STD_cerr << "ERROR: LogBase::set_log_levels: global already initialized with the following components:" << STD_endl; // trigger error if static members have already initialized log handlers for(STD_map::iterator it=global->components.begin();it!=global->components.end();++it) { STD_cerr << " " << it->first << STD_endl; } return true; } parse_log_cmdline_options(argc,argv, "-v", noLog); parse_log_cmdline_options(argc,argv, "-d", RELEASE_LOG_LEVEL); // backwards compatability return false; } #endif STD_string LogBase::get_usage() { STD_string result; result+="-v or for debugging/tracing all components or a single component, respectively. "; result+="Possible values for loglevel are: "; int upperLevel=numof_log_priorities; #ifndef ODIN_DEBUG upperLevel=RELEASE_LOG_LEVEL+1; #endif for(int i=0; icomponents)[name]=func; // set initial log level from cache, if available if(global->uniform_init_level!=ignoreArgument) { func(global->uniform_init_level); } else { STD_map::iterator it2=global->init_level.find(name); if(it2!=global->init_level.end()) func(it2->second); } return true; } return false; } void LogBase::unregister_component(const char* name) { // STD_cout << "LogBase::unregister_component: name=" << name << STD_endl; if(global) { STD_map::iterator it=global->components.find(name); if(it!=global->components.end()) global->components.erase(it); } } static STD_string levels_retval; const char* LogBase::get_levels() { if(!global) return ""; levels_retval=""; for(STD_map::iterator it=global->components.begin(); it!=global->components.end(); ++it) { // STD_cout << "LogBase::get_levels: it->first=" << (void*)(it->first) << STD_endl; levels_retval+=STD_string(it->first)+" "; log_component_fptr fp=it->second; if(fp) levels_retval+=itos(fp(ignoreArgument))+"\n"; } return levels_retval.c_str(); } void LogBase::set_levels(const char* str) { svector lines(tokens(str,'\n')); for(unsigned int i=0; i=2) { set_log_level(tokens_per_line[0].c_str(), logPriority(atoi(tokens_per_line[1].c_str()))); } } } void LogBase::flush_oneline(const STD_string& txt, logPriority level) { if(global && global->tracefunc) { // check for global because it might be called after Static::destroy_all LogMessage msg; msg.level=level; msg.comp=compLabel; if(objLabel) msg.obj=objLabel; if(namedObj) msg.obj=namedObj->get_label(); msg.func=funcName; msg.txt=txt; global->tracefunc(msg); } } void LogBase::set_log_output_function(tracefunction func) { LogBaseAlloc alloc; // allocate global global->tracefunc=func; } void LogBase::init_static() { global.init("LogBaseGlobal"); } void LogBase::destroy_static() { global.destroy(); } template class SingletonHandler; SingletonHandler LogBase::global; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/tjutils/tjembed.cpp0000644000175000017500000000002611322062342013204 00000000000000#include "tjembed.h" odin-1.8.5/tjutils/tjthread_code.h0000644000175000017500000000606011712547771014063 00000000000000#include #include template void ThreadedLoop::WorkThread::run() { Log odinlog("WorkThread","run"); while(1) { process.wait(); process.reset(); // Reset for next event ODINLOG(odinlog,normalDebug) << "catched process signal, cont=" << tloop->cont << STD_endl; if(!tloop->cont) break; ODINLOG(odinlog,normalDebug) << "processing thread " << begin << "/" << end << STD_endl; status=tloop->kernel(*tloop->in_cache, *out_cache, local, begin, end); ODINLOG(odinlog,normalDebug) << "signaling finished=" << status << STD_endl; finished.signal(); if(!status) break; } } ////////////////////////////////////////////////////////////////////////// template bool ThreadedLoop::init(unsigned int numof_threads, unsigned int loopsize) { Log odinlog("ThreadedLoop","init"); mainbegin=0; mainend=loopsize; #ifndef NO_THREADS destroy(); // stop old threads ODINLOG(odinlog,normalDebug) << "numof_threads=" << numof_threads << STD_endl; if(numof_threads>1) { threads.resize(numof_threads-1); // the main thread is also used unsigned int onesize=loopsize/numof_threads; unsigned int rest=loopsize%numof_threads; unsigned int count=0; for(unsigned int i=0; i<(numof_threads-1); i++) { threads[i]=new WorkThread(this); threads[i]->begin=count; count+=onesize; if(iend=count; threads[i]->start(); } mainbegin=count; count+=onesize; if((numof_threads-1) void ThreadedLoop::destroy() { Log odinlog("ThreadedLoop","destroy"); #ifndef NO_THREADS cont=false; // Stop threads for(unsigned int i=0; iprocess.signal(); threads[i]->wait(); delete threads[i]; } threads.resize(0); #endif } template bool ThreadedLoop::execute(const In& in, STD_vector& outvec) { Log odinlog("ThreadedLoop","execute"); #ifdef NO_THREADS outvec.resize(1); return kernel(in, outvec[0], mainlocal, mainbegin, mainend); #else unsigned int nthreads=threads.size(); outvec.resize(nthreads+1); if(nthreads) { in_cache=∈ cont=true; for(unsigned int i=0; iout_cache=&(outvec[i]); threads[i]->status=true; threads[i]->process.signal(); } } bool result=kernel(in, outvec[nthreads], mainlocal, mainbegin, mainend); // Use mainthread also for kernel if(nthreads) { for(unsigned int i=0; ifinished.wait(); // Wait for result threads[i]->finished.reset(); if(!threads[i]->status) result=false; } ODINLOG(odinlog,normalDebug) << "finished.wait() done" << STD_endl; } return result; #endif } odin-1.8.5/tjutils/tjcstd.h0000644000175000017500000000377211322062342012545 00000000000000/*************************************************************************** tjcstd.h - description ------------------- begin : Thu Jun 16 2004 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJCSTD_H #define TJCSTD_H #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif // boilerplate C headers #include #include #include #include #include #include #ifdef HAVE_CTYPE_H #include #endif // missing C functions #ifndef HAVE_CTYPE_H int isdigit (int c); int isspace (int c); int islower (int c); int tolower (int c); int isupper (int c); int toupper (int c); #endif #ifndef HAVE_J1 double j1(double x); #endif #ifndef HAVE_ACOSH double acosh(double x); #endif #ifdef VXWORKS // fix broken exp function #define exp exp4vxworks double exp4vxworks(double x); #endif #ifndef HAVE_DL void *dlopen (const char *filename, int flag); const char *dlerror(void); void *dlsym(void *handle, char *symbol); int dlclose (void *handle); #endif //make VStudio 2005 happy with snprintf #ifdef USING_WIN32 #ifndef HAVE_SNPRINTF #define snprintf _snprintf #endif //HAVE_SNPRINTF #endif //USING_WIN32 #endif odin-1.8.5/tjutils/tjstd.cpp0000644000175000017500000003150411322062342012727 00000000000000#include "tjutils.h" #include "tjcstd.h" #include "tjstream.h" #include "tjtest.h" #include "tjlog.h" //////////////////////////////////////////////////////////////////////////// #ifdef STL_REPLACEMENT STD_ostream & operator << (STD_ostream & s, tjstd_complex c) { char sign[2]; if (c.im>=0.0) { sign[0]='+';sign[1]='\0';} else sign[0]='\0'; return s << c.re << sign << c.im << "i"; } #endif //////////////////////////////////////////////////////////////////////////// #ifdef STRING_REPLACEMENT tjstd_string::tjstd_string () : sdata(0), length_cache(0) {} tjstd_string::tjstd_string (unsigned int n,const char c) : sdata(new char [n+1]), length_cache(n) { for(unsigned int i=0;i=n)) { return nullchar; } else { return sdata[i]; } } const char& tjstd_string::operator [] (unsigned int i) const { unsigned int n=length(); if( i<0 || i>=n) { return nullchar; } else { return sdata[i]; } } tjstd_string operator + (const tjstd_string& s1, const tjstd_string& s2) { tjstd_string result; result.concat2strings(s1,s2); return result; } tjstd_string operator + (const tjstd_string& s1, const char* s2) { tjstd_string result; result.concat2strings(s1,tjstd_string(s2)); return result; } tjstd_string operator + (const char* s1, const tjstd_string& s2) { tjstd_string result; result.concat2strings(tjstd_string(s1),s2); return result; } tjstd_string& tjstd_string::operator += (const tjstd_string& s2) { concat2strings(*this,s2); return *this; } bool operator == (const tjstd_string& s, const tjstd_string& t) {return tjstd_string::compare2strings(s.sdata, t.sdata);} bool operator == (const tjstd_string& s, const char* t) {return tjstd_string::compare2strings(s.sdata, t);} bool operator == (const char* s, const tjstd_string& t) {return tjstd_string::compare2strings(s, t.sdata);} bool operator != (const tjstd_string& s, const tjstd_string& t) {return !tjstd_string::compare2strings(s.sdata, t.sdata);} bool operator != (const tjstd_string& s, const char* t) {return !tjstd_string::compare2strings(s.sdata, t);} bool operator != (const char* s, const tjstd_string& t) {return !tjstd_string::compare2strings(s, t.sdata);} bool operator < (const tjstd_string& s, const tjstd_string& t) { unsigned int p=0; unsigned int q=0; while( (p!=s.length()) && (q!=t.length()) && (toupper(s[p]) == toupper(t[q])) ) { ++p; ++q; } if(p==s.length()) return q!=t.length(); if(q==t.length()) return false; return ( toupper(s[p]) < toupper(t[q]) ); } bool operator > (const tjstd_string& s, const tjstd_string& t) { if(s==t) return false; return !(s> (STD_istream& s, tjstd_string& t) { char c=0; // remove trailing whitespaces while(s.get(c)) { if(!isspace(c)) { s.putback(c); break; } } tjstd_string buffer(STREAM2PARSE_CHUNK_SIZE,'\0'); t=""; int ibuff=0; while(s.get(c) && !isspace(c)) { buffer[(unsigned int)ibuff]=c; ibuff++; if(ibuff==STREAM2PARSE_CHUNK_SIZE) { t+=buffer; buffer=tjstd_string(STREAM2PARSE_CHUNK_SIZE,'\0'); ibuff=0; } } t+=buffer; // remove following whitespaces while(s.get(c)) { if(!isspace(c)) { s.putback(c); break; } } return s; } tjstd_string tjstd_string::substr(unsigned int beginpos,unsigned int sublength) const { unsigned int end=beginpos+sublength; if(beginpos > end) return ""; if(beginpos<0) beginpos=0; if( end <0) end=0; unsigned int len=length(); if(beginpos>=len) beginpos=len; if(end >=len) end=len; unsigned int resultlength=end-beginpos; tjstd_string result(end-beginpos); for(unsigned int i=0; i(thislength-startpos)) return npos; const char* thisstr=(const char*)c_str(); const char* searchstr=(const char*)searchstring.c_str(); unsigned int nshifts=(thislength-startpos)-searchlength+1; for(unsigned int ishift=0; ishift& ilist) const { Log odinlog(this,"listtest_dump_list"); ODINLOG(odinlog,errorLog) << "list=" << STD_endl; for(STD_list::const_iterator it=ilist.begin(); it!=ilist.end(); ++it) { ODINLOG(odinlog,errorLog) << (*it) << STD_endl; } } /////////////////////////////////////////////////////////////////////////// void listtest_init_list(STD_list& ilist) const { int i; ilist.clear(); ///////////// preparing list of random number between 0 and 9 for(i=0; i9) randval=9; if(i%3) ilist.push_back(randval); else ilist.push_front(randval); } } /////////////////////////////////////////////////////////////////////////// void listtest_digit_count(STD_list& ilist, int* digit_count) const { STD_list::const_iterator it; int i; for(i=0; i<10; i++) digit_count[i]=0; for(it=ilist.begin(); it!=ilist.end(); ++it) { digit_count[*it]++; } } /////////////////////////////////////////////////////////////////////////// bool listtest_check_list() const { Log odinlog(this,"listtest_check_list"); STD_list::const_iterator it; int i; STD_list ilist; int digit_count[10]; listtest_init_list(ilist); listtest_digit_count(ilist,digit_count); ///////////// checking sort() ilist.sort(); // checking linear ordering with ++ operator int lastdigit=-1; for(it=ilist.begin(); it!=ilist.end(); ++it) { if(lastdigit>=0) { if(lastdigit>(*it)) { ODINLOG(odinlog,errorLog) << "(sort) with ++: inconsistent ordering" << STD_endl; listtest_dump_list(ilist); return false; } } lastdigit=(*it); } // checking linear ordering with -- operator lastdigit=-1; it=ilist.end(); while(it!=ilist.begin()) { --it; if(lastdigit>=0) { if(lastdigit<(*it)) { ODINLOG(odinlog,errorLog) << "(sort) with --: inconsistent ordering" << STD_endl; listtest_dump_list(ilist); return false; } } lastdigit=(*it); } // checking digit_count int digit_count_test[10]; for(i=0; i<10; i++) digit_count_test[i]=0; for(it=ilist.begin(); it!=ilist.end(); ++it) { digit_count_test[*it]++; } for(i=0; i<10; i++) { if(digit_count_test[i]!=digit_count[i]) { ODINLOG(odinlog,errorLog) << "(sort) inconsistent digit_count" << STD_endl; listtest_dump_list(ilist); return false; } } ///////////// checking unique() ilist.unique(); unsigned int n_different_digits=0; for(i=0; i<10; i++) { if(digit_count[i]) n_different_digits++; } ODINLOG(odinlog,normalDebug) << "n_different_digits=" << n_different_digits << STD_endl; if(ilist.size()!=n_different_digits) { ODINLOG(odinlog,errorLog) << "(unique) inconsistent list after unique" << STD_endl; listtest_dump_list(ilist); return false; } ///////////// checking remove() listtest_init_list(ilist); ilist.remove(3); listtest_digit_count(ilist,digit_count); if(digit_count[3]) { ODINLOG(odinlog,errorLog) << "(remove) elements still there after remove" << STD_endl; listtest_dump_list(ilist); return false; } ///////////// checking clear() ilist.clear(); if(ilist.size()) { ODINLOG(odinlog,errorLog) << "(clear) elements still there after clear" << STD_endl; listtest_dump_list(ilist); return false; } /////////// checking STD_find ilist.clear(); ilist.push_back(1); ilist.push_back(3); ilist.push_back(4); if(STD_find(ilist.begin(), ilist.end(), 3) == ilist.end()) { ODINLOG(odinlog,errorLog) << "STD_find does not find existing element 3" << STD_endl; listtest_dump_list(ilist); return false; } if(STD_find(ilist.begin(), ilist.end(), 2) != ilist.end()) { ODINLOG(odinlog,errorLog) << "STD_find finds non-existing element 2" << STD_endl; listtest_dump_list(ilist); return false; } return true; } /////////////////////////////////////////////////////////////////////////// bool check_map() const { Log odinlog(this,"check_map"); STD_map imap; imap["12"]=12; imap["34"]=34; imap["56"]=56; int expected, returned; expected=34; returned=imap["34"]; if(expected!=returned) { ODINLOG(odinlog,errorLog) << "testing [] operator: expected/returned=" << expected << "/" << returned << STD_endl; return false; } STD_map::iterator it=imap.find("56"); expected=56; returned=it->second; if(expected!=returned) { ODINLOG(odinlog,errorLog) << "testing find: expected/returned=" << expected << "/" << returned << STD_endl; return false; } imap.erase(imap.find("34")); expected=2; returned=imap.size(); if(imap.size()!=2) { ODINLOG(odinlog,errorLog) << "testing erase: expected/returned=" << expected << "/" << returned << STD_endl; return false; } return true; } bool check() const { Log odinlog(this,"check"); for(unsigned int i=0; i #include #include /** * @addtogroup tjutils * @{ */ /////////////////////////////////////////////////////////////// class StateComponent { public: static const char* get_compName(); }; /////////////////////////////////////////////////////////////// template class State : public Labeled { public: typedef bool (T::* transition) (); State(T* statemachine, const char* statelabel, State* prerequired_state, transition tr) : Labeled(statelabel), machine(statemachine), pre_state(prerequired_state), trans(tr) { Log odinlog(this,"State()"); } bool obtain_state() { Log odinlog(this,"obtain_state"); // return if we are already in the desired state if(machine->current_state==this) return true; // try a registered direct transition if(machine->direct_transition(this)) return true; if(pre_state) { // check whether a prerequisite state exists and obtain that state if(!pre_state->obtain_state()) return false; } bool result=(machine->*trans)(); // perform the transition if(result) machine->current_state=this; return result; } private: T* machine; State* pre_state; transition trans; }; /////////////////////////////////////////////////////////////// template struct DirectTransition { DirectTransition(State* init, State* dest, typename State::transition tr) : init_state(init), dest_state(dest), trans(tr) { Log odinlog("DirectTransition","DirectTransition()"); } bool operator == (const DirectTransition& dt) const {return init_state==dt.init_state && dest_state==dt.dest_state && trans==dt.trans;} bool operator != (const DirectTransition& dt) const {return !(*this==dt);} bool operator < (const DirectTransition& dt) const {return init_state* init_state; State* dest_state; typename State::transition trans; }; /////////////////////////////////////////////////////////////// template class StateMachine { protected: StateMachine(State* first_state) : current_state(first_state) { Log odinlog("StateMachine","StateMachine()"); } const STD_string& get_current_state_label() const {return current_state->get_label();} void register_direct_trans(State* init, State* dest, typename State::transition tr) { direct_trans.push_back( DirectTransition(init,dest,tr) ); } bool direct_transition(State* dest) { typename STD_list >::iterator it; for(it=direct_trans.begin(); it!=direct_trans.end(); ++it) { if( (it->init_state==current_state) && (it->dest_state==dest) ) { typename State::transition tt=it->trans; bool result=((T*)(this)->*tt)(); if(result) current_state=dest; return result; } } return false; } private: friend class State; STD_list > direct_trans; State* current_state; }; /** @} */ #endif odin-1.8.5/tjutils/tjheap.h0000644000175000017500000000347611322062342012526 00000000000000/*************************************************************************** tjheap.h - description ------------------- begin : Thu Jul 31 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJHEAP_H #define TJHEAP_H #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif // pointer for external trace function typedef void (*heaptracefunction)(const char*); class Heap { public: static void malloc_stats(); static void set_trace_function(heaptracefunction func) {tracefunc=func;} static heaptracefunction tracefunc; }; //#ifdef CUSTOM_HEAP //#include //#ifndef STL_REPLACEMENT //#include //#endif // overloading new/delete if a custom heap (block of static memory) is used //#ifndef STL_REPLACEMENT //void* operator new(size_t size) throw (std::bad_alloc); //#else //void* operator new(size_t size); //#endif //void* operator new[](size_t size); //void operator delete(void* mptr); //void operator delete[](void* mptr); //#endif #endif odin-1.8.5/tjutils/tjhandler.cpp0000644000175000017500000000506711322062342013557 00000000000000#include "tjhandler.h" #include "tjlog.h" #include "tjlog_code.h" const char* HandlerComponent::get_compName() {return "Handler";} LOGGROUNDWORK(HandlerComponent) //////////////////////////////////////////////////////////////////////// void SingletonBase::set_singleton_map_external(SingletonMap* extmap) { // Log uses SingletonHandler -> do not use Log in here singleton_map_external=extmap; // in order to cache ptr properly, no singletons should be allocated at this point if(singleton_map && singleton_map->size()) { STD_cerr << "ERROR: SingletonBase::set_singleton_map_external: There are already singletons allocated:" << STD_endl; for(SingletonMap::iterator it=singleton_map->begin(); it!=singleton_map->end(); ++it) { STD_cerr << it->first << "/" << (void*)it->second << STD_endl; } } } SingletonBase::SingletonBase() { if(!singleton_map) singleton_map=new SingletonMap; } SingletonMap* SingletonBase::get_singleton_map() { // NOTE: Debug uses SingletonHandler -> do not use Debug in here if(!singleton_map) singleton_map=new SingletonMap; return singleton_map; } STD_string SingletonBase::get_singleton_label(SingletonBase* sing_ptr) { Log odinlog("SingletonBase","get_singleton_label"); STD_string result; if(!(singleton_map || singleton_map_external)) { ODINLOG(odinlog,normalDebug) << "neither singleton_map nor singleton_map_external available" << STD_endl; return result; } SingletonMap::iterator mapbegin=singleton_map->begin(); SingletonMap::iterator mapend =singleton_map->end(); if(singleton_map_external) { mapbegin=singleton_map_external->begin(); mapend =singleton_map_external->end(); } for(SingletonMap::iterator it=mapbegin; it!=mapend; ++it) { if(it->second==sing_ptr) result=it->first; } ODINLOG(odinlog,normalDebug) << "result(" << (void*)sing_ptr << ")=" << result << STD_endl; return result; } void* SingletonBase::get_external_map_ptr(const STD_string& sing_label) { // NOTE: Log uses SingletonHandler -> do not use Log in here if(singleton_map_external) { if(singleton_map_external->find(sing_label)==singleton_map_external->end()) { STD_cerr << "ERROR: SingletonBase::get_external_map_ptr: singleton >" << sing_label << "< not found in singleton_map_external" << STD_endl; return 0; } return (*singleton_map_external)[sing_label]->get_ptr(); } return 0; } SingletonMap* SingletonBase::singleton_map=0; SingletonMap* SingletonBase::singleton_map_external=0; //////////////////////////////////////////////////////////////////////// odin-1.8.5/tjutils/tjstatic.h0000644000175000017500000000661311322062342013074 00000000000000/*************************************************************************** tjstatic.h - description ------------------- begin : Sun Jul 7 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJSTATIC_H #define TJSTATIC_H #include #include /** * @addtogroup tjutils * @{ */ //////////////////////////////////////////////////////////////////// class Static { public: Static() {} virtual ~Static() {} // destroy all static objects manually static void destroy_all(); static void append_to_destructor_list(Static* sp); protected: static STD_list* destructor_list; }; //////////////////////////////////////////////////////////////////// template struct StaticAlloc : public virtual Static { StaticAlloc() { } ~StaticAlloc() { T::destroy_static(); } }; //////////////////////////////////////////////////////////////////// /** * This template class handles static members of all classes that * must be initialised exactly once. The rationale behind this * is that some of the classes posses static members on which * a certain action has to be performed EXACTLY once BEFORE * anything else happens with that class. The 'StaticHandler' serves as * as a base class for classes that require this feature. * It makes this easier by keeping track of how often the static * members have been initialised so that this is done only once. * The following steps must be performed to make use of the * StaticHandler: * * -# Deriving the class C from the template class StaticHandler * by adding 'public StaticHandler' to the list of base * classes * -# Adding the static member function * 'static void init_static();' * to the public section of the class. This function should * contain the actions that will be performed only once for * the static members. * -# Adding the static member function * 'static void destroy_static();' * to the public section of the class. This function should * contain the actions to deallocate memory allocated by init_static() * -# Adding the line 'bool StaticHandler::staticdone=false;' * to the source code of the class C */ template class StaticHandler { public: StaticHandler() { if(!staticdone) { // fast check staticdone=true; // must be assigned before call to T::init_static() to avoid infinite loops Static* sp=new StaticAlloc; Static::append_to_destructor_list(sp); T::init_static(); } } private: static bool staticdone; }; /** @} */ #endif odin-1.8.5/tjutils/tjarray.cpp0000644000175000017500000004152511322062342013257 00000000000000#include "tjarray.h" #include "tjtypes.h" #include "tjtest.h" ndim::ndim (unsigned long d) : STD_vector(d) { } // ndim nn(3); ndim::ndim (const STD_string& s) : STD_vector() { Log odinlog("ndim","ndim(const STD_string&)"); unsigned long incosistent=0; STD_string tt=shrink(s); ODINLOG(odinlog,normalDebug) << "ndim::ndim (const STD_string& s): after shrinking >" << tt << "<" << STD_endl; if(tt[(unsigned int)0] != '(') incosistent++; if(tt[tt.length()-1] != ')') incosistent++; STD_string innertext=replaceStr(extract(tt,"(",")",true),",",""); // if (typeofcontent(innertext)!=intnumbers) incosistent++; if(!incosistent) { ODINLOG(odinlog,normalDebug) << "ndim::ndim (const STD_string& s): no inconsistences in >" << tt << "<" << STD_endl; tt=replaceStr(tt,"(",","); tt=replaceStr(tt,")",","); ODINLOG(odinlog,normalDebug) << "ndim::ndim (const STD_string& s): string used for dim extraction: >" << tt << "<" << STD_endl; svector extends(tokens(tt,',')); unsigned int n=extends.size(); resize(n); for(unsigned int i=0;i odinlog("ndim","--()"); unsigned long n=size(); if (n <= 0) ODINLOG(odinlog,errorLog) << "reduce to negative dimension ?!" << STD_endl; else { ndim tt(*this); n--; resize(n); for(unsigned long i=0;i odinlog("ndim","--(int)"); unsigned long n=size(); if (n <= 0) ODINLOG(odinlog,errorLog) << "reduce to negative dimension ?!" << STD_endl; else { ndim tt(*this); n--; resize(n); for(unsigned long i=0;i odinlog("ndim","extent2index"); unsigned long totalIndex=0,subsize; if (dim() != mm.dim()) ODINLOG(odinlog,errorLog) <<"dimension mismatch: dim()!=mm.dim()=" << dim() << "!=" << mm.dim() << STD_endl; if(!dim()) return 0; ndim nn(*this); for(unsigned long i=0;i=0;i--){ nn[i]=temp%((*this)[i]); temp=temp/(*this)[i]; } return nn; } bool ndim::operator == (const ndim& nn) const { unsigned long i,flag=0; if (dim()==nn.dim()) { for(i=0;i= n ) return *this; ndim oldndim(*this); resize(newdim); unsigned long extent_factor=1; while(oldndim.dim()>newdim) { extent_factor=oldndim[0]; --oldndim; oldndim[0]*=extent_factor; } for(unsigned int i=0;i indexlist; unsigned long i; for(i=0;i1) indexlist.push_back((*this)[i]); } resize(indexlist.size()); i=0; for(STD_list::iterator it=indexlist.begin(); it!=indexlist.end(); ++it) { (*this)[i]=(*it); i++; } #else STD_vector::iterator new_end; new_end=std::remove(begin(),end(),(unsigned long)(1)); erase(new_end,end()); #endif if((size()==0) && at_least_one_element) { resize(1); (*this)[0]=1; } return *this; } #ifndef NO_UNIT_TEST class NdimTest : public UnitTest { public: NdimTest() : UnitTest("ndim") {} private: bool check() const { Log odinlog(this,"check"); ndim nn_reference(3); nn_reference[0]=4; nn_reference[1]=7; nn_reference[2]=9; nn_reference.add_dim(2,true); nn_reference.add_dim(3,false); ndim nn_parse(" ( 2, 4, 7, 9, 3 )"); if(nn_parse!=nn_reference) { ODINLOG(odinlog,errorLog) << "Mismatch: nn_reference/nn_parse=" << STD_string(nn_reference) << "/" << STD_string(nn_parse) << STD_endl; return false; } return true; } }; void alloc_NdimTest() {new NdimTest();} // create test instance #endif /**************************************************************/ /****************** Template code *******************/ /**************************************************************/ /*------------------------------------------------------*/ template tjarray::tjarray () : V() { extent.resize(1); extent[0] = 0; } template tjarray::tjarray (unsigned long n1) {redim(create_extent(n1));} template tjarray::tjarray (unsigned long n1, unsigned long n2) {redim(create_extent(n1,n2));} template tjarray::tjarray (unsigned long n1, unsigned long n2, unsigned long n3) {redim(create_extent(n1,n2,n3));} template tjarray::tjarray (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) {redim(create_extent(n1,n2,n3,n4));} template tjarray::tjarray (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) {redim(create_extent(n1,n2,n3,n4,n5));} template tjarray::tjarray (const tjarray &ta) : V(ta) { extent=ta.extent; } template tjarray::tjarray (const V& sv) : V(sv) { extent.resize(1); extent[0]=sv.size(); } template tjarray::tjarray (const ndim &nn) { V::resize(nn.total()); extent=nn; } template tjarray& tjarray::operator = (const tjarray& ta) { Log odinlog("tjarray","operator = (const tjarray&)"); V::operator = (ta); extent=ta.extent; return *this; } template tjarray& tjarray::operator = (const T& value) { for(unsigned int i=0; i V& tjarray::resize (unsigned int newsize) { Log odinlog("tjarray","resize"); extent.resize (1); extent[0]=newsize; V::resize(extent.total()); return *this; } template tjarray& tjarray::redim (const ndim &nn) { Log odinlog("tjarray","redim"); ODINLOG(odinlog,normalDebug) << "nn=" << STD_string(nn) << STD_endl; unsigned int newtot=nn.total(); if(total()!=newtot) V::resize(newtot); extent=nn; return *this; } template tjarray& tjarray::redim (unsigned long n1) {redim(create_extent(n1)); return *this;} template tjarray& tjarray::redim (unsigned long n1, unsigned long n2) {redim(create_extent(n1,n2)); return *this;} template tjarray& tjarray::redim (unsigned long n1, unsigned long n2, unsigned long n3) {redim(create_extent(n1,n2,n3)); return *this;} template tjarray& tjarray::redim (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) {redim(create_extent(n1,n2,n3,n4)); return *this;} template tjarray& tjarray::redim (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) {redim(create_extent(n1,n2,n3,n4,n5)); return *this;} //#endif template const ndim& tjarray::get_extent () const { return extent; } template T& tjarray::operator () (const ndim& ii) { Log odinlog("tjarray","operator ()"); unsigned long totalIndex=extent.extent2index(ii); unsigned long totalExtent=extent.total(); ODINLOG(odinlog,normalDebug) << "totalIndex/totalExtent=" << totalIndex << "/" << totalExtent << STD_endl; if(totalIndex>=totalExtent) return element_dummy; else return (*this)[totalIndex]; } template const T& tjarray::operator () (const ndim& ii) const { Log odinlog("tjarray","operator () const"); unsigned long totalIndex=extent.extent2index(ii); unsigned long totalExtent=extent.total(); ODINLOG(odinlog,normalDebug) << "totalIndex/totalExtent=" << totalIndex << "/" << totalExtent << STD_endl; if(totalIndex>=totalExtent) return element_dummy; else return (*this)[totalIndex]; } template T& tjarray::operator () (unsigned long n1) {return tjarray::operator () (create_extent(n1));} template T& tjarray::operator () (unsigned long n1, unsigned long n2) {return tjarray::operator () (create_extent(n1,n2));} template T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3) {return tjarray::operator () (create_extent(n1,n2,n3));} template T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) {return tjarray::operator () (create_extent(n1,n2,n3,n4));} template T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) {return tjarray::operator () (create_extent(n1,n2,n3,n4,n5));} template const T& tjarray::operator () (unsigned long n1) const {return tjarray::operator () (create_extent(n1));} template const T& tjarray::operator () (unsigned long n1, unsigned long n2) const {return tjarray::operator () (create_extent(n1,n2));} template const T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3) const {return tjarray::operator () (create_extent(n1,n2,n3));} template const T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) const {return tjarray::operator () (create_extent(n1,n2,n3,n4));} template const T& tjarray::operator () (unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4, unsigned long n5) const {return tjarray::operator () (create_extent(n1,n2,n3,n4,n5));} template unsigned long tjarray::dim() const {return extent.dim();} template unsigned long tjarray::size(unsigned long i) const {return extent[i];} template unsigned long tjarray::total() const {return extent.total();} template unsigned long tjarray::length() const {return total();} template unsigned int tjarray::elementsize() const {return sizeof(T);} template tjarray& tjarray::assignValues(const tjarray &ta) { Log odinlog("tjvector","assignValues"); if(ta.length()==length()) { for(unsigned int i=0; i"; tokens[i]=val; } return tokenstring(tokens,_DEFAULT_LINEWIDTH_); } template STD_ostream& tjarray::printbody2stream(STD_ostream& s) const { Log odinlog("tjarray","printbody2stream"); unsigned long n=length(); T typedummy; bool stringarr=(TypeTraits::type2label(typedummy)==STD_string("string")); unsigned int width=0; for(unsigned long i=0; i_DEFAULT_LINEWIDTH_) {s << "\n"; width=0;} if(stringarr) {s << "<"; width++;} STD_string val(TypeTraits::type2string((*this)[i])); s << val; width+=val.length(); if(stringarr) {s << ">"; width++;} if(i!=(n-1)) {s << " "; width++;} } return s; // << "\n"; } template ndim tjarray::create_extent(unsigned long n1) { ndim nn(1); nn[0]=n1; return nn; } template ndim tjarray::create_extent(unsigned long n1,unsigned long n2) { ndim nn(2); nn[0]=n1; nn[1]=n2; return nn; } template ndim tjarray::create_extent(unsigned long n1,unsigned long n2,unsigned long n3) { ndim nn(3); nn[0]=n1; nn[1]=n2; nn[2]=n3; return nn; } template ndim tjarray::create_extent(unsigned long n1,unsigned long n2,unsigned long n3,unsigned long n4) { ndim nn(4); nn[0]=n1; nn[1]=n2; nn[2]=n3; nn[3]=n4; return nn; } template ndim tjarray::create_extent(unsigned long n1,unsigned long n2,unsigned long n3,unsigned long n4,unsigned long n5) { ndim nn(5); nn[0]=n1; nn[1]=n2; nn[2]=n3; nn[3]=n4; nn[4]=n5; return nn; } template ndim tjarray::create_index(unsigned long index) const {return extent.index2extent(index);} ///////////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class ArrayTest : public UnitTest { public: ArrayTest() : UnitTest("array") {} private: bool check() const { Log odinlog(this,"check"); farray fa(1,2,3,4,5); STD_string expected="( 1, 2, 3, 4, 5 )"; STD_string printed=fa.get_extent(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "farray(...) failed: got extent >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } fa.redim(3,2,1); expected="( 3, 2, 1 )"; printed=fa.get_extent(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "farray.redim(...) failed: got extent >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } float testval=44.0; fa(2,1,0)=testval; if(fa.sum()!=44.0) { ODINLOG(odinlog,errorLog) << "farray.operator (...) failed: " << fa.sum() << "!=" << testval << STD_endl; return false; } return true; } }; void alloc_ArrayTest() {new ArrayTest();} // create test instance #endif /**************************************************************/ /****************** Template instantiations *********/ /**************************************************************/ template class tjarray; template class tjarray; template class tjarray; template class tjarray; template class tjarray; ///////////////////////////////////////////////////////////////////////////// // Helper functions: STD_string print_table(const sarray& table) { Log odinlog("","print_table"); STD_string result; if(table.dim()!=2) { ODINLOG(odinlog,errorLog) << "Dimension of input array != 2" << STD_endl; return result; } int ncols=table.size(0); int nrows=table.size(1); int icol, irow; // Get max width of each column ivector width(ncols); width=0; for(irow=0; irow #include /** * @addtogroup tjutils * @{ */ /** * This class holds nested lists (tree) of values. * Each node can contain a single value, or a list of other nested lists. * In addition, it contains a repetition counter for this node. * Its main purpose is to retrieve value lists (e.g. frequency lists, delay lists, reco indices) from the sequence tree. */ template class ValList : public virtual Labeled { /** * Actual data with reference counting */ struct ValListData { ValListData() : val(0), times(1), sublists(0), elements_size_cache(0), references(0) {} ValListData(const ValListData& vld) : times(vld.times), elements_size_cache(vld.elements_size_cache), references(0) { if(vld.val) val=new T(*vld.val); else val=0; if(vld.sublists) sublists=new STD_list< ValList >(*vld.sublists); else sublists=0; } ~ValListData() { if(sublists) delete sublists; if(val) delete val; } T* val; // zero pointer indicates 'value not set' unsigned int times; STD_list< ValList >* sublists; // zero pointer indicates 'list not set' unsigned int elements_size_cache; // cache for the number of values of one repetition of this node unsigned short references; // reference counter }; public: /** * Empty node with given label and repetitions */ ValList(const STD_string& object_label="unnamedValList", unsigned int repetitions=1); /** * Node with a single value */ ValList(T value); /** * Copy constructor */ ValList(const ValList& vl); ~ValList(); /** * Assignment operator */ ValList& operator = (const ValList& vl); /** * Make node single value */ ValList& set_value(T value); /** * Append another node to this */ ValList& add_sublist(const ValList& vl); /** * Multiply number of repetitions of this node by 'reptimes' */ ValList& multiply_repetitions(unsigned int reptimes) {copy_on_write(); data->times*=reptimes; return *this;} /** * Returns unrolled values of nested list */ STD_vector get_values_flat() const; /** * Returns unrolled values of nested list for one repetition of this list */ STD_vector get_elements_flat() const; /** * Equal operator */ bool operator == (const ValList& vl) const; /** * Comparison operator */ bool operator < (const ValList& vl) const; /** * Acess i'th value in the nested list */ T operator [] (unsigned int i) const; /** * Returns number of values of one repetition of this node */ // unsigned int elements_size() const; /** * Returns number of values */ unsigned int size() const {return data->times*data->elements_size_cache;} /** * Serializes list to a string */ STD_string printvallist() const; /** * Parses list from string */ bool parsevallist(const STD_string& str); /** * Prints value list to stream */ STD_ostream& print2stream(STD_ostream& os) const; /** * Clears the value list */ void clear(); private: friend class ValListTest; bool equalelements (const ValList& vl) const; ValList& increment_repetitions(unsigned int reptimes) {copy_on_write(); data->times+=reptimes; return *this;} unsigned int get_repetitions() const {return data->times;} void flatten_sublists(); void copy_on_write(); ValListData* data; }; /////////////////////////////////////////////////// /** @} */ #endif odin-1.8.5/tjutils/tjlist.h0000644000175000017500000001111111322062342012545 00000000000000/*************************************************************************** tjlist.h - description ------------------- begin : Mon Aug 5 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJLIST_H #define TJLIST_H #include /** * @addtogroup tjutils * @{ */ // for debugging List class ListComponent { public: static const char* get_compName(); }; ////////////////////////////////////////////////////////////// class ListItemBase {}; class ListBase { public: virtual ~ListBase() {} virtual void objlist_remove(ListItemBase* item) = 0; }; ////////////////////////////////////////////////////////////// template class ListItem : public ListItemBase { public: ListItem() {} ~ListItem(); // empty copy and assignment operator to avoid copying of 'objhandlers' member ListItem(const ListItem&) {} ListItem& operator = (const ListItem&) {return *this;} unsigned int numof_references() const {return objhandlers.size();} const ListItemBase& append_objhandler(ListBase& objhandler) const; const ListItemBase& remove_objhandler(ListBase& objhandler) const; private: mutable STD_list objhandlers; }; ///////////////////////////////////////////// /** * This template class handles a list of references to other objects. * In contrast to the STL list, it stores only pointers to the members * of the list instead of storing copies. That means, if a member of the * list is modified, the property of the whole list changes. This list * is well suited to build blocks of objects that will be modified after * they have been inserted into the list, e.g. a list of parameters. * * If you want to use this list, i.e. create an instantiation for a specific * data type T, you must first decide whether to use const objects, i.e. which * will not changed via the list, or non-const objects that can be modified * via the list. In the former case, create a list by instatiating * * List * * otherwise * * List * * Classes which are to be inserted into the list must be derived * from the base class * * ListItem * * This construct ensures that whenever an item of the list is deleted, * it deregisters itself from the list. */ template class List : public ListBase { public: /** * Constructs an empty List */ List(); /** * Destructor */ ~List(); /** * Assignment operator that will result in a list that holds references to all objects for which * 'l' contains a reference */ List& operator = (const List& l); /** * Removes all items from the list */ List& clear(); /** * Appends a reference to 'item' */ List& append(R item); /** * Removes all references to 'item' */ List& remove(R item); /** * Returns the number of items in the list */ unsigned int size() const {return objlist.size();} /** * Iterator for mutable lists */ typedef typename STD_list

    ::iterator iter; /** * Iterator for const lists */ typedef typename STD_list

    ::const_iterator constiter; /** * returns an iterator that points to the head of the list (for mutable lists) */ iter get_begin() {return objlist.begin();} /** * returns an iterator that points to the end of the list (for mutable lists) */ iter get_end() {return objlist.end();} /** * returns an iterator that points to the head of the list (for const lists) */ constiter get_const_begin() const {return objlist.begin();} /** * returns an iterator that points to the end of the list (for const lists) */ constiter get_const_end() const {return objlist.end();} private: void objlist_remove(ListItemBase* item); void link_item(P ptr); void unlink_item(P ptr); STD_list

    objlist; }; /** @} */ #endif odin-1.8.5/tjutils/tjthread.h0000644000175000017500000001267011712547771013075 00000000000000/*************************************************************************** tjthread.h - description ------------------- begin : Mon Dec 12 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef TJTHREAD_H #define TJTHREAD_H #include /** * @addtogroup tjutils * @{ */ //////////////////////////////////////////////////////////////////// // for debugging class ThreadComponent { public: static const char* get_compName(); }; //////////////////////////////////////////////////////////////////// /** * Lock for mutually exclusive (mutex) access in threads. The mutex is recursive. */ class Mutex { public: /** * Constructs unlocked mutex object. */ Mutex(); ~Mutex(); /** * Locks the mutex. */ void lock(); /** * Unlocks the mutex. */ void unlock(); private: friend class Event; // disable copying Mutex(const Mutex&) {} Mutex& operator = (const Mutex&) {return *this;} void* id; }; //////////////////////////////////////////////////////////////////// /** * Lock object using a mutex. */ class MutexLock { public: /** * Constructs a lock using 'mutex'. The mutex is locked for the lifetime of the object. */ MutexLock(Mutex& mutex) : m(mutex) {m.lock();} ~MutexLock() {m.unlock();} private: // disable copying MutexLock(const MutexLock& ml) : m(ml.m) {} // bogus MutexLock& operator = (const MutexLock&) {return *this;} Mutex& m; }; //////////////////////////////////////////////////////////////////// /** * Manual-reset event to synchronize threads. */ class Event { public: /** * Constructs an event object. */ Event(); ~Event(); /** * Waits until any other thread calls signal(). * Returns immediately if this has already happended. */ void wait(); /** * Signal event to all waiting threads. */ void signal(); /** * Manually reset event. */ void reset(); private: // disable copying Event(const Event&) {} Event& operator = (const Event&) {return *this;} void* id; // Extra stuff for pthread Mutex mutex; bool active; }; //////////////////////////////////////////////////////////////////// class ThreadIndex; // forward declaration /** * Base class for threads. Derive from this and implement * the run() function to use it. */ class Thread { public: /** * Constructs thread object with the given label. */ Thread(); virtual ~Thread(); /** * Starts the thread. * 'stack_size' is used as the threads stack size if not zero (in which case the * systems default stack size is used). * Returns 'true' only on sucess. */ bool start(unsigned int stack_size=0); /** * Waits for the thread to finish. Returns 'true' only on sucess. */ bool wait(); /** * Implement to run threads execution path. */ virtual void run() = 0; /** * Returns thread-unique ID of the current thread. */ static int self(); private: // disable copying Thread(const Thread&) {} Thread& operator = (const Thread&) {return *this;} void clear_id(); void* id; ThreadIndex* index; // give each thread a unique index }; //////////////////////////////////////////////////////////////////// /** * Class to parallelize loops. */ template class ThreadedLoop { public: /** * Default constructor. */ ThreadedLoop() : mainbegin(0), mainend(0) {} virtual ~ThreadedLoop() {destroy();} /** * Initialize to use 'numof_threads' executing 'loopsize' jobs in parallel. * Starts the worker threads. */ bool init(unsigned int numof_threads, unsigned int loopsize); /** * Stops the worker threads. */ void destroy(); /** * Execute loop using input 'in' and storing result from each thread in 'outvec'. */ bool execute(const In& in, STD_vector& outvec); private: /** * Overload this function to do the work of one thread using input 'in', * generating output 'out' with thread-local storage 'local' for the the loop inidices (begin <= i < end). */ virtual bool kernel(const In& in, Out& out, Local& local, unsigned int begin, unsigned int end) = 0; class WorkThread : public Thread { friend class ThreadedLoop; WorkThread(ThreadedLoop* tl) : tloop(tl) {} void run(); ThreadedLoop* tloop; unsigned int begin; unsigned int end; Event process; Event finished; volatile bool status; Out* out_cache; Local local; }; unsigned int mainbegin; unsigned int mainend; Local mainlocal; friend class WorkThread; STD_vector threads; const In* in_cache; volatile bool cont; }; /** @} */ #endif odin-1.8.5/tjutils/tjfeedback.cpp0000644000175000017500000000235611322062342013664 00000000000000#include "tjfeedback.h" #include "tjtools.h" ///////////////////////////////////////////////////////////////////////////// bool ProgressMeter::increase_counter(const char* subj) { MutexLock lock(mutex); display->increase(subj); return display->refresh(); } bool ProgressMeter::refresh_display() { MutexLock lock(mutex); return display->refresh(); } ProgressMeter& ProgressMeter::new_task(unsigned int total_steps, const char* txt) { MutexLock lock(mutex); if(display) display->init(total_steps,txt); return *this; } ///////////////////////////////////////////////////////////////////////////// #ifndef NO_CMDLINE void ProgressDisplayConsole::init(unsigned int nsteps, const char* txt) { counter=0; old_perc=0; nsteps_cache=nsteps; done=false; if(txt) STD_cout << txt << " " << STD_flush; } void ProgressDisplayConsole::increase(const char* subj) { if(done) return; counter++; unsigned int perc=(unsigned int)(100.0*secureDivision(counter,nsteps_cache)); if(perc>old_perc) { if(perc>=100) { STD_cout << "done" << STD_endl; done=true; } else { if(!(perc%10)) STD_cout << perc << "%" << STD_flush; else if(!(perc%2)) STD_cout << "." << STD_flush; } old_perc=perc; } } #endif odin-1.8.5/tjutils/tjtools.h0000644000175000017500000001654211363773555012773 00000000000000/*************************************************************************** tjtools.h - description ------------------- begin : Thu Jul 13 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ // This is a collection of frequently used C-routines #ifndef TJTOOLS_H #define TJTOOLS_H #include /** * @addtogroup tjutils * @{ */ #ifndef PII #define PII 3.14159265358979323846264338327950288 #endif #ifndef ODIN_MAXCHAR #define ODIN_MAXCHAR 4096 #endif #ifdef HAVE_LONG_LONG #define LONGEST_INT long long #else #define LONGEST_INT long #endif // functions of large file extension, define them here so // these macros can re-used in other modules #ifdef HAVE_STAT64 #define STAT stat64 #else #ifdef HAVE_STAT #define STAT stat #endif #endif #ifdef HAVE_OPEN64 #define OPEN open64 #else #define OPEN open #endif #ifdef HAVE_FOPEN64 #define FOPEN fopen64 #else #define FOPEN fopen #endif #ifdef HAVE_FSEEKO64 #define FSEEK fseeko64 #else #ifdef HAVE_FSEEKO #define FSEEK fseeko #else #define FSEEK fseek #endif #endif #ifdef HAVE_FTELLO64 #define FTELL ftello64 #else #ifdef HAVE_FTELLO #define FTELL ftello #else #define FTELL ftell #endif #endif #ifdef HAVE_MMAP64 #define MMAP mmap64 #else #define MMAP mmap #endif /** * * Mode flag when reading/writing raw data to disk: * - readMode: Read-only access * - overwriteMode: If a file with the same name already exists, it is overwritten * - appendMode: If a file with the same name already exists, the data is appended */ enum fopenMode {readMode,overwriteMode,appendMode}; /** * Norm of a double vector */ double norm(double x, double y); /** * Norm of a triple vector */ double norm3(double x,double y,double z); /** * * Maximum value of 3 numbers */ double maxof3(double f1, double f2, double f3); #ifndef NO_FILEHANDLING /** * * Returns mode string suitable for fopen according to 'mode' */ const char* modestring(fopenMode mode); /** * * Returns file size in bytes if file exists, otherwise -1 */ LONGEST_INT filesize(const char *filename); /** * * Returns the current directory of the process */ const char* getpwd(); /** * * Changes the current directory of the process to dirname. On success, zero is returned. On error, -1 is returned. */ int chpwd(const char *dirname); /** * * Creates the given directory. On success, zero is returned. On error, -1 is returned. */ int createdir(const char *dirname); /** * * Returns true if directory 'dirname' exists, otherwise false */ bool checkdir(const char *dirname); /** * * Moves a file 'src' to destination 'dst'. On success, zero is returned. On error, -1 is returned. */ int movefile(const char *src, const char* dst); /** * * Copies a file 'src' to destination 'dst'. On success, zero is returned. On error, -1 is returned. */ int copyfile(const char *src, const char* dst); /** * * Removes the file or directory 'fname'. On success, zero is returned. On error, -1 is returned. */ int rmfile(const char *fname); /** * * Changes permissions of file 'fname' to 'perm'. On success, zero is returned. On error, -1 is returned. */ int chperm(const char *fname, int perm); /** * * Creates a file mapping of file 'filename' with 'nbytes' length starting at 'offset' bytes into the file, * optionally in 'readonly' mode. * The 'fd' will hold the file descriptor (handle) of the mapped file. * Returns a pointer to the mapped memory region. */ void* filemap(const STD_string& filename, LONGEST_INT nbytes, LONGEST_INT offset, bool readonly, int& fd); /** * * Deletes a file mapping of file descriptor 'fd' which maps a region at memory location 'start' of 'nbytes' length * starting at 'offset' bytes into the file. */ void fileunmap(int fd, void* start, LONGEST_INT nbytes, LONGEST_INT offset); /** * * Return a unique name for a temporary file. */ STD_string tempfile(); /** * * Create an empty file, filled with zeroes. Overwrite or append according to 'mode'. * On error, -1 is returned. */ int create_empty_file(const STD_string& filename, LONGEST_INT nbytes, fopenMode mode=overwriteMode); #endif /** * * Returns the last system error as a string */ const char* lasterr(); /** * * Halt process/thread for 'ms' miliseconds. */ void sleep_ms(unsigned int ms); /** * * Returns the current time in s */ double current_time_s(); /** * * If denominator is zero the functions returns 0, otherwise numerator/denominator */ double secureDivision(double numerator, double denominator); /** * * If denominator is zero the functions returns 0, otherwise 1/denominator */ inline double secureInv(double denominator) {return secureDivision(1.0, denominator); } /** * * Same as getenv, but does return "" instead of 0 if variable is not found */ const char* secure_getenv(const char* variable_name); /** * * Returns true if the current platform has little endian byte order, otherwise false */ bool little_endian_byte_order(); /** * * Returns the number of (virtual) CPUs */ unsigned int numof_cores(); /** * * Returns sinc function with accurate results for small x * (in contrast to using sin(x)/x directly) */ double sinc(double x); #ifndef NO_CMDLINE /** * * Copies maximum of 'maxchar' characters from the argv[] which * follows an argv[] that matches 'option' into 'returnvalue'; * returns TRUE if successful; 'maxchar' should NOT be greater * than the number of bytes allocated for 'returnvalue' even if * the number of chars in argv[] is smaller. * If 'modify' is true, remove argument from the list. */ int getCommandlineOption(int argc, char *argv[], const char *option, char *returnvalue, int maxchar,bool modify=true); /** * * Returns TRUE if 'option' is found in argv[] * If 'modify' is true, remove argument from the list. */ int isCommandlineOption(int argc, char *argv[], const char *option,bool modify=true); /** * * Copies maximum of 'maxchar' characters from the last argv[] * that DOESN'T start with '-' into 'returnvalue'; * returns TRUE if successful; 'maxchar' should NOT be greater * than the number of bytes allocated for 'returnvalue' even if * the number of chars in argv[] is smaller */ int getLastArgument(int argc, char *argv[], char *returnvalue, int maxchar,bool modify=true); /** * * Returns whether one of the options '-h, -help, --help or --version' was given */ int hasHelpOption(int argc, char *argv[]); /** * * Returns description of the standard help, version options */ const char* helpUsage(); #endif /** @} */ #endif odin-1.8.5/tjutils/tjindex.cpp0000644000175000017500000001226711322062342013251 00000000000000#include "tjindex.h" #include "tjtest.h" #include "tjlog_code.h" #include "tjhandler_code.h" const char* Index::get_compName() {return "Index";} LOGGROUNDWORK(Index) /////////////////////////////////////////////////////////////////////////////////////////// unsigned int UniqueIndexMap::get_index(STD_list::iterator& index, const STD_string& type, unsigned int max_instances) { Log odinlog(type.c_str(),"get_index"); STD_list& indices=(*this)[type]; if(index==indices.end()) assign_index(index,type); if(max_instances && ((*index)>=max_instances)) { ODINLOG(odinlog,errorLog) << "maximum number of indices exceeded for type " << type << STD_endl; return 0; } ODINLOG(odinlog,normalDebug) << "returning index=" << *index << STD_endl; return (*index); } void UniqueIndexMap::remove_index(const STD_list::iterator& index, const STD_string& type) { Log odinlog(type.c_str(),"remove_index"); STD_list& indices=(*this)[type]; if(index!=indices.end()) { ODINLOG(odinlog,normalDebug) << "Trying to remove index=" << *index << STD_endl; indices.erase(index); contiguous=false; } } unsigned int UniqueIndexMap::assign_index(STD_list::iterator& index, const STD_string& type) { Log odinlog(type.c_str(),"assign_index"); STD_list& indices=(*this)[type]; index=indices.end(); unsigned int i=0; STD_list::iterator iter; if(contiguous){ //if the list is contiguous iter=indices.end(); if(indices.begin()!=indices.end())//use the last member +1 or leave 0 i= *(--indices.end())+1; } else {//if list is not complete find the first "gap" for(iter=indices.begin();iter!=indices.end() && *iter==i;++iter) i++; } index=indices.insert(iter,i);//insert i into the gap (or the end) ODINLOG(odinlog,normalDebug) << "adding index=" << i << STD_endl; for(;iter!=indices.end() && *iter==(i+1);++iter); //check for a gap behind contiguous = (iter==indices.end()); return i; } /////////////////////////////////////////////////////////////////////////////////////////// template class SingletonHandler; SingletonHandler UniqueIndexBase::indices_map; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; /////////////////////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST #define INDEX_TESTSIZE 5 class IndexTest : public UnitTest { // Test class class UniqueIndexTest : public UniqueIndex { public: UniqueIndexTest(){}; static const char* get_typename() {return "UniqueIndexTest";} static unsigned int get_max_instances() {return 0;} }; public: IndexTest() : UnitTest("index") {} private: bool compare_and_report(int expected[INDEX_TESTSIZE], UniqueIndexTest* objs[INDEX_TESTSIZE], const char* txt) const { Log odinlog(this,"compare_and_report"); for(unsigned int i=0; i=0) { int returned=objs[i]->get_index(); if(expected[i]!=returned) { ODINLOG(odinlog,errorLog) << txt << "[" << i << "]: expected/returned=" << expected[i] << "/" << returned << STD_endl; return true; } } } return false; } bool check() const { Log odinlog(this,"check"); UniqueIndexTest* objs[INDEX_TESTSIZE]; for(unsigned int i=0; iget_index(); if(endobjindex!=endobjindex_expected) { ODINLOG(odinlog,errorLog) << "endobjindex/_expected=" << endobjindex << "/" << endobjindex_expected << STD_endl; return false; } delete endobj; // Delete in reverse order and check again delete objs[1]; delete objs[3]; objs[1]=new UniqueIndexTest; objs[3]=new UniqueIndexTest; if(compare_and_report(expected, objs, "realloc2")) return false; // Delete begin and end indices delete objs[0]; delete objs[INDEX_TESTSIZE-1]; int expected3[]={-1,1,2,3,-1}; if(compare_and_report(expected3, objs, "begin/end")) return false; // Re-create in reverse order objs[INDEX_TESTSIZE-1]=new UniqueIndexTest; int expected4[]={-1,1,2,3,0}; if(compare_and_report(expected4, objs, "begin/end(realloc1)")) return false; objs[0]=new UniqueIndexTest; int expected5[]={4,1,2,3,0}; if(compare_and_report(expected5, objs, "begin/end(realloc2)")) return false; for(unsigned int i=0; i #include #include "geoeditlabel.h" #define MAGN_FACTOR 2 #define MIN_MATRIX_SIZE 256 class GeoEditView : public QWidget { Q_OBJECT public: GeoEditView(Geometry& geometry, ImageSet& pilot, unsigned int blowup, QWidget *parent); private slots: void geometryChanged(); void emitDone(); void setProjection(bool) {geometryChanged();} void setCrossSection(bool) {geometryChanged();} void sagSet(); void corSet(); void axiSet(); void magnify0(int,int,int) {magnify(0);} void magnify1(int,int,int) {magnify(1);} void magnify2(int,int,int) {magnify(2);} signals: void donePressed(); private: void magnify(int index); unsigned int coarse; Geometry& geometry_cache; ImageSet& pilot_cache; JDXwidget* blockwidget[n_geometry_modes]; GuiGridLayout* grid; STD_list labels; buttonBox* projection; buttonBox* crosssect; geometryMode old_mode; }; #endif odin-1.8.5/geoedit/geoeditlabel.h0000644000175000017500000000522511322062334013610 00000000000000/*************************************************************************** geoeditlabel.h - description ------------------- begin : Tue Apr 16 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GEOEDITLABEL_H #define GEOEDITLABEL_H #include #include #include #define REL_READVEC_LENGTH 0.2 #define READVEC_ARROW_LENGTH 0.1 #define CROSSSECT_COLOR "Red" #define PROJECTION_COLOR "Green" //////////////////////////////////////// // for debugging geoedit component class GeoEditComp { public: static const char* get_compName(); }; //////////////////////////////////////// class GeoEditLabel : public floatBox3D { Q_OBJECT public: GeoEditLabel(const Image& background, unsigned int coarseFactor, QWidget *parent); void drawImagingArea(const Geometry& ia, bool drawProj, bool drawCross); private: int xcoord2labelxpos(double pos) { return label->xpos2labelxpos(int((double)label->get_nx()*(0.5+secureDivision(pos,backgr.get_geometry().get_FOV(readDirection)))));} int ycoord2labelypos(double pos) { return label->ypos2labelypos(int((double)label->get_ny()*(0.5+secureDivision(pos,backgr.get_geometry().get_FOV(phaseDirection)))));} void drawSliceProjection(const darray& cornersProj, GuiPainter& painter); void drawSliceCrossSection(const darray& connectPoints, double slicethick, GuiPainter& painter, unsigned int slice); void drawVoxelProjection(const darray& cornersProj, GuiPainter& painter); void drawReadVector(const dvector& readvecstart_proj, const dvector& readvec_proj, GuiPainter& painter); // overloading virtual function of floatBox3D void repaint() {if(ia_cache) drawImagingArea(*ia_cache,drawProj_cache,drawCross_cache);} Image backgr; unsigned int coarse; const Geometry* ia_cache; bool drawProj_cache; bool drawCross_cache; }; #endif odin-1.8.5/geoedit/main.cpp0000644000175000017500000000055711322062334012452 00000000000000#include "geoedit.h" int main(int argc, char *argv[]) { // do this here so we do not have to query X server in order to get usage for manual if(hasHelpOption(argc, argv)) {GeoEditApp::usage();exit(0);} GuiApplication a(argc, argv); // debug handler will be initialized here GeoEditApp *geoedit=new GeoEditApp(); return a.start(geoedit->get_widget()); } odin-1.8.5/geoedit/geoedit.cpp0000644000175000017500000000503011322062334013135 00000000000000#include "geoedit.h" #include void GeoEditApp::usage() { STD_cout << "geoedit: Geometry editor of ODIN" << STD_endl; STD_cout << "Usage: geoedit [options] " << STD_endl; STD_cout << "Options:" << STD_endl; STD_cout << "\t -pilot : Load pilot scan as background" << STD_endl; STD_cout << "\t -sample : Load sample as background" << STD_endl; STD_cout << "\t -blowup : Enlarge size of backround by this factor" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } GeoEditApp::GeoEditApp() : geometry("Geometry") { Log odinlog("GeoEditApp","GeoEditApp(...)"); // command line parsing char optval[ODIN_MAXCHAR]; if(hasHelpOption(GuiApplication::argc(),GuiApplication::argv())) {usage();exit(0);} if(GuiApplication::argc()<=1) { filename = get_open_filename("Please select geometryInfo to start with ...", "", "", GuiMainWindow::get_widget()); }else { getLastArgument(GuiApplication::argc(),GuiApplication::argv(),optval,ODIN_MAXCHAR); filename=optval; } if(filename=="") exit(0); if(geometry.load(filename)<=0) { ODINLOG(odinlog,warningLog) << "unable to load " << filename << " as geometry file, will be created" << STD_endl; } ODINLOG(odinlog,normalDebug) << "load done" << STD_endl; if(getCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-pilot",optval,ODIN_MAXCHAR)) { pilot.load(optval); } ODINLOG(odinlog,normalDebug) << "pilot done" << STD_endl; if(getCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-sample",optval,ODIN_MAXCHAR)) { Sample sample("sample",false); if(sample.load(optval)>0) { ODINLOG(odinlog,normalDebug) << "Creating pilot from sample" << STD_endl; pilot=ImageSet(sample); } } ODINLOG(odinlog,normalDebug) << "sample done" << STD_endl; set_caption((STD_string("GeoEdit " VERSION) + " - " + filename).c_str()); unsigned int blowup=1; if(getCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-blowup",optval,ODIN_MAXCHAR)) { blowup=atoi(optval); } view=new GeoEditView(geometry,pilot,blowup,GuiMainWindow::get_widget()); connect(view,SIGNAL(donePressed()),this,SLOT( exitGeoEdit())); ODINLOG(odinlog,normalDebug) << "view done" << STD_endl; GuiMainWindow::show(view); // setCentralWidget(view); } void GeoEditApp::exitGeoEdit() { geometry.write(filename); GuiApplication::quit(); // qApp->quit(); } odin-1.8.5/geoedit/Makefile.am0000644000175000017500000000137411322062334013054 00000000000000 if GUI_ENABLED INCLUDES = $(all_includes) # Auto-generate any needed moc files %_moc.cpp: %.h $(MOC) -o $@ $< bin_PROGRAMS = geoedit geoedit_SOURCES = \ main.cpp \ geoedit.cpp geoedit.h geoedit_moc.cpp \ geoeditlabel.cpp geoeditlabel.h geoeditlabel_moc.cpp \ geoeditview.cpp geoeditview.h geoeditview_moc.cpp geoedit_LDADD = ../odinqt/libodinqt.la ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = geoedit.1 dist-hook: -rm -rf $(distdir)/*_moc.cpp endif clean-local: -rm -f *_moc.cpp odin-1.8.5/geoedit/Makefile.in0000644000175000017500000005325211734622602013076 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @GUI_ENABLED_TRUE@bin_PROGRAMS = geoedit$(EXEEXT) subdir = geoedit DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__geoedit_SOURCES_DIST = main.cpp geoedit.cpp geoedit.h \ geoedit_moc.cpp geoeditlabel.cpp geoeditlabel.h \ geoeditlabel_moc.cpp geoeditview.cpp geoeditview.h \ geoeditview_moc.cpp @GUI_ENABLED_TRUE@am_geoedit_OBJECTS = main.$(OBJEXT) \ @GUI_ENABLED_TRUE@ geoedit.$(OBJEXT) geoedit_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ geoeditlabel.$(OBJEXT) \ @GUI_ENABLED_TRUE@ geoeditlabel_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ geoeditview.$(OBJEXT) \ @GUI_ENABLED_TRUE@ geoeditview_moc.$(OBJEXT) geoedit_OBJECTS = $(am_geoedit_OBJECTS) @GUI_ENABLED_TRUE@geoedit_DEPENDENCIES = ../odinqt/libodinqt.la \ @GUI_ENABLED_TRUE@ ../odindata/libodindata.la \ @GUI_ENABLED_TRUE@ ../odinpara/libodinpara.la \ @GUI_ENABLED_TRUE@ ../tjutils/libtjutils.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(geoedit_SOURCES) DIST_SOURCES = $(am__geoedit_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @GUI_ENABLED_TRUE@INCLUDES = $(all_includes) @GUI_ENABLED_TRUE@geoedit_SOURCES = \ @GUI_ENABLED_TRUE@ main.cpp \ @GUI_ENABLED_TRUE@ geoedit.cpp geoedit.h geoedit_moc.cpp \ @GUI_ENABLED_TRUE@ geoeditlabel.cpp geoeditlabel.h geoeditlabel_moc.cpp \ @GUI_ENABLED_TRUE@ geoeditview.cpp geoeditview.h geoeditview_moc.cpp @GUI_ENABLED_TRUE@geoedit_LDADD = ../odinqt/libodinqt.la ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Manual pages for distribution @GUI_ENABLED_TRUE@dist_man_MANS = geoedit.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu geoedit/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu geoedit/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list geoedit$(EXEEXT): $(geoedit_OBJECTS) $(geoedit_DEPENDENCIES) @rm -f geoedit$(EXEEXT) $(CXXLINK) $(geoedit_OBJECTS) $(geoedit_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoedit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoedit_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoeditlabel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoeditlabel_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoeditview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geoeditview_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @GUI_ENABLED_FALSE@dist-hook: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags dist-hook \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 # Auto-generate any needed moc files @GUI_ENABLED_TRUE@%_moc.cpp: %.h @GUI_ENABLED_TRUE@ $(MOC) -o $@ $< # Auto-generate manual pages, only if not in srcdir @GUI_ENABLED_TRUE@%.1: % @GUI_ENABLED_TRUE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @GUI_ENABLED_TRUE@dist-hook: @GUI_ENABLED_TRUE@ -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/geoedit/geoeditlabel.cpp0000644000175000017500000002013611322062334014141 00000000000000 #include "geoeditlabel.h" #include "geoeditview.h" #include const char* GeoEditComp::get_compName() {return "GeoEdit";} LOGGROUNDWORK(GeoEditComp) //////////////////////////////////////////////////////////////////////////// GeoEditLabel::GeoEditLabel(const Image& background, unsigned int coarseFactor, QWidget *parent ) : floatBox3D(background.get_magnitude().c_array(),0.0,0.0, background.size(xAxis),background.size(yAxis),background.size(zAxis), coarseFactor,parent,background.get_label().c_str()), backgr(background), coarse(coarseFactor), ia_cache(0) { } void GeoEditLabel::drawSliceProjection(const darray& cornersProj, GuiPainter& painter) { painter.setPen(PROJECTION_COLOR,1,true); painter.moveTo(xcoord2labelxpos(cornersProj(0,0)),ycoord2labelypos(cornersProj(0,1))); for(unsigned int icorner=1; icorner<4; icorner++) { painter.lineTo(xcoord2labelxpos(cornersProj(icorner,0)),ycoord2labelypos(cornersProj(icorner,1))); } painter.lineTo(xcoord2labelxpos(cornersProj(0,0)),ycoord2labelypos(cornersProj(0,1))); } void GeoEditLabel::drawSliceCrossSection(const darray& connectPoints, double slicethick, GuiPainter& painter, unsigned int slice) { Log odinlog("GeoEditLabel","drawSliceCrossSection"); int penwidth=(int)(slicethick/backgr.get_geometry().get_FOV(readDirection)*float(backgr.size(xAxis))*float(coarse)); if(penwidth<1) penwidth=1; painter.setPen(CROSSSECT_COLOR,penwidth); int xstart=xcoord2labelxpos(connectPoints(0,0)); int ystart=ycoord2labelypos(connectPoints(0,1)); int xend=xcoord2labelxpos(connectPoints(1,0)); int yend=ycoord2labelypos(connectPoints(1,1)); ODINLOG(odinlog,normalDebug) << "xstart/ystart/xend/yend=" << xstart << "/" << ystart << "/" << xend << "/" << yend << STD_endl; painter.moveTo(xstart,ystart); painter.lineTo(xend,yend); painter.drawText((xend+xstart)/2, (yend+ystart)/2,itos(slice).c_str(),CROSSSECT_COLOR); } void GeoEditLabel::drawVoxelProjection(const darray& cornersProj, GuiPainter& painter) { unsigned int icorner; painter.setPen(PROJECTION_COLOR,1,true); for(unsigned int ilevel=0; ilevel<2; ilevel++) { painter.moveTo(xcoord2labelxpos(cornersProj(ilevel,0,0)),ycoord2labelypos(cornersProj(ilevel,0,1))); for(unsigned int icorner=1; icorner<4; icorner++) { painter.lineTo(xcoord2labelxpos(cornersProj(ilevel,icorner,0)),ycoord2labelypos(cornersProj(ilevel,icorner,1))); } painter.lineTo(xcoord2labelxpos(cornersProj(ilevel,0,0)),ycoord2labelypos(cornersProj(ilevel,0,1))); } for(icorner=0; icorner<4; icorner++) { painter.moveTo(xcoord2labelxpos(cornersProj(0,icorner,0)),ycoord2labelypos(cornersProj(0,icorner,1))); painter.lineTo(xcoord2labelxpos(cornersProj(1,icorner,0)),ycoord2labelypos(cornersProj(1,icorner,1))); } } void GeoEditLabel::drawReadVector(const dvector& readvecstart_proj, const dvector& readvec_proj, GuiPainter& painter) { painter.setPen(PROJECTION_COLOR); dvector readvec_end(2); readvec_end=readvecstart_proj+readvec_proj; dvector readvec_proj_perp(2); readvec_proj_perp[0]=-readvec_proj[1]; readvec_proj_perp[1]= readvec_proj[0]; dvector readvec_arrow_end(2); readvec_arrow_end=readvecstart_proj+(1.0-READVEC_ARROW_LENGTH)*readvec_proj+READVEC_ARROW_LENGTH*readvec_proj_perp; painter.moveTo(xcoord2labelxpos(readvecstart_proj[0]),ycoord2labelypos(readvecstart_proj[1])); painter.lineTo(xcoord2labelxpos(readvec_end[0]),ycoord2labelypos(readvec_end[1])); painter.lineTo(xcoord2labelxpos(readvec_arrow_end[0]),ycoord2labelypos(readvec_arrow_end[1])); } void GeoEditLabel::drawImagingArea(const Geometry& ia, bool drawProj, bool drawCross) { Log odinlog("GeoEditLabel","drawImagingArea"); ia_cache=&ia; drawProj_cache=drawProj; drawCross_cache=drawCross; // init painter label->init_pixmap(); GuiPainter painter(label->pixmap); // first, get corner points in coordinate system of background image ODINLOG(odinlog,normalDebug) << "get_current_z()=" << get_current_z() << STD_endl; darray cornerPoints=ia.get_cornerPoints(backgr.get_geometry(),floatBox3D::get_current_z()); // will be 1 for slicepack mode or 2 for 3D/Voxel mode int n_slice_bounds=cornerPoints.size(3); bool is3d=(n_slice_bounds>1); if(is3d) drawCross=false; darray corners(4,3); darray corners3d(2,4,3); dvector cornervec1(3); dvector cornervec2(3); darray crosspoints(2,2); darray allCornersTemp(4,2); darray allCornersTemp3d(2,4,2); // the coordinate system of the plot axis projAxis1=xAxis; axis projAxis2=yAxis; axis perpax=zAxis; unsigned int n_slices=cornerPoints.size(0); unsigned int midslice=n_slices/2; dvector readvec(3); dvector readvecstart(3); for(unsigned int idir=0;idir<3;idir++) { readvec[idir]=REL_READVEC_LENGTH*(cornerPoints(midslice,upperBound,0,0,idir)-cornerPoints(midslice,lowerBound,0,0,idir)); readvecstart[idir]=cornerPoints(midslice,lowerBound,lowerBound,0,idir); } ODINLOG(odinlog,normalDebug) << "readvec=" << readvec.printbody() << STD_endl; dvector readvec_proj(2); readvec_proj[0]=readvec[projAxis1]; readvec_proj[1]=readvec[projAxis2]; dvector readvecstart_proj(2); readvecstart_proj[0]=readvecstart[projAxis1]; readvecstart_proj[1]=readvecstart[projAxis2]; if(drawProj) drawReadVector(readvecstart_proj,readvec_proj,painter); for(unsigned int j=0;j0.0) && (s<1.0) && (icross<2) ) { crosspoints(icross,0)=cornervec1[projAxis1]+s*(cornervec2[projAxis1]-cornervec1[projAxis1]); crosspoints(icross,1)=cornervec1[projAxis2]+s*(cornervec2[projAxis2]-cornervec1[projAxis2]); icross++; } } } } if(drawProj) { if(is3d) drawVoxelProjection(allCornersTemp3d,painter); else drawSliceProjection(allCornersTemp,painter); } if(drawCross && (icross==2)) { ODINLOG(odinlog,normalDebug) << "crosspoints(" << j << ")=" << crosspoints.printbody() << STD_endl; drawSliceCrossSection(crosspoints,ia.get_sliceThickness(),painter,j); } } painter.end(); label->set_pixmap(); } odin-1.8.5/geoedit/geoedit.10000644000175000017500000000146611734623150012532 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH GEOEDIT "1" "March 2012" "geoedit 1.8.5" "User Commands" .SH NAME geoedit \- Geometry editor of ODIN .SH SYNOPSIS .B geoedit [\fIoptions\fR] \fI\fR .SH DESCRIPTION geoedit: Geometry editor of ODIN .SH OPTIONS .HP \fB\-pilot\fR : Load pilot scan as background .TP \fB\-sample\fR : Load sample as background .HP \fB\-blowup\fR : Enlarge size of backround by this factor .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/geoedit/geoedit.h0000644000175000017500000000260211322062334012604 00000000000000/*************************************************************************** geoedit.h - description ------------------- begin : Mon Apr 15 18:40:55 CEST 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GEOEDIT_H #define GEOEDIT_H #include "geoeditview.h" //////////////////////////////////////// class GeoEditApp : public QObject, public GuiMainWindow { Q_OBJECT public: GeoEditApp(); static void usage(); private slots: void exitGeoEdit(); private: STD_string filename; ImageSet pilot; Geometry geometry; GeoEditView *view; }; #endif odin-1.8.5/geoedit/geoeditview.cpp0000644000175000017500000001172511322062334014040 00000000000000#include "geoedit.h" #include "geoeditview.h" #include GeoEditView::GeoEditView(Geometry& geometry, ImageSet& pilot, unsigned int blowup, QWidget *parent) : QWidget(parent), geometry_cache(geometry), pilot_cache(pilot) { Log odinlog("GeoEditView","GeoEditView(...)"); old_mode=n_geometry_modes; // invalid value to trigger generation of first widget for(int imode=0; imode0) { coarse=(unsigned int)secureDivision(MIN_MATRIX_SIZE,(nx+ny)/2); if(!coarse) coarse=1; ODINLOG(odinlog,normalDebug) << "coarse[" << i<< "]=" << coarse << STD_endl; img.normalize_magnitude(); GeoEditLabel* imglabel=new GeoEditLabel(img,coarse*blowup,this); if(i==0) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify0(int,int,int))); if(i==1) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify1(int,int,int))); if(i==2) connect(imglabel,SIGNAL(clicked(int,int,int)),this,SLOT( magnify2(int,int,int))); grid->add_widget( imglabel, 0, 2*i, GuiGridLayout::Center, 1,2); labels.push_back(imglabel); } } /* ------------ draw projection button -----------------*/ projection=new buttonBox("Hide","Show",true, this, "Projection" ); grid->add_widget( projection, 1,5, GuiGridLayout::Center); connect(projection,SIGNAL(buttonToggled(bool)),this,SLOT( setProjection(bool))); /* ------------ draw cross section button -----------------*/ crosssect=new buttonBox("Hide","Show",true, this, "CrossSection" ); grid->add_widget( crosssect, 2,5, GuiGridLayout::Center); connect(crosssect,SIGNAL(buttonToggled(bool)),this,SLOT( setCrossSection(bool))); /* ------------ set sagittal button -----------------*/ buttonBox *sagbutton=new buttonBox("Set", this, "Sagittal" ); grid->add_widget( sagbutton, 3,5, GuiGridLayout::Center); connect(sagbutton,SIGNAL(buttonClicked()),this,SLOT( sagSet())); /* ------------ set coronal button -----------------*/ buttonBox *corbutton=new buttonBox("Set", this, "Coronal" ); grid->add_widget( corbutton, 4,5, GuiGridLayout::Center); connect(corbutton,SIGNAL(buttonClicked()),this,SLOT( corSet())); /* ------------ set axial button -----------------*/ buttonBox *axibutton=new buttonBox("Set", this, "Axial" ); grid->add_widget( axibutton, 5,5, GuiGridLayout::Center); connect(axibutton,SIGNAL(buttonClicked()),this,SLOT( axiSet())); /* ------------ save & exit button -----------------*/ buttonBox *saveexit=new buttonBox("Done", this, "Save & Exit" ); grid->add_widget( saveexit, 6,5, GuiGridLayout::Center); connect(saveexit,SIGNAL(buttonClicked()),this,SLOT( emitDone())); ODINLOG(odinlog,normalDebug) << "Buttons done" << STD_endl; this->showNormal(); geometryChanged(); } void GeoEditView::geometryChanged() { Log odinlog("GeoEditView","geometryChanged"); geometry_cache.update(); ODINLOG(odinlog,normalDebug) << "update done" << STD_endl; geometryMode mode=geometry_cache.get_Mode(); if(old_mode!=mode) { if(old_mode!=n_geometry_modes) blockwidget[old_mode]->hide(); if(blockwidget[mode]==0) blockwidget[mode]=new JDXwidget(geometry_cache,3,this); blockwidget[mode]->show(); grid->add_widget( blockwidget[mode], 1,0, GuiGridLayout::Center, 6,5); connect(blockwidget[mode],SIGNAL(valueChanged()),this,SLOT(geometryChanged())); } blockwidget[mode]->updateWidget(); old_mode=mode; ODINLOG(odinlog,normalDebug) << "JDXwidget done" << STD_endl; for(STD_list::iterator labelit=labels.begin(); labelit!=labels.end(); ++labelit) { (*labelit)->drawImagingArea(geometry_cache,projection->is_on(),crosssect->is_on()); } ODINLOG(odinlog,normalDebug) << "labels->drawImagingArea done" << STD_endl; } void GeoEditView::emitDone() { emit donePressed(); } void GeoEditView::sagSet() { geometry_cache.set_orientation(sagittal); geometryChanged(); } void GeoEditView::corSet() { geometry_cache.set_orientation(coronal); geometryChanged(); } void GeoEditView::axiSet() { geometry_cache.set_orientation(axial); geometryChanged(); } void GeoEditView::magnify(int index) { Image& img=pilot_cache.get_image(index); STD_string tmpdir=STD_string(secure_getenv("HOME"))+SEPARATOR_STR+".odin"+SEPARATOR_STR+"tmp"+SEPARATOR_STR; createdir(tmpdir.c_str()); STD_string tmpfname=tmpdir+"image4geo.jdx"; img.write(tmpfname); system(("miview -blowup "+itos(coarse)+" "+tmpfname+" &").c_str()); } odin-1.8.5/replacements/0000755000175000017500000000000011735135552012150 500000000000000odin-1.8.5/replacements/Makefile.am0000644000175000017500000000010011322062345014102 00000000000000EXTRA_DIST = cxxwrapper.cpp toolwrapper.cpp gsl_replacement.cpp odin-1.8.5/replacements/Makefile.in0000644000175000017500000002275411734622602014143 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = replacements DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ EXTRA_DIST = cxxwrapper.cpp toolwrapper.cpp gsl_replacement.cpp all: all-am .SUFFIXES: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu replacements/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu replacements/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs tags: TAGS TAGS: ctags: CTAGS CTAGS: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile installdirs: install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-generic dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: .MAKE: install-am install-strip .PHONY: all all-am check check-am clean clean-generic clean-libtool \ distclean distclean-generic distclean-libtool distdir dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/replacements/toolwrapper.cpp0000644000175000017500000000145211322062345015143 00000000000000#include #include #include // Win-style process handling #include #include #include using namespace std; int main(int argc, char* argv[]) { string tool; string toolpath; #include "toolwrapper_config.h" // add path for ppc-compiler binaries string newpath="PATH="+toolpath; const char* oldpath_ptr=getenv("PATH"); if(oldpath_ptr) { string oldpath=oldpath_ptr; // remove blanks which make ccppc fail while(oldpath.find("; ")!=string::npos) oldpath.replace(oldpath.find("; "),2,";"); while(oldpath.find(" ;")!=string::npos) oldpath.replace(oldpath.find(" ;"),2,";"); newpath+=";"+string(oldpath); } _putenv(newpath.c_str()); argv[0]=(char*)tool.c_str(); return _spawnv( _P_WAIT, tool.c_str(), argv ); } odin-1.8.5/replacements/cxxwrapper.cpp0000644000175000017500000000607111322062345014772 00000000000000/** * Since the compiler for MPCU does not create executables directly, * using autoconf is not straighforward. Instead we have to wrap the * compiler for the MPCU into this program to create dummy files * instead of actual executables. */ #include #include #include // Win-style process handling #include #include #include using namespace std; int main(int argc, char* argv[]) { string cxx; string cxxpath; #include "cxxwrapper_config.h" // check if we only compile, i.e. have the -c flag bool only_compile=false; for(int i=1; icache = 0; a->hit_count = 0; a->miss_count = 0; return a; } gsl_interp* gsl_interp_alloc (const gsl_interp_type * T, size_t size) { if (size < T->min_size) { STD_cerr << "gsl_interp_alloc: insufficient number of points for interpolation type" << STD_endl; return 0; } gsl_interp * interp=new gsl_interp; interp->type = T; interp->size = size; if (interp->type->alloc == NULL) { interp->state = NULL; return interp; } interp->state = interp->type->alloc(size); if (interp->state == NULL) { delete interp; STD_cerr << "gsl_interp_alloc: failed to allocate space for interp state" << STD_endl; return 0; } return interp; } gsl_spline* gsl_spline_alloc (const gsl_interp_type * T, size_t size) { gsl_spline * spline = new gsl_spline; spline->interp = gsl_interp_alloc (T, size); if (spline->interp == NULL) { delete spline; STD_cerr << "gsl_interp_alloc: failed to allocate space for interp" << STD_endl; return 0; } spline->x = new double[size]; spline->y = new double[size]; spline->size = size; return spline; } int gsl_interp_init (gsl_interp * interp, const double x_array[], const double y_array[], size_t size) { if (size != interp->size) { STD_cerr << "gsl_interp_init: data must match size of interpolation object" << STD_endl; } interp->xmin = x_array[0]; interp->xmax = x_array[size - 1]; int status = interp->type->init(interp->state, x_array, y_array, size); return status; } int gsl_spline_init (gsl_spline * spline, const double x_array[], const double y_array[], size_t size) { if (size != spline->size) { STD_cerr << "gsl_spline_init: data must match size of spline object" << STD_endl; } memcpy (spline->x, x_array, size * sizeof(double)); memcpy (spline->y, y_array, size * sizeof(double)); int status = gsl_interp_init (spline->interp, x_array, y_array, size); return status; } void gsl_interp_accel_free(gsl_interp_accel * a) {delete a;} void gsl_interp_free (gsl_interp * interp) { if (interp->type->free) interp->type->free (interp->state); delete interp; } void gsl_spline_free (gsl_spline * spline) { gsl_interp_free (spline->interp); delete[] spline->x; delete[] spline->y; delete spline; } /////////////////////////////////////////////////////////////////////// double gsl_interp_eval (const gsl_interp * interp, const double xa[], const double ya[], double x, gsl_interp_accel * a) { double y; int status = interp->type->eval (interp->state, xa, ya, interp->size, x, a, &y); // DISCARD_STATUS(status); return y; } double gsl_spline_eval (const gsl_spline * spline, double x, gsl_interp_accel * a) { return gsl_interp_eval (spline->interp, spline->x, spline->y, x, a); } /////////////////////////////////////////////////////////////////////// size_t gsl_interp_bsearch ( const double x_array[], double x, size_t index_lo, size_t index_hi ) { size_t ilo = index_lo; size_t ihi = index_hi; while (ihi > ilo + 1) { size_t i = (ihi + ilo) / 2; if (x_array[i] > x) ihi = i; else ilo = i; } return ilo; } /////////////////////////////////////////////////////////////////////// size_t gsl_interp_accel_find (gsl_interp_accel * a, const double xa[], size_t len, double x) { size_t x_index = a->cache; if (x < xa[x_index]) { a->miss_count++; a->cache = gsl_interp_bsearch (xa, x, 0, x_index); } else if (x > xa[x_index + 1]) { a->miss_count++; a->cache = gsl_interp_bsearch (xa, x, x_index, len - 1); } else { a->hit_count++; } return a->cache; } /////////////////////////////////////////////////////////////////////// static inline double integ_eval (double ai, double bi, double ci, double di, double xi, double a, double b) { const double t0 = b + a; const double t1 = a * a + a * b + b * b; const double t2 = a * a * a + a * a * b + b * b * a + b * b * b; const double bterm = 0.5 * bi * (t0 - 2.0 * xi); const double cterm = ci / 3.0 * (t1 - 3.0 * xi * (t0 - xi)); const double dterm = di / 4.0 * (t2 - 2.0 * xi * (2.0 * t1 - xi * (3.0 * t0 - 2.0 * xi))); return (b - a) * (ai + bterm + cterm + dterm); } /////////////////////////////////////////////////////////////////////// typedef struct { double * b; double * c; double * d; double * _m; } akima_state_t; /* common creation */ static void * akima_alloc (size_t size) { akima_state_t *state = new akima_state_t; state->b = new double[size]; state->c = new double[size]; state->d = new double[size]; state->_m = new double[size + 4]; return state; } /* common calculation */ static void akima_calc (const double x_array[], double b[], double c[], double d[], size_t size, double m[]) { size_t i; for (i = 0; i < (size - 1); i++) { const double NE = fabs (m[i + 1] - m[i]) + fabs (m[i - 1] - m[i - 2]); if (NE == 0.0) { b[i] = m[i]; c[i] = 0.0; d[i] = 0.0; } else { const double h_i = x_array[i + 1] - x_array[i]; const double NE_next = fabs (m[i + 2] - m[i + 1]) + fabs (m[i] - m[i - 1]); const double alpha_i = fabs (m[i - 1] - m[i - 2]) / NE; double alpha_ip1; double tL_ip1; if (NE_next == 0.0) { tL_ip1 = m[i]; } else { alpha_ip1 = fabs (m[i] - m[i - 1]) / NE_next; tL_ip1 = (1.0 - alpha_ip1) * m[i] + alpha_ip1 * m[i + 1]; } b[i] = (1.0 - alpha_i) * m[i - 1] + alpha_i * m[i]; c[i] = (3.0 * m[i] - 2.0 * b[i] - tL_ip1) / h_i; d[i] = (b[i] + tL_ip1 - 2.0 * m[i]) / (h_i * h_i); } } } static int akima_init (void * vstate, const double x_array[], const double y_array[], size_t size) { akima_state_t *state = (akima_state_t *) vstate; double * m = state->_m + 2; /* offset so we can address the -1,-2 components */ size_t i; for (i = 0; i <= size - 2; i++) { m[i] = (y_array[i + 1] - y_array[i]) / (x_array[i + 1] - x_array[i]); } /* non-periodic boundary conditions */ m[-2] = 3.0 * m[0] - 2.0 * m[1]; m[-1] = 2.0 * m[0] - m[1]; m[size - 1] = 2.0 * m[size - 2] - m[size - 3]; m[size] = 3.0 * m[size - 2] - 2.0 * m[size - 3]; akima_calc (x_array, state->b, state->c, state->d, size, m); return GSL_SUCCESS; } static void akima_free (void * vstate) { akima_state_t *state = (akima_state_t *) vstate; delete[] (state->b); delete[] (state->c); delete[] (state->d); delete[] (state->_m); delete (state); } static int akima_eval (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *y) { const akima_state_t *state = (const akima_state_t *) vstate; size_t index; if (a != 0) { index = gsl_interp_accel_find (a, x_array, size, x); } else { index = gsl_interp_bsearch (x_array, x, 0, size - 1); } /* evaluate */ { const double x_lo = x_array[index]; const double delx = x - x_lo; const double b = state->b[index]; const double c = state->c[index]; const double d = state->d[index]; *y = y_array[index] + delx * (b + delx * (c + d * delx)); return GSL_SUCCESS; } } static int akima_eval_deriv (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *dydx) { const akima_state_t *state = (const akima_state_t *) vstate; size_t index; // DISCARD_POINTER(y_array); /* prevent warning about unused parameter */ if (a != 0) { index = gsl_interp_accel_find (a, x_array, size, x); } else { index = gsl_interp_bsearch (x_array, x, 0, size - 1); } /* evaluate */ { double x_lo = x_array[index]; double delx = x - x_lo; double b = state->b[index]; double c = state->c[index]; double d = state->d[index]; *dydx = b + delx * (2.0 * c + 3.0 * d * delx); return GSL_SUCCESS; } } static int akima_eval_deriv2 (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *y_pp) { const akima_state_t *state = (const akima_state_t *) vstate; size_t index; // DISCARD_POINTER(y_array); /* prevent warning about unused parameter */ if (a != 0) { index = gsl_interp_accel_find (a, x_array, size, x); } else { index = gsl_interp_bsearch (x_array, x, 0, size - 1); } /* evaluate */ { const double x_lo = x_array[index]; const double delx = x - x_lo; const double c = state->c[index]; const double d = state->d[index]; *y_pp = 2.0 * c + 6.0 * d * delx; return GSL_SUCCESS; } } static int akima_eval_integ (const void * vstate, const double x_array[], const double y_array[], size_t size, gsl_interp_accel * acc, double a, double b, double * result) { const akima_state_t *state = (const akima_state_t *) vstate; size_t i, index_a, index_b; if (acc != 0) { index_a = gsl_interp_accel_find (acc, x_array, size, a); index_b = gsl_interp_accel_find (acc, x_array, size, b); } else { index_a = gsl_interp_bsearch (x_array, a, 0, size - 1); index_b = gsl_interp_bsearch (x_array, b, 0, size - 1); } *result = 0.0; /* interior intervals */ for(i=index_a; i<=index_b; i++) { const double x_hi = x_array[i + 1]; const double x_lo = x_array[i]; const double y_lo = y_array[i]; const double dx = x_hi - x_lo; if(dx != 0.0) { if (i == index_a || i == index_b) { double x1 = (i == index_a) ? a : x_lo; double x2 = (i == index_b) ? b : x_hi; *result += integ_eval (y_lo, state->b[i], state->c[i], state->d[i], x_lo, x1, x2); } else { *result += dx * (y_lo + dx*(0.5*state->b[i] + dx*(state->c[i]/3.0 + 0.25*state->d[i]*dx))); } } else { *result = 0.0; return GSL_FAILURE; } } return GSL_SUCCESS; } static const gsl_interp_type akima_type = { "akima", 5, &akima_alloc, &akima_init, &akima_eval, &akima_eval_deriv, &akima_eval_deriv2, &akima_eval_integ, &akima_free }; const gsl_interp_type * gsl_interp_akima = &akima_type; /////////////////////////////////////////////////////////////////// static int linear_init (void * vstate, const double x_array[], const double y_array[], size_t size) { return GSL_SUCCESS; } static int linear_eval (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *y) { double x_lo, x_hi; double y_lo, y_hi; double dx; size_t index; if (a != 0) { index = gsl_interp_accel_find (a, x_array, size, x); } else { index = gsl_interp_bsearch (x_array, x, 0, size - 1); } /* evaluate */ x_lo = x_array[index]; x_hi = x_array[index + 1]; y_lo = y_array[index]; y_hi = y_array[index + 1]; dx = x_hi - x_lo; if (dx > 0.0) { *y = y_lo + (x - x_lo) / dx * (y_hi - y_lo); return GSL_SUCCESS; } else { *y = 0.0; return GSL_EINVAL; } } static int linear_eval_deriv (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *dydx) { double x_lo, x_hi; double y_lo, y_hi; double dx; double dy; size_t index; if (a != 0) { index = gsl_interp_accel_find (a, x_array, size, x); } else { index = gsl_interp_bsearch (x_array, x, 0, size - 1); } /* evaluate */ x_lo = x_array[index]; x_hi = x_array[index + 1]; y_lo = y_array[index]; y_hi = y_array[index + 1]; dx = x_hi - x_lo; dy = y_hi - y_lo; if (dx > 0.0) { *dydx = dy / dx;; return GSL_SUCCESS; } else { *dydx = 0.0; return GSL_EINVAL; } } static int linear_eval_deriv2 (const void * vstate, const double x_array[], const double y_array[], size_t size, double x, gsl_interp_accel * a, double *y_pp) { *y_pp = 0.0; return GSL_SUCCESS; } static int linear_eval_integ (const void * vstate, const double x_array[], const double y_array[], size_t size, gsl_interp_accel * acc, double a, double b, double * result) { size_t i, index_a, index_b; if (acc != 0) { index_a = gsl_interp_accel_find (acc, x_array, size, a); index_b = gsl_interp_accel_find (acc, x_array, size, b); } else { index_a = gsl_interp_bsearch (x_array, a, 0, size - 1); index_b = gsl_interp_bsearch (x_array, b, 0, size - 1); } /* endpoints span more than one interval */ *result = 0.0; /* interior intervals */ for(i=index_a; i<=index_b; i++) { const double x_hi = x_array[i + 1]; const double x_lo = x_array[i]; const double y_lo = y_array[i]; const double y_hi = y_array[i + 1]; const double dx = x_hi - x_lo; if(dx != 0.0) { if (i == index_a || i == index_b) { double x1 = (i == index_a) ? a : x_lo; double x2 = (i == index_b) ? b : x_hi; const double D = (y_hi-y_lo)/dx; *result += (x2-x1) * (y_lo + 0.5*D*((x2-x_lo)+(x1-x_lo))); } else { *result += 0.5 * dx * (y_lo + y_hi); } } } return GSL_SUCCESS; } static const gsl_interp_type linear_type = { "linear", 2, NULL, /* alloc, not applicable */ &linear_init, &linear_eval, &linear_eval_deriv, &linear_eval_deriv2, &linear_eval_integ, NULL, /* free, not applicable */ }; const gsl_interp_type * gsl_interp_linear = &linear_type; /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// odin-1.8.5/Makefile.am0000644000175000017500000000566511455553545011463 00000000000000SUBDIRS = tjutils odinpara odinseq odinqt odindata odin pulsar geoedit miview odinreco cmdline-utils sequences samples coils docs replacements EXTRA_DIST = 00odin.h odin.doxygen odin.nsi install.win install.macos TESTS = cmdline-utils/odintestsuite test: install $(TESTPREFIXCMD) ${prefix}/bin/odintestsuite $(MAKE) -C sequences test $(MAKE) -C odinreco test $(MAKE) -C docs/tutorials test manual: all $(PACKAGE).doxygen $(MAKE) -C cmdline-utils manual $(MAKE) -C miview manual $(MAKE) -C odinreco manual doxygen $(PACKAGE).doxygen release: test ! # Please make sure that you have done the following before continuing test ! # - updated versions in configure.in test ! # - updated ChangeLog test ! # - executed svn copy https://od1n.svn.sourceforge.net/svnroot/od1n/trunk/odin https://od1n.svn.sourceforge.net/svnroot/od1n/tags/release_x_y_z -m "Release message" test ! # Press to continue read DUMMY $(MAKE) dist PLATFORMS=StandAlone test ! ########### Generating source dist ############### rm -f */*.1 rm -rf $(PACKAGE)-homepage mkdir -p $(PACKAGE)-homepage rm -rf $(PACKAGE)-upload mkdir -p $(PACKAGE)-upload cp $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-upload test ! ########### Generating manual #################### $(MAKE) manual mv manual $(PACKAGE)-homepage test ! ########### Generating tutorial ################## $(MAKE) -C docs/tutorials main.pdf mv docs/tutorials/main.pdf $(PACKAGE)-homepage/odintut.pdf test ! ########### Generating homepage ################## rm -f docs/homepage/*.html $(MAKE) -C docs/homepage homepage cp docs/homepage/*.html docs/homepage/*.jpg docs/homepage/*.png ChangeLog $(PACKAGE)-homepage convert -resize 16x16 docs/homepage/favicon.png $(PACKAGE)-homepage/favicon.ico admin/sitemap.sh $(PACKAGE)-homepage http://od1n.sourceforge.net test ! ########### Success ! ############################ test ! # test ! # Copy content of directory $(PACKAGE)-homepage to wodan,od1n@web.sourceforge.net:/home/groups/o/od/od1n/htdocs/ (via scp) # test ! # Copy content of directory $(PACKAGE)-upload to wodan@frs.sourceforge.net:uploads (via sftp) test ! # Upload content of directory $(PACKAGE)-upload via webinterface test ! # install-data-local: for platform in $(PLATFORMS) ; do \ if test -f $(srcdir)/platforms/$$platform/HOWTO.txt ; then \ mkdir -p ${prefix}/share/doc/odin/$$platform ; \ cp $(srcdir)/platforms/$$platform/HOWTO.txt ${prefix}/share/doc/odin/$$platform/ ; \ fi ; \ done uninstall-local: -rm -rf ${prefix}/share/doc/odin dist-hook: mkdir -p $(distdir)/platforms for platform in $(PLATFORMS) ; do \ cp -r $(srcdir)/platforms/$$platform $(distdir)/platforms ; \ done rm -rf `find $(distdir)/platforms -name .svn` distclean-local: -rm -rf manual $(PACKAGE)-$(VERSION).tar.gz svnclean: distclean for entry in $$(svn status | grep ^? | grep -v platforms/ | awk '{print $$2}') ; do \ echo "Removing non-SVN file/directory $$entry"; \ rm -rf $$entry; \ done odin-1.8.5/Makefile.in0000644000175000017500000006665211734622602011466 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = . DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \ ChangeLog INSTALL NEWS TODO config.guess config.sub depcomp \ install-sh ltmain.sh missing ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \ html-recursive info-recursive install-data-recursive \ install-dvi-recursive install-exec-recursive \ install-html-recursive install-info-recursive \ install-pdf-recursive install-ps-recursive install-recursive \ installcheck-recursive installdirs-recursive pdf-recursive \ ps-recursive uninstall-recursive RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \ distdir dist dist-all distcheck ETAGS = etags CTAGS = ctags am__tty_colors = \ red=; grn=; lgn=; blu=; std= DIST_SUBDIRS = $(SUBDIRS) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ { test ! -d "$(distdir)" \ || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -fr "$(distdir)"; }; } am__relativize = \ dir0=`pwd`; \ sed_first='s,^\([^/]*\)/.*$$,\1,'; \ sed_rest='s,^[^/]*/*,,'; \ sed_last='s,^.*/\([^/]*\)$$,\1,'; \ sed_butlast='s,/*[^/]*$$,,'; \ while test -n "$$dir1"; do \ first=`echo "$$dir1" | sed -e "$$sed_first"`; \ if test "$$first" != "."; then \ if test "$$first" = ".."; then \ dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ else \ first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ if test "$$first2" = "$$first"; then \ dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ else \ dir2="../$$dir2"; \ fi; \ dir0="$$dir0"/"$$first"; \ fi; \ fi; \ dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ done; \ reldir="$$dir2" DIST_ARCHIVES = $(distdir).tar.gz GZIP_ENV = --best distuninstallcheck_listfiles = find . -type f -print distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = tjutils odinpara odinseq odinqt odindata odin pulsar geoedit miview odinreco cmdline-utils sequences samples coils docs replacements EXTRA_DIST = 00odin.h odin.doxygen odin.nsi install.win install.macos TESTS = cmdline-utils/odintestsuite all: all-recursive .SUFFIXES: am--refresh: @: $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ echo ' cd $(srcdir) && $(AUTOMAKE) --gnu'; \ $(am__cd) $(srcdir) && $(AUTOMAKE) --gnu \ && exit 0; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck $(top_srcdir)/configure: $(am__configure_deps) $(am__cd) $(srcdir) && $(AUTOCONF) $(ACLOCAL_M4): $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs distclean-libtool: -rm -f libtool config.lt # This directory's subdirectories are mostly independent; you can cd # into them and run `make' without going through this Makefile. # To change the values of `make' variables: instead of editing Makefiles, # (1) if the variable is set in `config.status', edit `config.status' # (which will cause the Makefiles to be regenerated when you run `make'); # (2) otherwise, pass the desired values on the `make' command line. $(RECURSIVE_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ list='$(SUBDIRS)'; for subdir in $$list; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ dot_seen=yes; \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done; \ if test "$$dot_seen" = "no"; then \ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ fi; test -z "$$fail" $(RECURSIVE_CLEAN_TARGETS): @fail= failcom='exit 1'; \ for f in x $$MAKEFLAGS; do \ case $$f in \ *=* | --[!k]*);; \ *k*) failcom='fail=yes';; \ esac; \ done; \ dot_seen=no; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ rev=''; for subdir in $$list; do \ if test "$$subdir" = "."; then :; else \ rev="$$subdir $$rev"; \ fi; \ done; \ rev="$$rev ."; \ target=`echo $@ | sed s/-recursive//`; \ for subdir in $$rev; do \ echo "Making $$target in $$subdir"; \ if test "$$subdir" = "."; then \ local_target="$$target-am"; \ else \ local_target="$$target"; \ fi; \ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ || eval $$failcom; \ done && test -z "$$fail" tags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ done ctags-recursive: list='$(SUBDIRS)'; for subdir in $$list; do \ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \ done ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ include_option=--etags-include; \ empty_fix=.; \ else \ include_option=--include; \ empty_fix=; \ fi; \ list='$(SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test ! -f $$subdir/TAGS || \ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ fi; \ done; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ $(am__tty_colors); \ if test -n "$$list"; then \ for tst in $$list; do \ if test -f ./$$tst; then dir=./; \ elif test -f $$tst; then dir=; \ else dir="$(srcdir)/"; fi; \ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ col=$$red; res=XPASS; \ ;; \ *) \ col=$$grn; res=PASS; \ ;; \ esac; \ elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ col=$$lgn; res=XFAIL; \ ;; \ *) \ failed=`expr $$failed + 1`; \ col=$$red; res=FAIL; \ ;; \ esac; \ else \ skip=`expr $$skip + 1`; \ col=$$blu; res=SKIP; \ fi; \ echo "$${col}$$res$${std}: $$tst"; \ done; \ if test "$$all" -eq 1; then \ tests="test"; \ All=""; \ else \ tests="tests"; \ All="All "; \ fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ banner="$$All$$all $$tests passed"; \ else \ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ banner="$$failed of $$all $$tests failed"; \ else \ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ if test "$$skip" -eq 1; then \ skipped="($$skip test was not run)"; \ else \ skipped="($$skip tests were not run)"; \ fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ report=""; \ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ report="Please report to $(PACKAGE_BUGREPORT)"; \ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$report"; \ fi; \ dashes=`echo "$$dashes" | sed s/./=/g`; \ if test "$$failed" -eq 0; then \ echo "$$grn$$dashes"; \ else \ echo "$$red$$dashes"; \ fi; \ echo "$$banner"; \ test -z "$$skipped" || echo "$$skipped"; \ test -z "$$report" || echo "$$report"; \ echo "$$dashes$$std"; \ test "$$failed" -eq 0; \ else :; fi distdir: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ fi; \ done @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ if test "$$subdir" = .; then :; else \ dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ $(am__relativize); \ new_distdir=$$reldir; \ dir1=$$subdir; dir2="$(top_distdir)"; \ $(am__relativize); \ new_top_distdir=$$reldir; \ echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ ($(am__cd) $$subdir && \ $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$$new_top_distdir" \ distdir="$$new_distdir" \ am__remove_distdir=: \ am__skip_length_check=: \ am__skip_mode_fix=: \ distdir) \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook -test -n "$(am__skip_mode_fix)" \ || find "$(distdir)" -type d ! -perm -755 \ -exec chmod u+rwx,go+rx {} \; -o \ ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 $(am__remove_distdir) dist-lzma: distdir tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma $(am__remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz $(am__remove_distdir) dist-tarZ: distdir tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__remove_distdir) dist-shar: distdir shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__remove_distdir) dist dist-all: distdir tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz $(am__remove_distdir) # This target untars the dist file and tries a VPATH configuration. Then # it guarantees that the distribution is self-contained by making another # tarfile. distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lzma*) \ lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\ *.tar.xz*) \ xz -dc $(distdir).tar.xz | $(am__untar) ;;\ *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ esac chmod -R a-w $(distdir); chmod a+w $(distdir) mkdir $(distdir)/_build mkdir $(distdir)/_inst chmod a-w $(distdir) test -d $(distdir)/_build || exit 0; \ dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ && am__cwd=`pwd` \ && $(am__cd) $(distdir)/_build \ && ../configure --srcdir=.. --prefix="$$dc_install_base" \ $(DISTCHECK_CONFIGURE_FLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) \ && $(MAKE) $(AM_MAKEFLAGS) dvi \ && $(MAKE) $(AM_MAKEFLAGS) check \ && $(MAKE) $(AM_MAKEFLAGS) install \ && $(MAKE) $(AM_MAKEFLAGS) installcheck \ && $(MAKE) $(AM_MAKEFLAGS) uninstall \ && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ distuninstallcheck \ && chmod -R a-w "$$dc_install_base" \ && ({ \ (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ } || { rm -rf "$$dc_destdir"; exit 1; }) \ && rm -rf "$$dc_destdir" \ && $(MAKE) $(AM_MAKEFLAGS) dist \ && rm -rf $(DIST_ARCHIVES) \ && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \ && cd "$$am__cwd" \ || exit 1 $(am__remove_distdir) @(echo "$(distdir) archives ready for distribution: "; \ list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x' distuninstallcheck: @$(am__cd) '$(distuninstallcheck_dir)' \ && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ || { echo "ERROR: files left after uninstall:" ; \ if test -n "$(DESTDIR)"; then \ echo " (check DESTDIR support)"; \ fi ; \ $(distuninstallcheck_listfiles) ; \ exit 1; } >&2 distcleancheck: distclean @if test '$(srcdir)' = . ; then \ echo "ERROR: distcleancheck can only run from a VPATH build" ; \ exit 1 ; \ fi @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ || { echo "ERROR: files left in build directory after distclean:" ; \ $(distcleancheck_listfiles) ; \ exit 1; } >&2 check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-recursive all-am: Makefile installdirs: installdirs-recursive installdirs-am: install: install-recursive install-exec: install-exec-recursive install-data: install-data-recursive uninstall: uninstall-recursive install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-recursive install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -f Makefile distclean-am: clean-am distclean-generic distclean-libtool \ distclean-local distclean-tags dvi: dvi-recursive dvi-am: html: html-recursive html-am: info: info-recursive info-am: install-data-am: install-data-local install-dvi: install-dvi-recursive install-dvi-am: install-exec-am: install-html: install-html-recursive install-html-am: install-info: install-info-recursive install-info-am: install-man: install-pdf: install-pdf-recursive install-pdf-am: install-ps: install-ps-recursive install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive mostlyclean-am: mostlyclean-generic mostlyclean-libtool pdf: pdf-recursive pdf-am: ps: ps-recursive ps-am: uninstall-am: uninstall-local .MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) check-am \ ctags-recursive install-am install-strip tags-recursive .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \ all all-am am--refresh check check-TESTS check-am clean \ clean-generic clean-libtool ctags ctags-recursive dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzma dist-shar \ dist-tarZ dist-xz dist-zip distcheck distclean \ distclean-generic distclean-libtool distclean-local \ distclean-tags distcleancheck distdir distuninstallcheck dvi \ dvi-am html html-am info info-am install install-am \ install-data install-data-am install-data-local install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am install-man \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ installdirs-am maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ ps ps-am tags tags-recursive uninstall uninstall-am \ uninstall-local test: install $(TESTPREFIXCMD) ${prefix}/bin/odintestsuite $(MAKE) -C sequences test $(MAKE) -C odinreco test $(MAKE) -C docs/tutorials test manual: all $(PACKAGE).doxygen $(MAKE) -C cmdline-utils manual $(MAKE) -C miview manual $(MAKE) -C odinreco manual doxygen $(PACKAGE).doxygen release: test ! # Please make sure that you have done the following before continuing test ! # - updated versions in configure.in test ! # - updated ChangeLog test ! # - executed svn copy https://od1n.svn.sourceforge.net/svnroot/od1n/trunk/odin https://od1n.svn.sourceforge.net/svnroot/od1n/tags/release_x_y_z -m "Release message" test ! # Press to continue read DUMMY $(MAKE) dist PLATFORMS=StandAlone test ! ########### Generating source dist ############### rm -f */*.1 rm -rf $(PACKAGE)-homepage mkdir -p $(PACKAGE)-homepage rm -rf $(PACKAGE)-upload mkdir -p $(PACKAGE)-upload cp $(PACKAGE)-$(VERSION).tar.gz $(PACKAGE)-upload test ! ########### Generating manual #################### $(MAKE) manual mv manual $(PACKAGE)-homepage test ! ########### Generating tutorial ################## $(MAKE) -C docs/tutorials main.pdf mv docs/tutorials/main.pdf $(PACKAGE)-homepage/odintut.pdf test ! ########### Generating homepage ################## rm -f docs/homepage/*.html $(MAKE) -C docs/homepage homepage cp docs/homepage/*.html docs/homepage/*.jpg docs/homepage/*.png ChangeLog $(PACKAGE)-homepage convert -resize 16x16 docs/homepage/favicon.png $(PACKAGE)-homepage/favicon.ico admin/sitemap.sh $(PACKAGE)-homepage http://od1n.sourceforge.net test ! ########### Success ! ############################ test ! # test ! # Copy content of directory $(PACKAGE)-homepage to wodan,od1n@web.sourceforge.net:/home/groups/o/od/od1n/htdocs/ (via scp) # test ! # Copy content of directory $(PACKAGE)-upload to wodan@frs.sourceforge.net:uploads (via sftp) test ! # Upload content of directory $(PACKAGE)-upload via webinterface test ! # install-data-local: for platform in $(PLATFORMS) ; do \ if test -f $(srcdir)/platforms/$$platform/HOWTO.txt ; then \ mkdir -p ${prefix}/share/doc/odin/$$platform ; \ cp $(srcdir)/platforms/$$platform/HOWTO.txt ${prefix}/share/doc/odin/$$platform/ ; \ fi ; \ done uninstall-local: -rm -rf ${prefix}/share/doc/odin dist-hook: mkdir -p $(distdir)/platforms for platform in $(PLATFORMS) ; do \ cp -r $(srcdir)/platforms/$$platform $(distdir)/platforms ; \ done rm -rf `find $(distdir)/platforms -name .svn` distclean-local: -rm -rf manual $(PACKAGE)-$(VERSION).tar.gz svnclean: distclean for entry in $$(svn status | grep ^? | grep -v platforms/ | awk '{print $$2}') ; do \ echo "Removing non-SVN file/directory $$entry"; \ rm -rf $$entry; \ done # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/00odin.h0000644000175000017500000007126011734622163010654 00000000000000/** * \page odinseq_doc ODIN sequence modelling framework (odinseq library) * * This page describes the design guidelines of the module \ref odinseq * * \section odinseq_intro Introduction * This is a framework for NMR sequence design. It follows * a hardware independent, object oriented design approach to * reach a high degree of flexibilty and portability while * keeping the amount of source code to a minimum. * * \section motivation Motivation * An NMR sequence typically consists of different components * like pulses, gradient shapes and so on. From the physicists * point of view these objects and their relations can be exclusively * described by physical parameters (pulse duration, gradient stength, * echo time, ...). This description does not depend on the current * hardware the sequence is used on. * Furthermore, at this level of abstraction these objects can * be grouped together in different ways to form a variety of NMR * sequences. * * Unfortunately most programming enviroments of contemporary * spectrometers/scanners do not reflect this modularity. A sequence * written in the native enviroment of the machine often contains * a vast amount of redundant source code repeated in every method * and a difficult low-level interface. * Furthermore each manufacturer follows his own approach to write * unportable sequences, which may be a disadvantage for scientists * working on different spectrometers. * * This is the point where this framework could come into play. * It offers a hardware independent programming interface to a C++ * class library. This library then performs all the low-level * operations that are required for playing out the sequence. * * \section design Design Principles * The class hierachy (\ref odinseq) is designed according to the following guidelines: * * \subsection design_hierachy Class Hierachy * Each type of component in an NMR sequence (RF-pulse, gradient pulse, ...) * is identified with a class in the C++ programming language. * The components are ordered in a 'family tree' where each child * is a specialisation of its parent. For instance a constant * gradient (SeqGradConst) on one of the gradient channels has a parent * (SeqGradChan) that represents arbitrarily shaped gradient waveforms. * This inheritance graph is modelled by the inheritence mechanisms for * classes in C++. This approach minimises the amount of code that perform * certain operations on the objects, e.g. a function for * rotating the SeqGradChan class in the spatial domain (set_gradrotmatrix()) * is automatically available for all derived classes. * * \subsection design_seqobj Sequence Objects * In this manual the term 'sequence objects' refers to all components * of an NMR experiment that control the timing of the sequence. * For example RF-pulses, delays and acquisition windows are all specialised * sequence objects. * An (abstract) base class SeqObjBase exists for all sequence objects. * These objects then have a common * interface, e.g. they know how to write themselve to the pulse/gradient * program. * * \subsection design_seqgradobj Gradient Objects * The term 'gradient objects' refers to all components of an NMR sequence * that control the timecourse of the gradient fields, e.g. constant gradients, * phase encoding gradients, gradient waveforms. * An (abstract) base class SeqGradInterface exists for all gradient objects * in the sequence. These objects * then have a common interface, i.e. they know how to write themselve to the gradient * program or how to be combined among themselves. * * \subsection design_seqgrouping Grouping of Sequence Objects * Sequence objects can be grouped together by ordering them along * the time axis. The result is then a new, more complex sequence object. * In analogy to notations commonly used in scientific papers, this * is done by using the \p + operator. For instance two RF-pulses * represented by two objects called \p alpha and \p beta can build * a new sequence object \verbatim alpha + beta \endverbatim which results in a sequence * object which will play out the first pulse and then the second pulse. * * \subsection design_gradgrouping Grouping of Gradient Objects * Gradient objects can also be serialised by using the \p + operator. Furthermore * the \p / operator tries to build a new object that plays out the two operands * in parallel if the timing is apropriate. For example two gradient pulses * \p gp1 and \p gp2, one for the read and another for the phase channel, can be * played out in parallel by using the combination \verbatim gp1 / gp2 \endverbatim * * \subsection design_seqparallel Combining Sequence and Gradient objects * Sequence and gradient objects can also be serialised by the \p + operator. To * play out a gradient and a sequence object in parallel, the \p / operator can be * used. For example let \p alpha be an excitation pulse and \p constgrad a constant * gradient, then the combination \verbatim alpha / constgrad \endverbatim would * give a slice selective pulse. * * \subsection design_seqcontainer Container for Sequence Objects * The sequence object SeqObjList can be used as a container for other * sequence objects. That is, each SeqObjList can have its own sub-sequence that * consists of other sequence components. * If a certain operation is applied to a SeqObjList object, the operation * will also be applied to all elements of the sub-sequence. For example: * \verbatim SeqPuls alpha; // excitation pulse SeqGradConstPulse constgrad; // constant gradient SeqObjList objlist = alpha + constgrad; // alpha is played out after constgrad \endverbatim * Calling the member function * \verbatim objlist.get_duration() \endverbatim would then return the sum of the durations of \p alpha and \p constgrad. * * \subsection design_seqgradcontainer Container for Gradient Objects * The gradient object SeqGradChanList can be used as a container for other * gradient objects which share the same gradient channel. That is, each SeqGradChanList * can have its own sub-sequence that consists of other gradient components. * These sub-objects are then played out subsequently. * This analogous to the above described sequence container. * * \subsection design_append Appending to Container Objects * New objects can be added to the container class SeqObjList * by using the \p += operator. * * \subsection design_loops Sequence Loops ans Vectors * Loops are special sequence containers. They are used to repeat * a certain part of the sequence. Within ODIN, the class SeqObjLoop * accomplishes this task. Two kind of loops are possible when using * this class: Pure repitition loops and vector loops. Repitition * loops simply repeat the specified part of the sequence without * altering it. Let \p loop be of type SeqObjLoop, then heir syntax is: * \verbatim loop ( kernel ) [ n ]; \endverbatim * This statement will return a sequence object that repeats the sequence * object \p kernel \p n times, where \p n is an integer number. * * Vector loops also repeat a specified part of the sequence. Furthermore * they increment the value of a sequence vector each time it is played out. * Sequence vectors are for example phase encoding gradients or pulses * with a frequency list. All sequence vectors share the same base class * SeqVector. Let \p loop be of type SeqObjLoop, then the syntax for vector loops is: * \verbatim loop ( kernel ) [ vector1 ] [ vector2 ] ...; \endverbatim * This statement will return a sequence object that repeats the sequence * object \p kernel while incrementing the values of the attached sequence * vectors \p vector1, \p vector2, ... * The vectors must contain the same number of values. The loop is then * repeated this number of times. * * \subsection design_vectors Specialialized Sequence Vectors * - Gradient pulses with different gradient strengths for phase encoding or diffusion weighting (SeqGradVectorPulse, SeqGradPhaseEnc). * - Sequence objects that drive the transmitter (RF pulses) or receiver (acquisition windows) * contain two vector objects for frequency and phase switching to be used for multislice * experiments or phase cycling (SeqFreqChan and SeqPhaseListVector). * - Delay objects with a variable duration, which is changed for each iteration (SeqDelayVector). * - A list of user-defined rotation matrices that can be attached to gradient-related objects in order * to alter their direction subsequently (SeqRotMatrixVector). * - A container object that holds a list of other sequence objects which are played out * sequentially for each repetition (SeqObjVector). * * * \section units Physical Units * ODIN is consistent corncerning the physical units. That is, everywhere in the library the * following units and their combinations are used: * - [mT] for magnetic field strength * - [mm] as the spatial unit * - [ms] for durations * * This system has shown to be of practical value for NMR because the numbers are then * in a reasonable range. * For example the gradient strength is then given in mT/mm and the frequency is given in * 1/ms=kHz. * The only exception is the angular unit which is treated internally as rad but can be * specified at the interface functions in degree for phaselists and flipangles. * * * * \section coding Coding Standards * \subsection coding_class Building new classes * If you want to write your own class that can be plugged into the ODIN framework, * please use the following form for your class 'SeqMyClass' that is derived from * 'SeqBaseClass': * \verbatim /////////////// *.h stuff: ////////////////////////////// class SeqMyClass : public SeqBaseClass { public: SeqMyClass(const STD_string& object_label, float parameter1, ... ); SeqMyClass(const STD_string& object_label = "unnamedSeqMyClass" ); SeqMyClass(const SeqMyClass& sct); SeqMyClass& operator = (const SeqMyClass& sct); ~SeqMyClass(); private: float parameter1; }; /////////////// *.cpp stuff: //////////////////////////// SeqMyClass::SeqMyClass(const STD_string& object_label, float parameter1_value, ... ) : SeqBaseClass(object_label) { parameter1=parameter1_value; ... } SeqMyClass::SeqMyClass(const STD_string& object_label ) : SeqBaseClass(object_label) { parameter1=0.0; ... } SeqMyClass::SeqMyClass(const SeqMyClass& sct) { SeqMyClass::operator = (sct); } SeqMyClass& SeqMyClass::operator = (const SeqMyClass& sct) { SeqBaseClass::operator = (sct); parameter1=sct.parameter1; ... return *this; } SeqMyClass::~SeqMyClass() { } \endverbatim * Following this standard prevents the base classes from getting confused by not * correctly initialising or copying them. * * \subsection coding_stl Using the C++ standard library * Unfortunately, on some systems the stanard C++ library seems to be either broken * or absent. For these platforms, ODIN contains its own implementation that is a subset of * the original library. * To use the same source code on different platforms, classes of the standard * library are used together with the prefix STD_, e.g. STD_list * instead of std::list. These macros will be replaced by the appropriate classes on * each platform. * * \subsection coding_debug Debugging/Tracing * To generate debugging and tracing output, please use the Log template class instead * of using streams. * Instances of that class offer a stream to log trace messages via the ODINLOG macro: * \verbatim int MyClass::myfunction() { Log odinlog("MyClass","myfunction"); ODINLOG(odinlog,significantDebug) << "Hello World" << STD_endl; } \endverbatim * Which will result in the following output: * \verbatim Seq | MyClass.myfunction : START Seq | MyClass.myfunction : Hello World Seq | MyClass.myfunction : END \endverbatim * It can generate debugging output at different levels of verbosity * and the output is redirected to the native logging channel (console, log file) of * the current platform. Furthermore, it can be completely removed from the executable * for release compilations in a safe way without changing the source code. */ /** * @defgroup odinseq Classes for sequence design (odinseq library) * * \ref odinseq_doc * */ /** * * @defgroup odinseq_internals Internal Classes for sequence design (odinseq library) * * PLEASE DO NOT USE THESE CLASSES DIRECTLY WHEN WRITING SEQUENCES! */ /////////////////////////////////////////////////////////////////////////////////////// /** * \page tjutils_doc Basic data types, vectors and arrays used by ODIN (tjutils library) * * * \section tjutils_intro Introduction * Well known data types, such as integers, floating point numbers, complex numbers, strings, * vectors (1-dimensional) and arrays (multi-dimensional) are used in ODIN. * For all types discussed in this section, there exists a corresponding JCAMP-DX type (\ref jcampdx). * This JCAMPD-DX type is prefixed by 'JDX' and then the data type, e.g. 'STD_string' has a JCAMP-DX * counterpart 'JDXstring' with the same functionality. * In addition, JCAMP-DX parameters can be assigned a label, grouped together with other JCAMP-DX parameters, etc. * * \section vectors Vectors * Vectors are implemented by the tjvector template class which is * derived from the STL vector class. Its interface is therefore * equivalent to that of the std::vector class. * In addition, some useful functions are added. * Some predefined vector classes are created by using the tjvector * template class: * - fvector: vector of float numbers * - dvector: vector of double precision float numbers * - ivector: vector of int numbers * - svector: vector of strings (STD_string objects) * - cvector: vector of complex numbers (STD_complex objects) * * \section arrays Arrays * Multidimensional arrays are covered by the tjarray template class. * It is derived from the tjvector class to store the data. In addition, * the information about the dimensionality and extent in each dimension * is stored separately in the class by an ndim object. * Some predefined array classes and their corresponding JCAMP-DX type are * created by using the tjarray template class: * - farray / JDXfloatArr: array of float numbers * - darray / JDXdoubleArr: array of double precision float numbers * - iarray / JDXintArr: array of int numbers * - sarray / JDXstringArr: array of strings (STD_string objects) * - carray / JDXcomplexArr: array of complex numbers (STD_complex objects) * * Some examples on how to use these arrays: * \verbatim farray fa1(3,3); // creates a 2-dimensional 3x3 array fa1(0,1)=5.7; // assigns 5.7 to the second element in the firs row farray fa2(3,3); // creates another 2-dimensional 3x3 array fa1+fa2; // returns the element-wise sum of the two arrays fa1.redim(1,2,3); // resizes fa1 to a 3-dimensional 1x2x3 array \endverbatim * Please see the class documention for a complete reference. * */ /** * @defgroup tjutils Classes for basic data types and vectors/arrays (tjutils library) * * \ref tjutils_doc * */ /////////////////////////////////////////////////////////////////////////////////////// /** * @defgroup jcampdx JCAMP-DX implementation (odinpara library) * * This page describes the design guidelines of the module \ref jcampdx * * The following framework can be used to deal with single parameters of different * type (int,float,string,...) and multidimensional arrays that are build from these * base types. It is possible to build blocks of parameter, i.e. parameter lists, * that can be written/loaded to/from disk in an easily editable ASCII format. * The file format is designed roughly according to the JCAMP-DX [1,2] standard, but * its main aim was to be compatible with the PARX[3] file format. * * * A very simple examples on how to use this module: * \verbatim JDXint mynumber(23,"mynumber"); // Create an integer parameter with initial value 23 mynumber+=42; // JDXint can be used just as a native int for arithmetics JcampDxBlock block; // A block (list) of parameters block.append(mynumber); // Append the parameter to the block block.write("block.jdx"); // Write block and its parameters to file 'block.jdx' block.load("block.jdx"); // Load block and its parameters from file 'block.jdx' \endverbatim * Please see the class documention for a complete reference. * * * References: * -# JCAMP-DX: A Standard Form of Exchange of Infrared Spectra in Computer * Readable Form, McDONALD, R.S., WILKS, P.A., Apllied Spectroscopy, * Vol.42, No.1, 1988 * -# JCAMP-DX for NMR, DAVIES, A.N., LAMPEN, P., Apllied Spectroscopy, * Vol.47, No.8, 1993 * -# PARX is a preprocessor/compiler framework to interactively modify parameters * that can also be embedded into C-code. * It is part of the Bruker software 'Paravision' that serves as an user interface * for their medical MR-scanners. * * *@author Thies H. Jochimsen */ /////////////////////////////////////////////////////////////////////////////////////// /** * @defgroup odinpara MR Parameters (odinpara library) * * This page describes the design guidelines of the module \ref odinpara_doc * * *@author Thies H. Jochimsen */ /** * \page odinpara_doc Protcol classes in ODIN (odinpara library) * * This module/library contains a set of classes which describe * different aspects of an MR measurement, i.e. the measurement protocol: * - System: The MR system used * - Geometry: The geometry of the scan * - SeqPars: Common sequence parameters * - Study: Information about the current study (patient data, etc.) * - RecoPars: Parameters for automatic reconstruction * * The class Protocol combines the first four of the above in a single * class for convenient access. * * Within sequence classes, instances of these classes are * accessible via the pointers systemInfo, geometryInfo, * commonPars, studyInfo and recoInfo */ /////////////////////////////////////////////////////////////////////////////////////// /** * \page odindata_doc ODIN data processing framework (odindata library) * * This page describes the design guidelines of the module \ref odindata * * \section blitz4nmr Blitz++ for NMR * The Blitz++ library is great for numerical calculations, but it lacks * some functionality that is crucial when using it together with NMR data: * - Convenient input/output of medical image data * - Numerical routines essential for NMR (FFT, gridding, fitting, ...) * - Associating large data files on disk with arrays in memory * * For this reason, ODIN contains two classes that help dealing with these tasks: * - Data: A template class derived from the Blitz++ Array class that * has the ability to be associated with a raw data file for read and * write access. This is done by using the mmap function so that no extra * memory is allocated on contstruction. Instead, the task of reading/writing * is handled transparently by the operating system. Any changes made * to the array in memory are also visible in the file on disk. With this * mechanism, arrays that are larger than the available RAM can be handled * without extra effort. * In addition, member functions Data::autoread() and Data::autowrite() are available to load/store * the data in different file formats using the FileIO module (\ref fileio_doc ). * * - ComplexData: A template class with a * fixed storage type of complex numbers. It contains useful functions * to deal with NMR data (FFT,...). On construction, it can be * associated with raw data on disk (16bit, 32bit, float) and blocks * of the file can be loaded subsequently into memory for further * processing. * * * \section numerics Common Numerical Operations * * In order to offer a framework for other numerical calculations, * the following functions/classes are available within ODIN: * * \subsection numerics_gridding Gridding * Regridding an array from one Cartesian grid to another can be * done using the Data::congrid() member function. * In addition, the functor Gridding can be used to data from a * non-Cartesian grid to a Cartesian grid. * * \subsection numerics_transform Coordinate Transformation * Transforming an array to a new coordinate system by * rotation, scaling and shifting can be done by using * the CoordTransformation functor. * * \subsection numerics_fft Fourier Transform * FFT of a whole complex data set can be calculated by the ComplexData::fft() member function. * If the FFT has to be applied only for certain dimensions, use ComplexData::partial_fft() * * \subsection numerics_linalg Linear Algebra * The functions solve_linear(), pseudo_inverse() and eigenvalues() will solve a sets of linear equations, * calculate the pseudo inverse and eigenvalues, respectively. * * \subsection numerics_fitting Non-Linear Function Fitting * Fitting of functions is accomplished by the two classes * ModelFunction and FunctionFit. The former is * used as a base class to specify the modelling function * by implementing its virtual functions. * The latter is used to do the actual fitting and to * store temporary data of the fit. * * \subsection numerics_linfit Linear Regression * The class LinearFunction can be used for linear fitting. * * \subsection numerics_polfit Polynomial Fit * The function polyniomial_fit() provides pixel-wise fitting * of polynomials using the values of neighbouring pixels. * * \subsection numerics_integration Integration of Functions * Integration of one-dimensional functions can be achieved * by the two classes Integrand and FunctionIntegral. * The former is used as a base class to specify the function * by implementing a virtual functions. * The latter is used to do the actual integration and to * store temporary data. * * \subsection numerics_statistics Basic Statistics * Simple statistics (mean, standard deviation) can be * calculated by the statistics() function. * * \subsection numerics_correlation Correlation Analysis * Correlation of two vectors can be calculated by * the correlation() function. * * \subsection numerics_fileio Convenient File Input/Output * The functions inside FileIO (\ref fileio_doc ) are a convenient way ro * read/write 4-dim Arrays, a variety of formats common * for medical image are supported. * * * */ /////////////////////////////////////////////////////////////////////////////////////// /** * \page fileio_doc Input/Output of medical image data (odindata library) * * \section fileio A unified approach for handling medical image data * This page describes the functionality of the FileIO module. * * \subsection fileio_intro Introduction * When working with different systems for generating and processing of medical images very quickly one problem arises: These systems use different data formats and the available export features of any toolkit mostly support only a subset of the needed formats. The following report describes an approach to design a unified and extensible interface to medical image data. Implemented in an function library this interface can be used to efficently enable custom-built applications to read and write medical image data. * * \subsection fileio_pdmap The Protocol-Data-Map * Unified access to different data formats implies a common interface for accessing this data. * Thus a data structure, which provides a superset of all features of all data formats which shall be supported. * Every medical image consists of image data of any type and metadata related to this image data. This data pair will be dicussed in the following. * * The metadata * which belong to an image usually describe the technical and administrative characteristics of an image. * They consist of some required information like image dimension and used data type, some common information like the age of the subject or the date the image was taken and some optional information like used field strength for MR data. These parameters are either in a header inside the imagefile or in a separate header file. The required and the common parameter are very usefull to distinguish images. They, and with them the whole metadataset, can be used as a unique key to reference this image. In the following this paremeter set will be called the Protocol. * * Some imagefile formats are only capable of storing at least two-dimensional images. In this case N-dimensional datasets are often stored by using several two-dimensional images. The protocols of these images differ only in the remaining coordinates (which needs to be specified in this case). * The system must recognize this and combine them into one N-dimensional dataset when reading. And the inverse approach appiles to writing N-dimensional data in a fileformat which does not support that many dimensions. * * The pair of protocol and dataset can be used as a universal interface to access image data. * While the protocol offers all information to interpret the data, the dataset serves as a coordinate-based interface to the data for reading and writing. * * Multiple protocol-dataset-pairs can efficiently be stored in a associative container where the protocol is the key which maps to the dataset. This enables the system to handle multiple datasets. A particular dataset can always be referenced by its protocol and a list of the available datasets can be obtained by iterating through this protocol-dataset-map (FileIO::ProtocolDataMap). * Also, when reading multiple low-dimensional image files which are part of an high-dimensional image, they all will have the same protocol and thus will be automaticly sorted into one high-dimensional dataset referenced by this protocol. * * \subsection fileio_formats read and write different file formats * To guarantee the flexibility of the system, the input from and the output to files is done via plugins (classes derived from FileFormat) which use the described protocol-dataset-map as front end. * These plugins are gathered at the initialisation and held in a map with the file suffixes they support as key. If available, they are also referenced by a regular expression to detect the supported format directly from that data. * * The selection of the right plugin is done in two ways. If a fileformat is directly requested, the corresponding plugin is used. If the format is not selected explicitly, the system at first tries to get the suffix of the file requested for read or write and guesses the format. * * Many medical image formats exist in several different dialects or have optional extensions which makes it necessary to fine tune them. Thus every plugin can bring a set of additional parameters which than can be used by the client to modify their behavior. * *@author Enrico Reimer */ /** * @defgroup odindata Classes of the ODIN data processing framework (odindata library) * * \ref odindata_doc * \ref fileio_doc * */ /////////////////////////////////////////////////////////////////////////////////////// /** * @defgroup odinreco The reconstruction framework (odinreco) * * \ref odinreco_doc * */ /////////////////////////////////////////////////////////////////////////////////////// /** * @defgroup odinreco_steps Steps(functors) of the reconstruction framework (odinreco) * * These steps(functors) can be used within the \ref odinreco_doc * */ /////////////////////////////////////////////////////////////////////////////////////// /** * \page cmdline_utils Command-line utilities * * miconv: \ref miconv * * micalc: \ref micalc * * miview: \ref miview * * odinreco: \ref odinreco_usage * * gencoil: \ref gencoil * * genmakefile: \ref genmakefile * * gensample: \ref gensample * * swab: \ref swab */ /////////////////////////////////////////////////////////////////////////////////////// /*! \mainpage ODIN Reference Manual * * * \section quick_start Quick Start * * I want to see documentation about ... * * \ref odin_doc * * \ref cmdline_utils * * \ref odinseq_doc * * \ref odinseq * * \ref odindata_doc * * \ref fileio_doc * * \ref odinreco_doc * * \ref odinreco_steps * * \ref tjutils_doc * * \ref odinpara_doc * * *@author Thies H. Jochimsen */ odin-1.8.5/miview/0000755000175000017500000000000011735135552010766 500000000000000odin-1.8.5/miview/miviewview.cpp0000644000175000017500000004450211734622163013610 00000000000000#include "miviewview.h" #include #include #include #include #include #include #include // for showProtocol #include const char* MiViewComp::get_compName() {return "MiView";} LOGGROUNDWORK(MiViewComp) ///////////////////////////////////////////////////////////////// struct FileData { Data data; Protocol prot; statisticResult stat; }; ///////////////////////////////////////////////////////////////// struct SelectionData { Data roi; // 4D to be suitable for autowrite Data profile; }; ///////////////////////////////////////////////////////////////// MiViewOpts::MiViewOpts() { color=false; color.set_cmdline_option("color").set_description("Use color map to display values"); append_member(color,"color"); contrast=0.0; contrast.set_minmaxval(-100, 100); contrast.set_cmdline_option("contrast").set_description("Relative contrast of display"); append_member(contrast,"Contrast"); brightness=0.0; brightness.set_minmaxval(-100, 100); brightness.set_cmdline_option("bright").set_description("Relative brightness of display"); append_member(brightness,"Brightness"); valfile.set_cmdline_option("val").set_description("Save value of ROI/point selection to this file"); append_member(valfile,"valfile"); recfile.set_cmdline_option("rec").set_description("Record clicked coordinates and values into this file"); append_member(recfile,"recfile"); blowup=1; blowup.set_cmdline_option("blowup").set_description("Enlarge display size by this factor"); append_member(blowup,"blowup"); low.set_cmdline_option("low").set_description("Lower windowing boundary: This value will appear black in display"); append_member(low,"low"); upp.set_cmdline_option("upp").set_description("Upper windowing boundary: This value will appear white in display"); append_member(upp,"upp"); dump.set_cmdline_option("dump").set_description("Dump all images as bitmap(bmp) files and exit, use the given filename prefix"); append_member(dump,"dump"); mapfile.set_cmdline_option("map").set_description("Load overlay map (colored voxels superimposed on image) from this file"); append_member(mapfile,"mapfile"); maplow=0.0; maplow.set_cmdline_option("maplow").set_description("Lower windowing boundary for overlay map"); append_member(maplow,"maplow"); mapupp=0.0; mapupp.set_cmdline_option("mapupp").set_description("Upper windowing boundary for overlay map"); append_member(mapupp,"mapupp"); maprect=0.6; maprect.set_cmdline_option("maprect").set_description("Relative size of rectangles which represent voxels of the overlay map"); append_member(maprect,"maprect"); maplegendexport.set_cmdline_option("maplegend").set_description("Export map legend as bitmap to this file"); append_member(maplegendexport,"maplegendexport"); noscale=false; noscale.set_cmdline_option("noscale").set_description("Disable scale in 2D/3D display"); append_member(noscale,"noscale"); } ///////////////////////////////////////////////////////////////// void show_in_xmgr(const Data& data) { STD_string tmpfile="/tmp/miview"+itos(int(current_time_s()))+".asc"; data.write_asc_file(tmpfile); STD_list execs2try; execs2try.push_back("xmgrace"); execs2try.push_back("xmgr"); for(STD_list::const_iterator it=execs2try.begin(); it!=execs2try.end(); ++it) { if(!system(STD_string((*it)+" "+tmpfile+" && rm "+tmpfile+" &").c_str())) break; } } ///////////////////////////////////////////////////////////////// void MiViewView::usage() { Protocol prot; MiViewOpts mopts; FileReadOpts ropts; FilterFactory filter; MiViewFmri fmri; set_defaults(prot); STD_cout << "miview: Viewer for medical image files" << STD_endl; STD_cout << " File formats are automatically identified by their file extension." << STD_endl; STD_cout << "Usage: miview [ options ] " << STD_endl; STD_cout << "Global options:" << STD_endl; STD_cout << mopts.get_cmdline_usage("\t"); STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "fMRI options (Give at least -design and -fmri to activate):" << STD_endl; STD_cout << fmri.get_cmdline_usage("\t"); STD_cout << "File read options:" << STD_endl; STD_cout << prot.get_cmdline_usage("\t"); STD_cout << ropts.get_cmdline_usage("\t"); STD_cout << "Filters:" << STD_endl; STD_cout << filter.get_cmdline_usage("\t"); STD_cout << "Supported file extensions(formats):" << STD_endl; STD_cout << FileIO::autoformats_str("\t") << STD_endl; } void MiViewView::set_defaults(Protocol& prot) { prot.seqpars.set_MatrixSize(readDirection,1); prot.seqpars.set_MatrixSize(phaseDirection,1); prot.seqpars.set_MatrixSize(sliceDirection,1); prot.set_parmode(noedit); } MiViewView::MiViewView(QWidget *parent) : QWidget(parent) { Log odinlog("MiViewView","MiViewView"); char optval[ODIN_MAXCHAR]; file=new FileData(); set_defaults(file->prot); file->prot.parse_cmdline_options(GuiApplication::argc(),GuiApplication::argv()); FileReadOpts ropts; ropts.parse_cmdline_options(GuiApplication::argc(),GuiApplication::argv()); mopts.parse_cmdline_options(GuiApplication::argc(),GuiApplication::argv()); fmri.parse_cmdline_options(GuiApplication::argc(),GuiApplication::argv()); FilterChain filterchain(GuiApplication::argc(),GuiApplication::argv()); JDXfileName fname; if(getLastArgument(GuiApplication::argc(),GuiApplication::argv(),optval,ODIN_MAXCHAR)) { fname=optval; } else { usage(); exit(0); } if(fname=="") { usage(); exit(0); } ProgressDisplayConsole display; ProgressMeter progmeter(display); if(file->data.autoread(fname,ropts,&(file->prot),&progmeter)<=0) exit(-1); ODINLOG(odinlog,normalDebug) << "mem(read): " << Profiler::get_memory_usage() << STD_endl; if(!filterchain.apply(file->prot, file->data)) exit(-1); file->stat=statistics(file->data); ODINLOG(odinlog,infoLog) << "data = " << file->stat << STD_endl; has_bounds=false; lowbound=file->stat.min; uppbound=file->stat.max; if(mopts.low!="") { lowbound=atof(mopts.low.c_str()); has_bounds=true; } if(mopts.upp!="") { uppbound=atof(mopts.upp.c_str()); has_bounds=true; } if(uppbound<=lowbound) has_bounds=false; // check input ODINLOG(odinlog,normalDebug) << "lowbound/uppbound/has_bounds=" << lowbound << "/" << uppbound << "/" << has_bounds << STD_endl; guiprops_cache.pixmap.minsize=mopts.blowup*256; guiprops_cache.fixedsize=false; guiprops_cache.pixmap.autoscale=false; guiprops_cache.pixmap.color=mopts.color; guiprops_cache.pixmap.overlay_rectsize=mopts.maprect; guiprops_cache.pixmap.overlay_minval=mopts.maplow; guiprops_cache.pixmap.overlay_maxval=mopts.mapupp; has_olm=false; if(mopts.mapfile!="") { Data mapdata; if(mapdata.autoread(mopts.mapfile,ropts)>0) { Protocol protdummy; if(!filterchain.apply(protdummy, mapdata)) exit(-1); guiprops_cache.pixmap.overlay_map=mapdata; has_olm=true; // gp.pixmap.overlay_map.normalize(); } } fmriwidget=0; if(fmri.init(ropts,file->prot,filterchain)) { guiprops_cache.pixmap.overlay_map=fmri.get_overlay_map(); // must be present during construction of displaywidget guiprops_cache.pixmap.overlay_firescale=true; fmri.update(); fmri.set_label("fMRI"); fmriwidget=new JDXwidget(fmri, 1, this); connect(fmriwidget,SIGNAL(valueChanged()),this,SLOT(update())); } displaydata.redim(get_nz(),get_ny(),get_nx()); filedata2displaydata(); // will set gui_props of displaydata displaydata.set_label("Data Plot"); displaywidget=new JDXwidget(displaydata, 1, this); exportLegend(mopts.maplegendexport); // Do this after displaywidget is initialized, bur before dump. String will be checked in exportLegend() if(mopts.dump!="") { ODINLOG(odinlog,infoLog) << "Dumping images with prefix " << mopts.dump << STD_endl; displaywidget->write_pixmap(mopts.dump.c_str(), "bmp", true); exit(0); } connect(displaywidget,SIGNAL(clicked(int,int,int)), this,SLOT(slotClicked(int,int,int))); connect(displaywidget,SIGNAL(newProfile(const float*, int, bool, int)), this, SLOT(slotNewProfile(const float*, int, bool, int))); connect(displaywidget,SIGNAL(newMask(const float*, int)), this, SLOT(slotNewMask(const float*, int))); if(has_timecourse()) { repetition.set_label("Repetition"); repetition.set_minmaxval(0, get_nrep()-1); settings.append(repetition); } if(is_image_display() && !has_bounds) { settings.append(mopts.contrast); settings.append(mopts.brightness); } settingswidget=0; int n_settings=settings.numof_pars(); ODINLOG(odinlog,normalDebug) << "n_settings=" << n_settings << STD_endl; if(n_settings) { settings.set_label("Display Settings"); settingswidget=new JDXwidget(settings, 1, this); connect(settingswidget,SIGNAL(valueChanged()),this,SLOT(update())); } tcoursewidget=0; if(has_timecourse()) { GuiProps tcgp; tcgp.fixedsize=false; timecourse.set_gui_props(tcgp); timecourse.set_label("Timecourse"); timecourse.redim(get_nrep()); tcoursewidget=new JDXwidget(timecourse, 1, this); } int ncols=1; int nrows=2; if(settingswidget) ncols++; if(tcoursewidget) nrows++; grid=new GuiGridLayout( this, nrows, ncols); grid->add_widget(displaywidget, 0, 0, GuiGridLayout::Default, 2, 1); if(settingswidget) grid->add_widget(settingswidget, 0, 1); if(fmriwidget) grid->add_widget(fmriwidget, 1, 1); if(tcoursewidget) grid->add_widget(tcoursewidget, 2, 0, GuiGridLayout::Default, 1, 2); selection=new SelectionData(); selection->roi.resize(1,get_nz(),get_ny(),get_nx()); selection->roi=0.0; if(mopts.recfile!="") rmfile(mopts.recfile.c_str()); } void MiViewView::writeImage() { image_fname_cache=get_save_filename("Image File for Screen Dump", image_fname_cache.c_str(), "", this); if(image_fname_cache=="") return; STD_string format=check_and_get_format(image_fname_cache,get_possible_image_fileformats()); if(format!="") { displaywidget->write_pixmap(image_fname_cache.c_str(), format.c_str()); } } void MiViewView::writeROIs() { Log odinlog("MiViewView","writeROIs"); rois_fname_cache=get_save_filename("Data File for ROIs", rois_fname_cache.c_str(), "", this); if(rois_fname_cache=="") return; STD_string format=check_and_get_format(rois_fname_cache,FileIO::autoformats()); if(format!="") { selection->roi.autowrite(rois_fname_cache); } } void MiViewView::writeFmriClusters() { Log odinlog("MiViewView","writeFmriClusters"); clusters_fname_cache=get_save_filename("Data File for fMRI clusters", clusters_fname_cache.c_str(), "", this); if(clusters_fname_cache=="") return; STD_string format=check_and_get_format(clusters_fname_cache,FileIO::autoformats()); if(format!="") { fmri.write_overlay_map(clusters_fname_cache); /* farray olmap(fmri.get_overlay_map()); Data maskdata(1,olmap.size(0),olmap.size(1),olmap.size(2)); maskdata=0.0; for(unsigned int i=0; i0.0) maskdata(maskdata.create_index(i))=1.0; } maskdata.autowrite(clusters_fname_cache); */ } } void MiViewView::writeProfile() { profile_fname_cache=get_save_filename("ASCII File for Profile", profile_fname_cache.c_str(), "", this); if(profile_fname_cache=="") return; selection->profile.write_asc_file(profile_fname_cache); } void MiViewView::writeTimecourse() { tcourse_fname_cache=get_save_filename("ASCII File for Timecourse", tcourse_fname_cache.c_str(), "", this); if(tcourse_fname_cache=="") return; Data tcourse(timecourse); tcourse.write_asc_file(tcourse_fname_cache); } void MiViewView::exportLegend(const STD_string& filename) { Log odinlog("MiViewView","exportLegend"); if(filename=="") return; STD_string format=check_and_get_format(filename,get_possible_image_fileformats()); if(format!="") { ODINLOG(odinlog,infoLog) << "Writing legend of format " << format << " to file " << filename << STD_endl; displaywidget->write_map_legend(filename.c_str(), format.c_str()); } } void MiViewView::writeLegend() { exportLegend(get_save_filename("File for Legend", "", "", this)); } void MiViewView::selectVoxel() { JcampDxBlock block; for(int idir=(n_directions-1); idir>=0; idir--) { // display reversed in dialog pos_cache[idir].set_label(directionLabel[idir]); pos_cache[idir].set_description("Voxel index in "+STD_string(directionLabel[idir])+" direction").set_unit("pixel"); block.append(pos_cache[idir]); } new JDXwidgetDialog(block,n_directions,this,true); slotClicked(pos_cache[readDirection], pos_cache[phaseDirection], pos_cache[sliceDirection]); displaywidget->updateWidget(); } void MiViewView::showProfile() { show_in_xmgr(selection->profile); } void MiViewView::showTimecourse() { show_in_xmgr(timecourse); } void MiViewView::showProtocol() { file->prot.set_parmode(noedit); new JDXwidgetDialog(file->prot,2,this,false,true); } STD_string MiViewView::check_and_get_format(const STD_string& fname, const svector& possible_formats) { Log odinlog("MiViewView","check_and_get_format"); STD_string result; STD_string format=JDXfileName(fname).get_suffix(); for(unsigned int ifmt=0; ifmt odinlog("MiViewView","update"); filedata2displaydata(); displaywidget->updateWidget(); if(fmriwidget) fmriwidget->updateWidget(); } void MiViewView::slotClicked(int x, int y, int z) { Log odinlog("MiViewView","slotClicked"); ODINLOG(odinlog,normalDebug) << "x/y/z=" << x << "/" << y << "/" << z << STD_endl; ODINLOG(odinlog,normalDebug) << "get_nx/ny/nz()=" << get_nx() << "/" << get_ny() << "/" << get_nz() << STD_endl; if(x<0 || x>=get_nx()) return; if(y<0 || y>=get_ny()) return; if(z<0 || z>=get_nz()) return; timecourse=Data(file->data(Range::all(),z,y,x)); if(tcoursewidget) tcoursewidget->updateWidget(); float val=file->data(int(repetition),z,y,x); STD_string msg="f("; if(get_nz()>1) msg+=itos(z)+","; msg+=itos(y)+","+itos(x)+")="+ftos(val); ODINLOG(odinlog,normalDebug) << "msg=" << msg << STD_endl; setMessage(msg.c_str()); val2file(repetition,z,y,x,val); } void MiViewView::slotNewProfile(const float *data, int npts, bool horizontal, int position) { Log odinlog("MiViewView","slotNewProfile"); if(!data) return; selection->profile.resize(npts); selection->profile=Array((float*)data,npts,neverDeleteData); ODINLOG(odinlog,normalDebug) << "profile=" << selection->profile << STD_endl; STD_string msg; if(horizontal) msg="y="; else msg="x="; msg+=itos(position); setMessage(msg.c_str()); } void MiViewView::slotNewMask(const float *data, int slice) { Log odinlog("MiViewView","slotNewMask"); if(!data) return; Range all=Range::all(); Array oneslicemask((float*)data, TinyVector(get_ny(),get_nx()), neverDeleteData); if(sum(oneslicemask)<=0.0) return; selection->roi(0,slice,all,all)=oneslicemask; if(tcoursewidget) { for(int irep=0; irepdata(irep,slice,all,all),&oneslicemask); timecourse[irep]=repstats.mean; } tcoursewidget->updateWidget(); } statisticResult roistats=statistics(file->data(int(repetition),slice,all,all),&oneslicemask); STD_string msg="f(ROI)="+ftos(roistats.mean)+"+/-"+ftos(roistats.meandev); setMessage(msg.c_str()); val2file(repetition,slice,-1,-1,roistats.mean); } MiViewView::~MiViewView() { if(tcoursewidget) delete tcoursewidget; if(settingswidget) delete settingswidget; if(fmriwidget) delete fmriwidget; delete displaywidget; delete grid; delete file; delete selection; } int MiViewView::get_nx() const {return file->data.extent()(3);} int MiViewView::get_ny() const {return file->data.extent()(2);} int MiViewView::get_nz() const {return file->data.extent()(1);} int MiViewView::get_nrep() const {return file->data.extent()(0);} void MiViewView::filedata2displaydata() { Log odinlog("MiViewView","filedata2displaydata"); Range all=Range::all(); if(is_image_display()) { if(has_bounds) { displaydata=Data( (file->data(repetition,all,all,all)-lowbound)/(uppbound-lowbound) ); } else { float min=file->stat.min; float delta=file->stat.max-file->stat.min; ODINLOG(odinlog,normalDebug) << "min/max/delta=" << file->stat.min << "/" << file->stat.max << "/" << delta << STD_endl; if(delta<=0.0) {displaydata=JDXfloat(min); return;} float brightoffset=mopts.brightness/100.0-0.5; float contrfactor=pow(10.0,mopts.contrast/100.0); displaydata=Data( ((file->data(repetition,all,all,all)-min)/delta+brightoffset)*contrfactor+0.5 ); lowbound=(-1.0/(2.0*contrfactor)-brightoffset)*delta+min; uppbound=(+1.0/(2.0*contrfactor)-brightoffset)*delta+min; } if(fmri.is_valid()) { guiprops_cache.pixmap.overlay_map=fmri.get_overlay_map(); fmri.update(); } } else { displaydata=Data(file->data(repetition,all,all,all)); } ODINLOG(odinlog,normalDebug) << "lowbound/uppbound=" << lowbound << "/" << uppbound << STD_endl; if(mopts.noscale) { // this will disable scale ODINLOG(odinlog,normalDebug) << "Disabling scale" << STD_endl; guiprops_cache.scale[displayScale].minval=0.0; guiprops_cache.scale[displayScale].maxval=0.0; } else { guiprops_cache.scale[displayScale].minval=lowbound; guiprops_cache.scale[displayScale].maxval=uppbound; } displaydata.set_gui_props(guiprops_cache); } void MiViewView::val2file(int rep, int z, int y, int x, float val) const { if(mopts.valfile!="") { ::write(ftos(val),mopts.valfile); } if(mopts.recfile!="") { STD_string linestr=itos(rep)+","+itos(z)+","+itos(y)+","+itos(x)+"\t "+ftos(val)+"\n"; ::write(linestr,mopts.recfile, appendMode); } } odin-1.8.5/miview/miview_fmri.cpp0000644000175000017500000002746111734622163013737 00000000000000#include "miview_fmri.h" #include "miviewview.h" // for Log #include #include float glover_hrf(float t) { if(t<=0.0) return 0.0; const double a1=6; const double a2=12; const double b=0.9; const double c=0.35; const double d1=5.4; const double d2=10.8; return pow(t/d1,a1)*exp(-(t-d1)/b) - c * pow(t/d2,a2)*exp(-(t-d2)/b); } ///////////////////////////////////////////////////////////////// struct FmriData { unsigned int brainvoxels; Data fmri; Data mask; Data pmap; Data zmap; Data smap; Data designdata; bool has_mask; Protocol protcopy; // writable copy }; ///////////////////////////////////////////////////////////////// MiViewFmri::MiViewFmri() { valid=false; data=new FmriData(); designfile.set_parmode(hidden).set_cmdline_option("design").set_description("Load fMRI design from this file (comma or space separated)"); append_member(designfile,"designfile"); fmrifile.set_parmode(hidden).set_cmdline_option("fmri").set_description("Load fMRI data from this file"); append_member(fmrifile,"fmrifile"); maskfile.set_parmode(hidden).set_cmdline_option("fmask").set_description("fMRI mask file"); append_member(maskfile,"maskfile"); bonferr=false; bonferr.set_cmdline_option("bonferr").set_description("Use Bonferroni correction"); append_member(bonferr,"Bonferroni Correction"); designavg=0; designavg.set_parmode(hidden).set_cmdline_option("davg").set_description("Smooth the design function using a moving average filter of width N (TR)"); append_member(designavg,"Moving Average"); hrf=false; hrf.set_parmode(hidden).set_cmdline_option("hrf").set_description("Convolve design function by hemodynamic response function prior to correlation (see Glover NeuroImage 9, 416-429)"); append_member(hrf,"hrf"); corr=0.05; corr.set_cmdline_option("corr").set_description("Error probability threshold for correlation"); append_member(corr,"Error Probability"); zscore=0.0; zscore.set_cmdline_option("zscore").set_description("z-Score threshold for correlation"); append_member(zscore,"z-Score"); neighb=1; neighb.set_cmdline_option("neighb").set_description("Minimum next neighbours with significant activation"); append_member(neighb,"Min Neighbours"); sigchange.set_parmode(noedit).set_description("fMRI signal change, averaged over all significant voxels"); append_member(sigchange,"Signal Change"); zsum.set_parmode(noedit).set_description("Sum of the z-scores of all significant voxels"); append_member(zsum,"z-Sum"); zcount.set_parmode(noedit).set_description("Count of all significant voxels"); append_member(zcount,"z-Count"); zaverage.set_parmode(noedit).set_description("Average z-score of all significant voxels"); append_member(zaverage,"z-Average"); design.set_description("fMRI design vector"); append_member(design,"fMRI Design"); tcourse.set_description("average signal in activated voxels"); append_member(tcourse,"fMRI Timecourse"); GuiProps gp; gp.scale[yPlotScaleLeft]=ArrayScale("Change","%"); sigcourse.set_gui_props(gp); sigcourse.set_description("fMRI signal change time course"); append_member(sigcourse,"Relative fMRI Timecourse"); dumptcourse.set_parmode(hidden).set_cmdline_option("scourse").set_description("Dump relative fMRI signal change time course to this file"); append_member(dumptcourse,"dumptcourse"); dumpzmap.set_parmode(hidden).set_cmdline_option("zmap").set_description("Dump z-score map to this file"); append_member(dumpzmap,"dumpzmap"); dumpsmap.set_parmode(hidden).set_cmdline_option("smap").set_description("Dump map of relative fMRI signal change to this file"); append_member(dumpsmap,"dumpsmap"); } MiViewFmri::~MiViewFmri() { delete data; } bool MiViewFmri::init(const FileReadOpts& ropts, const Protocol& prot, const FilterChain& filterchain) { Log odinlog("MiViewFmri","init"); Range all=Range::all(); if(fmrifile=="") return false; ODINLOG(odinlog,infoLog) << "Loading fMRI data ..." << STD_endl; if(data->fmri.autoread(fmrifile,ropts,&(data->protcopy))<=0) { ODINLOG(odinlog,errorLog) << "Unable to load fmrifile " << fmrifile << STD_endl; return false; } if(!filterchain.apply(data->protcopy, data->fmri)) return false; // read and parse design file if(designfile=="") return false; STD_string designstr; if(::load(designstr,designfile)<0) { ODINLOG(odinlog,errorLog) << "Unable to load designfile " << designfile << STD_endl; return false; } designstr=replaceStr(designstr,","," "); svector designvecstr=tokens(designstr); int nrep=designvecstr.size(); design.resize(nrep); tcourse.resize(nrep); sigcourse.resize(nrep); data->designdata.resize(nrep); for(int i=0; iprotcopy.seqpars.get_RepetitionTime(); ODINLOG(odinlog,infoLog) << "Convolving with HRF and TR=" << tr << STD_endl; fvector designcopy(design); design=JDXfloat(0.0); for(int i=0; i0) { ODINLOG(odinlog,infoLog) << "Smoothing design function with moving average filter of width=" << designavg << "(TR)" << STD_endl; int WidthHalf = designavg / 2; fvector designcopy(design); for(int i=0; i=0) && (jdesigndata=design; Protocol maskprot(data->protcopy); // local copy for mask data->has_mask=false; if(maskfile!="") { ODINLOG(odinlog,infoLog) << "Loading fMRI mask ..." << STD_endl; if(data->mask.autoread(maskfile,ropts,&maskprot)<=0) { ODINLOG(odinlog,errorLog) << "Unable to load maskfile " << maskfile << STD_endl; return false; } if(!filterchain.apply(maskprot, data->mask)) return false; TinyVector fmrishape=data->fmri.shape(); fmrishape(0)=1; TinyVector maskshape=data->mask.shape(); maskshape(0)=1; if(fmrishape!=maskshape) { ODINLOG(odinlog,errorLog) << "Shape mismatch: fmrishape/maskshape" << fmrishape << "/" << maskshape << STD_endl; return false; } data->has_mask=true; } int nrep_data=data->fmri.extent(0); if(nrep_data!=nrep) { ODINLOG(odinlog,errorLog) << "Repetition size mismatch: " << nrep_data << "!=" << nrep << STD_endl; return false; } if(!nrep) { return false; } int nz=data->fmri.extent(1); int ny=data->fmri.extent(2); int nx=data->fmri.extent(3); data->pmap.resize(1,nz,ny,nx); data->zmap.resize(1,nz,ny,nx); data->smap.resize(1,nz,ny,nx); data->brainvoxels=0; overlay_map.redim(nz,ny,nx); toberemoved.redim(nz,ny,nx); Data onepixel(nrep); double sigthreshold=0.5*mean(data->fmri); for(int iz=0; izfmri(all,iz,iy,ix); float p=0.0; float z=0.0; float sigchange=0.0; if(mean(onepixel)>sigthreshold) { correlationResult corr=correlation(data->designdata, onepixel); if(corr.r>0.0) { // take only positivie correlation p=corr.p; z=corr.z; sigchange=fmri_eval(onepixel, data->designdata).rel_diff; } data->brainvoxels++; } data->pmap(0,iz,iy,ix)=p; data->zmap(0,iz,iy,ix)=z; data->smap(0,iz,iy,ix)=sigchange; } } } ODINLOG(odinlog,infoLog) << "Correlation analysis with " << data->brainvoxels << " voxels" << STD_endl; valid=true; return true; } const farray& MiViewFmri::get_overlay_map() const { int nz=data->pmap.extent(1); int ny=data->pmap.extent(2); int nx=data->pmap.extent(3); overlay_map=0.0; // reset // Bonferroni correction float corrthresh=corr; unsigned int total_pixels=data->brainvoxels; if(bonferr && total_pixels>0) { corrthresh=1.0-pow(1.0-corr,1.0/float(total_pixels)); } for(int iz=0; izpmap(0,iz,iy,ix); float z=data->zmap(0,iz,iy,ix); bool include=(pzscore); if(data->has_mask && data->mask(0,iz,iy,ix)<=0.0) include=false; if(include) overlay_map(iz,iy,ix)=data->zmap(0,iz,iy,ix); } } } // next-neighbour analysis if(neighb>0) { for(int iz=0; iz=0 && iyc=0 && ixc0.0) neighbours++; } } } } if(neighbours tmpmap(get_overlay_map()); return (tmpmap.autowrite(dumpzmap,FileWriteOpts(),&(data->protcopy))>=0); } void MiViewFmri::update() { Log odinlog("MiViewFmri","update"); Range all=Range::all(); int nz=data->pmap.extent(1); int ny=data->pmap.extent(2); int nx=data->pmap.extent(3); // update tcourse and z-statistic int nrep=tcourse.length(); Data tcourse_all(nrep); tcourse_all=0.0; int nvoxels=0; zsum = 0; tcourse_all=0.0; for(int iz=0; iz0.0) { tcourse_all(all)+=data->fmri(all,iz,iy,ix); zsum += overlay_map(iz,iy,ix); nvoxels++; } } } } zcount = nvoxels; float zavg = secureDivision(zsum,zcount); // calculate stddev of zaverage float zavgerr = 0.0; for(int iz=0; iz0.0) { zavgerr += pow(overlay_map(iz,iy,ix) - zavg,2); } } } } zavgerr = sqrt(secureDivision(zavgerr,zcount-1)); zaverage = ftos(zavg,2) + " +/- " + ftos(zavgerr,2); if(nvoxels) tcourse_all/=float(nvoxels); for(int i=0; idesigndata(i))); // Encode as amplitude and phase tcourse[i]=tcourse_all(i); } // update sigchange fmriResult fr=fmri_eval(tcourse_all, data->designdata); sigchange=ftos(100.0*fr.rel_diff,2)+" +/- "+ftos(100.0*fr.rel_err,2)+"%"; // update sigcourse if(fr.Sbaseline>0.0) { // Use baseline, if available sigcourse.assignValues(tcourse); sigcourse-=fr.Sbaseline; sigcourse*=(100.0/fr.Sbaseline); } else { if(fr.Srest>0.0) { // fallback sigcourse.assignValues(tcourse); sigcourse-=fr.Srest; sigcourse*=(100.0/fr.Srest); } } if(dumptcourse!="") { STD_ofstream file(dumptcourse.c_str()); for(int i=0; i mask(get_overlay_map()); Data smap_mask(data->smap.shape()); smap_mask=where(Array(mask)>0.0, Array(data->smap), float(0.0)); smap_mask.autowrite(dumpsmap,FileWriteOpts(),&(data->protcopy)); } } odin-1.8.5/miview/main.cpp0000644000175000017500000000340311322062342012322 00000000000000/*************************************************************************** main.cpp - description ------------------- begin : Thu Aug 31 16:27:06 CEST 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "miview.h" int main(int argc, char *argv[]) { // do this here so we do not have to query X server in order to get usage for manual if(argc<=1) {MiViewView::usage();exit(0);} if(hasHelpOption(argc, argv)) {MiViewView::usage();exit(0);} char lastarg[ODIN_MAXCHAR]; char parname[ODIN_MAXCHAR]; STD_string parstring; parname[0]='\0'; getLastArgument(argc,argv,lastarg,ODIN_MAXCHAR,false); if(getCommandlineOption(argc,argv,"-jdx",parname,ODIN_MAXCHAR,false)) { parstring=STD_string("::")+parname; } GuiApplication a(argc, argv); // debug handler will be initialized here MiView* miview=new MiView(); miview->set_caption((STD_string("MiView - ") + lastarg + parstring).c_str()); return a.start(miview->get_widget()); } odin-1.8.5/miview/Makefile.am0000644000175000017500000000152611322062342012732 00000000000000 if GUI_ENABLED INCLUDES = $(all_includes) # Auto-generate any needed moc files %_moc.cpp: %.h $(MOC) -o $@ $< bin_PROGRAMS = miview miview_SOURCES = \ miviewview.cpp miviewview.h miviewview_moc.cpp \ miview_fmri.cpp miview_fmri.h \ miview.cpp miview.h miview_moc.cpp \ main.cpp miview_LDADD = ../odindata/libodindata.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = miview.1 manual: $(bin_PROGRAMS) for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done endif dist-hook: -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp *.usage odin-1.8.5/miview/Makefile.in0000644000175000017500000005302611734622602012755 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @GUI_ENABLED_TRUE@bin_PROGRAMS = miview$(EXEEXT) subdir = miview DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__miview_SOURCES_DIST = miviewview.cpp miviewview.h \ miviewview_moc.cpp miview_fmri.cpp miview_fmri.h miview.cpp \ miview.h miview_moc.cpp main.cpp @GUI_ENABLED_TRUE@am_miview_OBJECTS = miviewview.$(OBJEXT) \ @GUI_ENABLED_TRUE@ miviewview_moc.$(OBJEXT) \ @GUI_ENABLED_TRUE@ miview_fmri.$(OBJEXT) miview.$(OBJEXT) \ @GUI_ENABLED_TRUE@ miview_moc.$(OBJEXT) main.$(OBJEXT) miview_OBJECTS = $(am_miview_OBJECTS) @GUI_ENABLED_TRUE@miview_DEPENDENCIES = ../odindata/libodindata.la \ @GUI_ENABLED_TRUE@ ../odinqt/libodinqt.la \ @GUI_ENABLED_TRUE@ ../odinpara/libodinpara.la \ @GUI_ENABLED_TRUE@ ../tjutils/libtjutils.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(miview_SOURCES) DIST_SOURCES = $(am__miview_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @GUI_ENABLED_TRUE@INCLUDES = $(all_includes) @GUI_ENABLED_TRUE@miview_SOURCES = \ @GUI_ENABLED_TRUE@ miviewview.cpp miviewview.h miviewview_moc.cpp \ @GUI_ENABLED_TRUE@ miview_fmri.cpp miview_fmri.h \ @GUI_ENABLED_TRUE@ miview.cpp miview.h miview_moc.cpp \ @GUI_ENABLED_TRUE@ main.cpp @GUI_ENABLED_TRUE@miview_LDADD = ../odindata/libodindata.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Manual pages for distribution @GUI_ENABLED_TRUE@dist_man_MANS = miview.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu miview/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu miview/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list miview$(EXEEXT): $(miview_OBJECTS) $(miview_DEPENDENCIES) @rm -f miview$(EXEEXT) $(CXXLINK) $(miview_OBJECTS) $(miview_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miview_fmri.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miview_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miviewview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/miviewview_moc.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags dist-hook \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 # Auto-generate any needed moc files @GUI_ENABLED_TRUE@%_moc.cpp: %.h @GUI_ENABLED_TRUE@ $(MOC) -o $@ $< # Auto-generate manual pages, only if not in srcdir @GUI_ENABLED_TRUE@%.1: % @GUI_ENABLED_TRUE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @GUI_ENABLED_TRUE@manual: $(bin_PROGRAMS) @GUI_ENABLED_TRUE@ for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done dist-hook: -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp *.usage # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/miview/miview.10000644000175000017500000002200011734623157012264 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH MIVIEW "1" "March 2012" "miview 1.8.5" "User Commands" .SH NAME miview \- Viewer for medical image files .SH SYNOPSIS .B miview [ \fIoptions \fR] \fI\fR .SH DESCRIPTION miview: Viewer for medical image files .IP File formats are automatically identified by their file extension. .SS "Global options:" .HP \fB\-blowup\fR: Enlarge display size by this factor (default=1) .HP \fB\-bright\fR: Relative brightness of display (default=0.0) .HP \fB\-color\fR: Use color map to display values .HP \fB\-contrast\fR: Relative contrast of display (default=0.0) .HP \fB\-dump\fR: Dump all images as bitmap(bmp) files and exit, use the given filename prefix .HP \fB\-low\fR: Lower windowing boundary: This value will appear black in display .HP \fB\-map\fR: Load overlay map (colored voxels superimposed on image) from this file .HP \fB\-maplegend\fR: Export map legend as bitmap to this file .HP \fB\-maplow\fR: Lower windowing boundary for overlay map (default=0.0) .HP \fB\-maprect\fR: Relative size of rectangles which represent voxels of the overlay map (default=0.60) .HP \fB\-mapupp\fR: Upper windowing boundary for overlay map (default=0.0) .HP \fB\-noscale\fR: Disable scale in 2D/3D display .HP \fB\-rec\fR: Record clicked coordinates and values into this file .HP \fB\-upp\fR: Upper windowing boundary: This value will appear white in display .HP \fB\-val\fR: Save value of ROI/point selection to this file .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .SS "fMRI options (Give at least -design and -fmri to activate):" .HP \fB\-bonferr\fR: Use Bonferroni correction .HP \fB\-corr\fR: Error probability threshold for correlation (default=0.050) .HP \fB\-davg\fR: Smooth the design function using a moving average filter of width N (TR) (default=0) .HP \fB\-design\fR: Load fMRI design from this file (comma or space separated) .HP \fB\-fmask\fR: fMRI mask file .HP \fB\-fmri\fR: Load fMRI data from this file .HP \fB\-hrf\fR: Convolve design function by hemodynamic response function prior to correlation (see Glover NeuroImage 9, 416\-429) .HP \fB\-neighb\fR: Minimum next neighbours with significant activation (default=1) .HP \fB\-scourse\fR: Dump relative fMRI signal change time course to this file .HP \fB\-smap\fR: Dump map of relative fMRI signal change to this file .HP \fB\-zmap\fR: Dump z\-score map to this file .HP \fB\-zscore\fR: z\-Score threshold for correlation (default=0.0) .SS "File read options:" .HP \fB\-date\fR: Date of scan [yyyymmdd] (default=20120328yyyymmdd) .HP \fB\-fp\fR: FOV in phase direction [mm] (default=220.0mm) .HP \fB\-fr\fR: FOV in read direction [mm] (default=220.0mm) .HP \fB\-fs\fR: FOV in slice direction [mm] (default=5.0mm) .HP \fB\-nr\fR: Number of consecutive measurements (default=1) .HP \fB\-nx\fR: Number of points in read direction (default=1) .HP \fB\-ny\fR: Number of points in phase direction (default=1) .HP \fB\-nz\fR: Number of points in slice direction (default=1) .HP \fB\-pbirth\fR: Patients date of birth [yyyymmdd] (default=00000000yyyymmdd) .HP \fB\-pid\fR: Unique patient identifier (default=Unknown) .HP \fB\-pname\fR: Full patient name (default=Unknown) .HP \fB\-psex\fR: Patients sex (options=M F O , default=O) .HP \fB\-pweight\fR: Patients weight [kg] (default=50.0kg) .HP \fB\-scient\fR: Scientist Name (default=Unknown) .HP \fB\-sd\fR: Inter\-slice distance (from center to center) [mm] (default=10.0mm) .HP \fB\-serd\fR: Series Description (default=Unknown) .HP \fB\-serno\fR: Series Number (default=1) .HP \fB\-st\fR: Slice thickness [mm] (default=5.0mm) .HP \fB\-stud\fR: Study Description (default=Unknown) .HP \fB\-tcname\fR: Name of transmit coil (default=Unknown) .HP \fB\-te\fR: Time\-to\-echo of the sequence [ms] (default=80.0ms) .HP \fB\-time\fR: Time of scan [hhmmss] (default=165543hhmmss) .HP \fB\-tr\fR: Time between consecutive excitations [ms] (default=1000.0ms) .HP \fB\-cplx\fR: Treat data as complex and extract the given component (options=none abs pha real imag , default=none) .HP \fB\-ds\fR: Dataset index to extract if multiple datasets are read .HP \fB\-filter\fR: Read only those datasets which protocol parameter 'key' contains the string 'value' (given in the format 'key=value') .HP \fB\-fmap\fR: For reduced memory usage, keep filemapping after reading (raw) data, but writing into the array will result in a crash .HP \fB\-jdx\fR: If multiple JDX arrays are present, select this .HP \fB\-rdialect\fR: Read data using given dialect of the format. (default is no dialect) .HP \fB\-rf\fR: Read format, use it to override file extension (options=autodetect 3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk , default=autodetect) .HP \fB\-skip\fR: Skip this amount of bytes before reading the raw data (default=0) .SS "Filters:" .HP \fB\-align\fR : Align data to the geometry (voxel locations) of an external file .HP \fB\-automask\fR : Create mask using automatic histogram\-based threshold .HP \fB\-detrend\fR : Remove slow drift over time .HP \fB\-genmask\fR : Create mask including all voxels with value in given range .HP \fB\-isotrop\fR : make image voxels isotrop through interpolation (image geometry will not change) .HP \fB\-lowpass\fR : Lowpass filtering .HP \fB\-max\fR : Clip all values above maximum value .HP \fB\-maxip\fR : Perform maximum intensity projection over given direction .HP \fB\-merge\fR : Merge datasets into a single dataset by expanding the time dimension .HP \fB\-min\fR : Clip all values below mininum value .HP \fB\-minip\fR : Perform minimum intensity projection over given direction .HP \fB\-noNaN\fR : Replaces every NaN by the given value .HP \fB\-pflip\fR : Flip data in phase direction .HP \fB\-prange\fR : Select range in phase direction .HP \fB\-proj\fR : Perform projection over given direction .HP \fB\-quantilmask\fR : Create mask including all voxels above the given fractional threshold .HP \fB\-resample\fR : Temporal resize of image data .HP \fB\-resize\fR : Spatial resize of image data .HP \fB\-reslice\fR : reslices the image to a given orientation .HP \fB\-rflip\fR : Flip data in read direction .HP \fB\-rot\fR : In\-plane rotation .HP \fB\-rrange\fR : Select range in read direction .HP \fB\-scale\fR : Rescale image values .HP \fB\-sflip\fR : Flip data in slice direction .HP \fB\-shift\fR : Shift data spatially .HP \fB\-splice\fR : splices the image in the given direction .HP \fB\-srange\fR : Select range in slice direction .HP \fB\-swapdim\fR <[rps][\-],[rps][\-],[rps][\-]> : swap/reflect dimensions by specifying a direction triple with optional reflection sign appended .HP \fB\-tile\fR : Combine slices into a square 2D image .HP \fB\-trange\fR : Select range in time direction .HP \fB\-typemax\fR : Clip all values above maximum of a specific datatype .HP \fB\-typemin\fR : Clip all values below mininum of a specific datatype .HP \fB\-usemask\fR : Create 1D dataset including all values within mask from file .SS "Supported file extensions(formats):" .TP 3db (Iris3D binary data) .TP asc (ASCII, dialects: tcourse ) .TP coi (JCAMP\-DX data sets) .TP dat (Matlab ascii 2D data matrix) .TP dcm (DICOM, dialects: siemens ) .TP double (double raw data) .TP float (float raw data) .TP gz (GNU\-Zip container for other formats) .TP hdr (NIFTI/ANALYZE, dialects: fsl ) .TP idx (3D\-indices of non\-zeroes in ASCII) .TP ima (DICOM, dialects: siemens ) .TP jdx (JCAMP\-DX image format) .TP mag (DICOM, dialects: siemens ) .TP mhd (MetaImage) .TP nii (NIFTI/ANALYZE, dialects: fsl ) .TP ph (DICOM, dialects: siemens ) .TP png (Portable Network Graphics) .TP pos (x\-y positions of non\-zeroes in ASCII) .TP pro (ODIN measurement protocols) .TP reg (Ansoft HFSS ASCII) .TP s16bit (signed 16 bit raw data) .TP s32bit (signed 32 bit raw data) .TP s8bit (signed 8 bit raw data) .TP smp (JCAMP\-DX data sets) .TP u16bit (unsigned 16 bit raw data) .TP u32bit (unsigned 32 bit raw data) .TP u8bit (unsigned 8 bit raw data) .TP vtk (Visualization Toolkit) odin-1.8.5/miview/miview.h0000644000175000017500000000421611322062342012346 00000000000000/*************************************************************************** miview.h - description ------------------- begin : Thu Aug 31 16:27:06 CEST 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MIVIEW_H #define MIVIEW_H #include "miviewview.h" /** * \page miview View medical images * \verbinclude miview/miview.usage * * \section miview_examples Some examples how to use miview: * * Display DICOM file 'image.dcm': * \verbatim miview image.dcm \endverbatim * * * Display magnitude of float-type complex signal data stored in 'data.raw': * \verbatim miview -rf float -abs data.raw \endverbatim * * * Display short (16 bit) raw data file '2dseq' of size 256x256 * \verbatim miview -nx 256 -ny 256 -rf short 2dseq \endverbatim */ #define IDS_MIVIEW_ABOUT "MiView user interface\nVersion " VERSION \ "\n(w) 2000-2005 by Thies Jochimsen\n\n" class MiView : public QObject, public GuiMainWindow { Q_OBJECT public: MiView(); public slots: void slotHelpAbout(); void slotStatusMsg(const char* text) {GuiMainWindow::set_status_message(text);} void quit(); private: MiViewView *view; GuiPopupMenu* fileMenu; GuiPopupMenu* exportMenu; GuiPopupMenu* showMenu; GuiPopupMenu* helpMenu; }; #endif odin-1.8.5/miview/miviewview.h0000644000175000017500000000763211322062342013246 00000000000000/*************************************************************************** miviewview.h - description ------------------- begin : Thu Jun 20 19:02:26 CEST 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MIVIEWVIEW_H #define MIVIEWVIEW_H #include #include #include #include #include // miview modules #include "miview_fmri.h" class Protocol; // forward declaration struct FileData; // forward declaration struct SelectionData; // forward declaration //////////////////////////////////////// // for debugging MiView component class MiViewComp { public: static const char* get_compName(); }; //////////////////////////////////////// struct MiViewOpts : JcampDxBlock { JDXbool color; JDXfloat contrast; JDXfloat brightness; JDXstring valfile; JDXstring recfile; JDXint blowup; JDXstring low; JDXstring upp; JDXstring dump; JDXstring mapfile; JDXfloat maplow; JDXfloat mapupp; JDXfloat maprect; JDXstring maplegendexport; JDXbool noscale; MiViewOpts(); }; //////////////////////////////////////// class MiViewView : public QWidget { Q_OBJECT public: MiViewView(QWidget *parent); ~MiViewView(); static void set_defaults(Protocol& prot); static void usage(); bool is_image_display() const {return (get_nx()*get_ny())>1;} bool has_timecourse() const {return get_nrep()>1;} bool has_fmri() const {return fmri.is_valid();} bool has_overlay() const {return has_olm;} signals: void setMessage(const char* text); public slots: void writeImage(); void writeROIs(); void writeFmriClusters(); void writeProfile(); void writeTimecourse(); void writeLegend(); void selectVoxel(); void showProfile(); void showTimecourse(); void showProtocol(); private slots: void update(); void slotClicked(int x, int y, int z); void slotNewProfile(const float *data, int npts, bool horizontal, int position); void slotNewMask(const float *data, int slice); private: int get_nx() const; int get_ny() const; int get_nz() const; int get_nrep() const; void filedata2displaydata(); STD_string check_and_get_format(const STD_string& fname, const svector& possible_formats); void exportLegend(const STD_string& filename); void val2file(int rep, int z, int y, int x, float val) const; MiViewOpts mopts; bool has_bounds; // true if set manually float lowbound; float uppbound; FileData* file; // holding the data of the file JDXfloatArr displaydata; GuiProps guiprops_cache; JcampDxBlock settings; JDXint repetition; JDXfloatArr timecourse; bool has_olm; SelectionData* selection; // holding data of user selections GuiGridLayout* grid; JDXwidget* displaywidget; JDXwidget* settingswidget; JDXwidget* tcoursewidget; JDXwidget* fmriwidget; STD_string image_fname_cache; STD_string rois_fname_cache; STD_string clusters_fname_cache; STD_string profile_fname_cache; STD_string tcourse_fname_cache; JDXint pos_cache[n_directions]; // miview modules MiViewFmri fmri; }; #endif odin-1.8.5/miview/miview.cpp0000644000175000017500000000373011322062342012701 00000000000000#include "miview.h" MiView::MiView() { view=new MiViewView(GuiMainWindow::get_widget()); connect(view, SIGNAL(setMessage(const char*)), this, SLOT (slotStatusMsg(const char*))); fileMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); fileMenu->insert_item("&Quit", this, SLOT(quit()), Qt::CTRL+Qt::Key_Q); exportMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); showMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); showMenu->insert_item("Select Voxel", view, SLOT(selectVoxel())); if(view->is_image_display()) { exportMenu->insert_item("Dump current display as image (screenshot)", view, SLOT(writeImage())); exportMenu->insert_item("Export current ROIs", view, SLOT(writeROIs())); exportMenu->insert_item("Export current profile as ASCII", view, SLOT(writeProfile())); if(view->has_timecourse()) exportMenu->insert_item("Export current timecourse as ASCII", view, SLOT(writeTimecourse())); showMenu->insert_item("Show current profile in Xmgr(ace)", view, SLOT(showProfile())); showMenu->insert_item("Show current timecourse in Xmgr(ace)", view, SLOT(showTimecourse())); } if(view->has_fmri()) { exportMenu->insert_item("Export current fMRI clusters", view, SLOT(writeFmriClusters())); } if(view->has_overlay()) { exportMenu->insert_item("Export overlay legend", view, SLOT(writeLegend())); } showMenu->insert_item("Show Protcol", view, SLOT(showProtocol())); helpMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); helpMenu->insert_item("About...", this, SLOT(slotHelpAbout())); GuiMainWindow::insert_menu("&File", fileMenu); GuiMainWindow::insert_menu("Ex&port", exportMenu); GuiMainWindow::insert_menu("S&how", showMenu); GuiMainWindow::insert_menu_separator(); GuiMainWindow::insert_menu("&Help", helpMenu); GuiMainWindow::show(view); } void MiView::slotHelpAbout() { message_question(IDS_MIVIEW_ABOUT, "About...", GuiMainWindow::get_widget()); } void MiView::quit() { GuiApplication::quit(); } odin-1.8.5/miview/miview_fmri.h0000644000175000017500000000425511734622163013400 00000000000000/*************************************************************************** miview_fmri.h - description ------------------- begin : Mon Jan 2 19:02:26 CEST 2006 copyright : (C) 2006 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef MIVIEW_FMRI_H #define MIVIEW_FMRI_H #include #include #include #include // forward declarations class FileReadOpts; class Protocol; class FilterChain; struct FmriData; //////////////////////////////////////////////////////////// class MiViewFmri : public JcampDxBlock { public: MiViewFmri(); ~MiViewFmri(); bool init(const FileReadOpts& ropts, const Protocol& prot, const FilterChain& filterchain); bool is_valid() const {return valid;} const farray& get_overlay_map() const; bool write_overlay_map(const STD_string& filename); void update(); private: JDXstring designfile; JDXstring fmrifile; JDXstring maskfile; JDXbool bonferr; JDXbool hrf; JDXfloat corr; JDXfloat zscore; JDXint designavg; JDXint neighb; JDXstring sigchange; JDXfloat zsum; JDXint zcount; JDXstring zaverage; JDXfloatArr design; JDXfloatArr tcourse; JDXfloatArr sigcourse; JDXstring dumptcourse; JDXstring dumpzmap; JDXstring dumpsmap; FmriData* data; mutable farray overlay_map; mutable farray toberemoved; bool valid; }; #endif odin-1.8.5/odinqt/0000755000175000017500000000000011735135551010763 500000000000000odin-1.8.5/odinqt/intedit.cpp0000644000175000017500000000561311322062347013046 00000000000000#include #include "intedit.h" #include // for itos #include // for strtol intLineEdit::intLineEdit(int minValue, int maxValue, int value, QWidget *parent, const char *name, int width, int height ) { gle = new GuiLineEdit(parent, this, SLOT(emitSignal()), width, height); /* minValue & maxValue unused so far: */ minValue=maxValue=0; set_value(value); } intLineEdit::~intLineEdit() { delete gle; } void intLineEdit::setintLineEditValue( int newValue ) { set_value(newValue); } void intLineEdit::emitSignal() { if(gle->is_modified()) { int value=atoi(gle->get_text()); set_value(value); emit intLineEditValueChanged(value); } } void intLineEdit::set_value(int value) { gle->set_text( itos(value).c_str() ); } ////////////////////////////////////////////////////////////// intLineBox::intLineBox(int value,QWidget *parent, const char *name ) : QGroupBox(name,parent) { grid=new GuiGridLayout( this, 1, 1); le = new intLineEdit( 0, 0, value, this, "LineEdit", TEXTEDIT_WIDTH, TEXTEDIT_HEIGHT ); grid->add_widget( le->get_widget(), 0, 0); connect(le,SIGNAL(intLineEditValueChanged( int )), this,SLOT(emitSignal( int ))); connect(this,SIGNAL(SignalToChild( int )), le, SLOT(setintLineEditValue( int))); } void intLineBox::setintLineBoxValue( int newvalue ) { emit SignalToChild( newvalue ); } void intLineBox::emitSignal( int newvalue ) { emit intLineBoxValueChanged(newvalue); } intLineBox::~intLineBox() { delete le; delete grid; } ////////////////////////////////////////////////////////////// intScientSlider::intScientSlider(int minValue, int maxValue, int Step, int value, QWidget *parent, const char *name ) : QGroupBox(name, parent ) { grid=new GuiGridLayout( this, 1, 4); slider=new GuiSlider(this, minValue, maxValue, Step, value, int(((float)maxValue-(float)minValue)/20.0)); le = new intLineEdit( minValue, maxValue, value, this, "LineEdit" , SLIDER_CELL_WIDTH, SLIDER_CELL_HEIGHT ); grid->add_widget(slider->get_widget(), 0, 0, GuiGridLayout::Default, 1, 3 ); grid->add_widget(le->get_widget(), 0, 3); // cross-wise connection of slider and line edit connect(slider->get_widget(), SIGNAL(valueChanged(int)), le, SLOT(setintLineEditValue(int))); connect(le, SIGNAL(intLineEditValueChanged(int)), slider->get_widget(), SLOT(setValue(int))); // emit signal whenever of one of both has been changed connect(slider->get_widget(),SIGNAL(valueChanged(int)), this,SLOT(emitSignal( int ))); connect(le,SIGNAL(intLineEditValueChanged( int )), this,SLOT(emitSignal( int ))); } void intScientSlider::setintScientSliderValue( int newvalue ) { slider->set_value(newvalue); le->setintLineEditValue(newvalue); } void intScientSlider::emitSignal( int newvalue ) { emit intScientSliderValueChanged(newvalue); } intScientSlider::~intScientSlider(){ delete le; delete slider; delete grid; } odin-1.8.5/odinqt/boolbutton.cpp0000644000175000017500000000216411322062347013573 00000000000000#include "boolbutton.h" buttonBox::buttonBox(const char *text, QWidget *parent, const char *buttonlabel) : QGroupBox(buttonlabel,parent) { grid=new GuiGridLayout( this, 1, 1); gb=new GuiButton(this, this, SLOT(reportclicked()), text); grid->add_widget( gb->get_widget(), 0, 0, GuiGridLayout::VCenter); // connect( gb->get_widget(), SIGNAL(clicked()), SLOT(reportclicked()) ); } buttonBox::buttonBox(const char *ontext,const char *offtext, bool initstate, QWidget *parent, const char *buttonlabel) : QGroupBox(buttonlabel,parent) { grid=new GuiGridLayout( this, 1, 1); gb=new GuiButton(this, this, SLOT(setButtonState()), ontext, offtext, initstate); grid->add_widget( gb->get_widget(), 0, 0, GuiGridLayout::VCenter); // connect( gb->get_widget(), SIGNAL(toggled(bool)), SLOT(setButtonState(bool)) ); } void buttonBox::reportclicked() { emit buttonClicked(); } void buttonBox::setToggleState(bool state) { gb->set_toggled(state); } void buttonBox::setButtonState() { bool state=gb->is_on(); gb->set_text(state); emit buttonToggled(state); } buttonBox::~buttonBox(){ delete gb; delete grid; } odin-1.8.5/odinqt/jdxblockwidget.h0000644000175000017500000001034411363773557014075 00000000000000/*************************************************************************** jdxblockwidget.h - description ------------------- begin : Mon Aug 5 2005 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXBLOCKWIDGET_H #define JDXBLOCKWIDGET_H #include #include "odinqt.h" #include class JDXwidgetDialog; // forward declaration //////////////////////////////////////////////////////////// class JcampDxBlockGrid : public QWidget { Q_OBJECT public: JcampDxBlockGrid(JcampDxBlock& block,unsigned int columns=1,QWidget *parent=0,const char* omittext=""); signals: // public: void valueChanged(); // private: void updateSubWidget(); void deleteSubDialogs(); public slots: void updateWidget(); void deleteDialogs(); void swapSliderTracking() {} void emitValueChanged() {emit valueChanged();} private: friend class JcampDxBlockScrollView; void createDialog(); GuiGridLayout* grid; JcampDxBlock& val; STD_list subdialogs; }; //////////////////////////////////////////////////////////// class JcampDxBlockScrollView : public QObject { Q_OBJECT public: JcampDxBlockScrollView(JcampDxBlock& block, unsigned int columns=1, QWidget *parent=0, const char* omittext=""); ~JcampDxBlockScrollView(); // QSize gridsize() const {return jdxgrid->frameSize();} QWidget* get_widget() {return scroll->get_widget();} signals: void valueChanged(); public slots: void updateWidget() {jdxgrid->updateWidget();} void deleteDialogs() {jdxgrid->deleteDialogs();} void swapSliderTracking() {jdxgrid->swapSliderTracking();} void emitValueChanged() {emit valueChanged();} private: friend class JcampDxBlockWidget; void createDialog() {jdxgrid->createDialog();} GuiScroll* scroll; JcampDxBlockGrid* jdxgrid; }; //////////////////////////////////////////////////////////// class JcampDxBlockWidget : public QGroupBox { Q_OBJECT public: JcampDxBlockWidget(JcampDxBlock& jdxblock,unsigned int columns=1,QWidget *parent=0,bool doneButton=false,bool is_dialog=false,const char* omittext="", bool storeLoadButtons=false, bool readonly=false); ~JcampDxBlockWidget(); // QSize gridsize() const {if(jdxscroll) return jdxscroll->gridsize(); else return QSize();} signals: void valueChanged(); void doneButtonPressed(); public slots: void updateWidget() {if(jdxscroll) jdxscroll->updateWidget();} void deleteDialogs() {if(jdxscroll) jdxscroll->deleteDialogs();} void swapSliderTracking() {if(jdxscroll) jdxscroll->swapSliderTracking();} void createDialog(); void emitValueChanged() {emit valueChanged();} private slots: void emitDone(); void storeBlock(); void loadBlock(); private: GuiGridLayout *grid; GuiButton *pb_done; GuiButton *pb_edit; GuiButton *pb_store; GuiButton *pb_load; JcampDxBlock& parblock; JcampDxBlockScrollView* jdxscroll; GuiListView* noeditlist; STD_vector noedititems; }; //////////////////////////////////////////////////////////// class JDXwidgetDialog : public QObject, public GuiDialog { Q_OBJECT public: JDXwidgetDialog(JcampDxBlock& ldr,unsigned int columns=1,QWidget *parent=0, bool modal=false, bool readonly=false); ~JDXwidgetDialog(); public slots: void updateWidget(); void emitChanged(); private: GuiGridLayout *grid; JcampDxBlockWidget *jdx; private slots: void callDone(); signals: void finished(); void valueChanged(); }; #endif odin-1.8.5/odinqt/jdxwidget.h0000644000175000017500000001473711322062347013053 00000000000000/*************************************************************************** jdxwidget.h - description ------------------- begin : Mon Apr 15 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXWIDGET_H #define JDXWIDGET_H #include #include "odinqt.h" #include #include /////////////////////////////////////////////////////////////// #define _MAX_SLIDER_STEPS_ 100 #define _MAX_LABEL_LENGTH_ 15 #define _FLOAT_DIGITS_ 3 #define _INFOBOX_LINEWIDTH_ 50 #define _MAX_SUBWIDGETS_FOR_ALIGNCENT_ 5 /////////////////////////////////////////////////////////////// // forward declarations to decouple headers as far as possible class JcampDxClass; class intScientSlider; class intLineBox; class floatScientSlider; class floatLineBox; class enumBox; class buttonBox; class floatBox1D; class floatBox3D; class complexfloatBox1D; class stringBox; class floatLineBox3D; class JDXwidgetDialog; class JcampDxBlockWidget; class JDXeditCaller; /////////////////////////////////////////////////////////////// /** * * This class produces a widget according to a given JCAMP-DX parameter or a block * of them so that the parameter(s) can be edited interactively */ class JDXwidget : public QWidget { Q_OBJECT public: /** * *Constructs a widget for the parameter(s) 'ldr' with the following additional options: * - columns: If creating a widget for a block of parameters they will be grouped in the given number of columns * - parent: The parent widget * - doneButton: If creating a widget for a block of parameters a 'Done' push button will be added if this option is set to 'true' * The push button will then emit the doneButtonPressed() signal if clicked * - omittext: Text to blind out in the label of each parameter * - storeLoadButtons: Add buttons to store/load the parameters to/from file * */ JDXwidget(JcampDxClass& ldr,unsigned int columns=1, QWidget *parent=0, bool doneButton=false, const char* omittext="", bool storeLoadButtons=false); ~JDXwidget(); // members for 2D/3D plot void write_pixmap(const char* fname, const char* format, bool dump_all=false) const; void write_map_legend(const char* fname, const char* format) const; signals: /** * This signal will be emitted whenever one of the parameters is changed */ void valueChanged(); /** * This signal will be emitted whenever the 'Done' button is clicked */ void doneButtonPressed(); // signals for 2D/3D plot void clicked(int x, int y, int z); void newProfile(const float *data, int npts, bool horizontal, int position); void newMask(const float* data, int slice); // private: void updateSubWidget(); void deleteSubDialogs(); void newintval(int); void newfloatval(float); void newenumval(int); void newboolval(bool); void newfloatArr1( const float*, int, float, float); // void newdoubleArr1( const double*, int, float, float); void newfloatArr2( const float*, float, float); void newfloatArrMap(const float*, float, float, float); void newcomplexArr( const float*, const float*, int, float, float); void newfuncval(int); void newstringval(const char*); void newfilenameval(const char*); void newformulaval(const char*); void newtripleval(float,float,float); public slots: /** * Tell the widget that the parameter(s) were changed outside and that it has to update its view */ void updateWidget(); /** * Delete all dialogs that may have popped up during editing the parameters */ void deleteDialogs(); private slots: void emitValueChanged(); void emitDone(); void emitClicked(int x, int y, int z) {emit clicked(x,y,z);} void emitNewProfile(const float *data, int npts, bool horizontal, int position) {emit newProfile(data, npts, horizontal, position);} void emitNewMask(const float *data, int slice) {emit newMask(data,slice);} void changeJDXint( int ); void changeJDXfloat( float ); void changeJDXenum( int ); void changeJDXbool ( bool ); void changeJDXaction(); void changeJDXfunction( int ); void changeJDXstring(const char*); void changeJDXfileName(const char*); void browseJDXfileName(); void changeJDXformula(const char*); void changeJDXtriple(float,float,float); void infoJDXformula(); void editJDXfunction(); void infoJDXfunction(); public: STD_string get_label() const; unsigned int get_rows() const {return rows;} unsigned int get_cols() const {return cols;} private: void set_widget(QWidget *widget, GuiGridLayout::Alignment alignment = GuiGridLayout::Default, bool override_enabled=false); unsigned int get_sizedfarray_size_and_factor(unsigned int& nx, unsigned int& ny, unsigned int& nz) const; void create_or_update_floatArrwidget(const farray& arr, bool initial); GuiGridLayout* grid; QWidget* widget_cache; JcampDxBlockWidget* blockwidget; intScientSlider* intslider; intLineBox* intedit; floatScientSlider* floatslider; floatLineBox* floatedit; enumBox* enumwidget; buttonBox* boolwidget; buttonBox* actionwidget; QLabel* floatArrempty; floatBox1D* floatArrwidget1; floatLineBox* floatArredit; floatBox3D* floatArrwidget2; complexfloatBox1D* complexArrwidget; stringBox* stringwidget; stringBox* filenamewidget; enumBox* funcwidget; stringBox* formulawidget; floatLineBox3D* triplewidget; // float 2D/3D stuff farray sizedfarray; farray mapfarray; ndim oldfarraysize; farray overlay_map; QWidget* vport; JcampDxClass& val; STD_string ldrlabel; STD_string ldrlabel_uncut; bool label_cut; STD_list subdialogs; unsigned int rows,cols; }; #endif odin-1.8.5/odinqt/float1d.h0000644000175000017500000000360611322062347012405 00000000000000/*************************************************************************** float1d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FLOAT1D_H #define FLOAT1D_H #include "complex1d.h" /** * This class displays a float array in a nice box with title */ class floatBox1D : public complexfloatBox1D { Q_OBJECT public: floatBox1D(const float *data,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel=0, const char *yAxisLabel=0, float min_x=0.0, float max_x=0.0, bool detachable=false); floatBox1D(const double *data,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel=0, const char *yAxisLabel=0, float min_x=0.0, float max_x=0.0, bool detachable=false); public slots: void refresh(const float* data,int n, float min_x, float max_x); void refresh(const float* data,int n) {refresh (data,n,0.0,0.0);} void refresh(const double* data,int n, float min_x, float max_x); void refresh(const double* data,int n) {refresh (data,n,0.0,0.0);} }; #endif odin-1.8.5/odinqt/float2d.h0000644000175000017500000000735111322062347012407 00000000000000/*************************************************************************** float2d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FLOAT2D_H #define FLOAT2D_H #include #include "odinqt.h" #include "plot.h" class QPixmap; // forward declaration /** * QLabel containing a QPixmap to draw 2D float array */ class floatLabel2D : public QLabel { Q_OBJECT public: floatLabel2D(const float *data, float lowbound, float uppbound, unsigned int nx, unsigned int ny, unsigned int coarseFactor, QWidget *parent, const char *name, const float *overlay_map, float lowbound_map, float uppbound_map, unsigned int nx_map, unsigned int ny_map, bool map_firescale, float map_rectsize, bool colormap); ~floatLabel2D(); int xpos2labelxpos(int pos); int ypos2labelypos(int pos); int labelxpos2xpos(int pos); int labelypos2ypos(int pos); int xypos2index(int xpos,int ypos); unsigned int get_nx() const {return nx_cache;} unsigned int get_ny() const {return ny_cache;} void init_pixmap(bool clear=true); void set_pixmap(); void write_pixmap(const char* fname, const char* format) const; QLabel* get_map_legend(QWidget *parent) const; void write_map_legend(const char* fname, const char* format) const; QPixmap *pixmap; protected: void mousePressEvent (QMouseEvent *); void mouseReleaseEvent (QMouseEvent *); void mouseMoveEvent ( QMouseEvent * ); public slots: void refresh(const float *data, float lowbound, float uppbound); void refreshMap(const float *map, float map_lowbound, float map_uppbound, float rectsize); private slots: void drawprofil(int position,int direction); void drawcross(int xposition,int yposition); void drawroi(); signals: void clicked(int xposition,int yposition); void newProfile(const float *data, int npts, bool horizontal, int position); void newMask(const float *data); private: static int scale_width(float lowbound, float uppbound); void draw_text(GuiPainter& gp, int xpos, int ypos, const char* txt) const; void draw_scale_text(GuiPainter& gp, int ypos, float val) const; static int check_range(int val, int min, int max); int get_map_hue(float relval) const; int get_map_value(float relval) const; int get_map_saturation(float relval) const; int scalespace_cache; GuiPainter* roi_painter; mutable QPixmap* legend_pixmap; unsigned char* imagebuff; unsigned int len; const float* data_cache; unsigned int nx_cache; unsigned int ny_cache; float lowbound_cache; float uppbound_cache; unsigned int nx_map_cache; unsigned int ny_map_cache; float lowbound_map_cache; float uppbound_map_cache; bool fire_map_cache; float *profile_x; float *profile_y; unsigned int coarseFactor_cache; bool colormap_cache; long unsigned int i; STD_list roi_polygon; float* roi_mask; bool mouse_moved; }; #endif odin-1.8.5/odinqt/float3d.h0000644000175000017500000000655411322062347012414 00000000000000/*************************************************************************** float3d.h - description ------------------- begin : Thu Nov 10 2005 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FLOAT3D_H #define FLOAT3D_H #include #include "float2d.h" /** * QGroupBox that contains a floatLabel2D and a slider to display 3D float arrays */ class floatBox3D : public QGroupBox { Q_OBJECT public: floatBox3D(const float *data, float lowbound, float uppbound, long int nx, long int ny, long int nz, int coarseFactor, QWidget *parent, const char *name, const float *overlay_map=0, float lowbound_map=0.0, float uppbound_map=0.0, unsigned int nx_map=0, unsigned int ny_map=0, unsigned int nz_map=0, bool map_firescale=false, float map_rectsize=0.8, bool colormap=false); ~floatBox3D(); void write_pixmap(const char* fname, const char* format, bool dump_all=false) const; QLabel* get_map_legend(QWidget* parent) const {return label->get_map_legend(parent);} void write_map_legend(const char* fname, const char* format) const {label->write_map_legend(fname, format);} public slots: void refresh(const float* data, float lowbound, float uppbound); void refreshMap(const float* map, float lowbound_map, float uppbound_map, float rectsize) {map_cache=map; label->refreshMap(map_cache+onemapsize*get_current_z(),lowbound_map,uppbound_map,rectsize);} private slots: void emitClicked(int xposition, int yposition) {emit clicked(xposition,yposition,get_current_z());} void emitNewProfile(const float *data, int npts, bool horizontal, int position) {emit newProfile(data, npts, horizontal, position);} void emitNewMask(const float *data) {emit newMask(data,get_current_z());} protected slots: void changez(int iz); signals: void clicked(int x, int y, int z); void newProfile(const float *data, int npts, bool horizontal, int position); void newMask(const float* data, int slice); protected: floatLabel2D* label; // GeoEditLabel needs access to it int get_current_z() const; private: virtual void repaint() {} // overload this function to draw additional stuff after changez void repaint_slice(int iz) const; GuiSlider* zslider; QLabel* zval; GuiGridLayout *grid; QLabel* maplegend; const float* data_cache; unsigned int oneimagesize; unsigned int nz_cache; float lowbound_cache; float uppbound_cache; const float* map_cache; float lowbound_map_cache; float uppbound_map_cache; float rectsize_map_cache; unsigned int onemapsize; float* mask3d; }; #endif odin-1.8.5/odinqt/enumbox.cpp0000644000175000017500000000271111322062347013057 00000000000000#include // for connecting signals #include "enumbox.h" enumBox::enumBox(const svector& items,QWidget *parent,const char *name,bool editButton,bool infoButton ) : QGroupBox(name, parent ) { pb_edit=0; pb_info=0; unsigned int row=1; if(editButton) row++; if(infoButton) row++; grid=new GuiGridLayout( this, 1, row); row=0; cb = new GuiComboBox( this, items ); grid->add_widget( cb->get_widget(), 0, row ); connect( cb->get_widget(), SIGNAL(activated(int)),this, SLOT(emitNewVal(int)) ); row++; if(editButton) { pb_edit = new GuiButton( this, this, SLOT(reportEditClicked()), "Edit" ); grid->add_widget( pb_edit->get_widget(), 0, row, GuiGridLayout::VCenter ); row++; // connect( pb_edit->get_widget(), SIGNAL(clicked()), SLOT(reportEditClicked()) ); } if(infoButton) { pb_info = new GuiButton( this, this, SLOT(reportInfoClicked()), "Info" ); grid->add_widget( pb_info->get_widget(), 0, row, GuiGridLayout::VCenter ); row++; // connect( pb_info->get_widget(), SIGNAL(clicked()), SLOT(reportInfoClicked()) ); } } void enumBox::emitNewVal( int selected ) { old_val=selected; emit newVal(old_val); } void enumBox::reportEditClicked() {emit edit();} void enumBox::reportInfoClicked() {emit info();} void enumBox::setValue( int val ) { old_val=val; cb->set_current_item(val); } enumBox::~enumBox(){ delete cb; if(pb_edit) delete pb_edit; if(pb_info) delete pb_info; delete grid; } odin-1.8.5/odinqt/floatedit.h0000644000175000017500000001120611322062347013021 00000000000000/*************************************************************************** floatedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FLOATEDIT_H #define FLOATEDIT_H #include #include "odinqt.h" /** * This class implements a line edit with float values only; A number * of digits to display must be specified. */ class floatLineEdit : public QObject { Q_OBJECT public: floatLineEdit(float minValue, float maxValue, float value, int digits, QWidget *parent, const char *name, int width, int height ); ~floatLineEdit(); QWidget* get_widget() {return gle->get_widget();} // required public for range slider void set_value(float value); float get_value() const {return value_cache;} public slots: void setfloatLineEditValue( float value); private slots: void emitSignal(); signals: void floatLineEditValueChanged(float value); private: int digits_cache; float value_cache; GuiLineEdit* gle; }; //////////////////////////////////////////////////////////////// /** * This class implements a slider with float values (of course it's still * discrete !), so you can use rational numbers as its values */ class floatSlider : public QObject { Q_OBJECT public: floatSlider(float minValue, float maxValue, float step, float value, QWidget *parent, const char *name ); ~floatSlider(); QWidget* get_widget(); public slots: void setfloatSliderValue( float value); private slots: void emitSignal( int discrete_value); signals: void floatSliderValueChanged( float newvalue); private: GuiSlider* gs; float minValue_cache; float step_cache; int oldPosition; }; //////////////////////////////////////////////////////////////// /** * This class contains a floatlineedit to display a float value * in a nice box with a label. */ class floatLineBox : public QGroupBox { Q_OBJECT public: floatLineBox(float value, int digits, QWidget *parent, const char *name); ~floatLineBox(); public slots: void setfloatLineBoxValue( float value ); private slots: void emitSignal( float value ); signals: void floatLineBoxValueChanged( float value ); private: GuiGridLayout* grid; floatLineEdit *le; }; //////////////////////////////////////////////////////////////// /** * This class implements a slider useful for scientific applications * by composing a floatSlider and a floatLineEdit into one widget. */ class floatScientSlider : public QGroupBox { Q_OBJECT public: floatScientSlider(float minValue, float maxValue, float Step, float value, int digits, QWidget *parent, const char *name); ~floatScientSlider(); public slots: void setfloatScientSliderValue( float value ); private slots: void emitSignal( float value ); signals: void floatScientSliderValueChanged( float value ); private: float value; floatSlider* slider; GuiGridLayout* grid; floatLineEdit *le; }; /////////////////////////////////////////////////////////////////////// /** * This class contains 3 floatlineedit to display 3 values * in a nice box with a label. */ class floatLineBox3D : public QGroupBox { Q_OBJECT public: floatLineBox3D(float xval, float yval, float zval, int digits, QWidget *parent, const char *name); ~floatLineBox3D(); public slots: void setfloatLineBox3DValue( float xval, float yval, float zval ); private slots: void emitSignal_x( float newval ); void emitSignal_y( float newval ); void emitSignal_z( float newval ); signals: void floatLineBox3DValueChanged( float xval, float yval, float zval ); void SignalToChild_x( float ); void SignalToChild_y( float ); void SignalToChild_z( float ); private: GuiGridLayout* grid; floatLineEdit *lex; floatLineEdit *ley; floatLineEdit *lez; float xcache; float ycache; float zcache; }; #endif odin-1.8.5/odinqt/jdxblockwidget.cpp0000644000175000017500000002317111363773557014432 00000000000000#include "jdxwidget.h" #include "jdxblockwidget.h" ///////////////////////////////////////////////////////////////////////////// JcampDxBlockGrid::JcampDxBlockGrid(JcampDxBlock& block,unsigned int columns,QWidget *parent,const char* omittext) : QWidget(parent), val(block) { Log odinlog(&block,"JcampDxBlockGrid(...)"); grid=0; STD_list subwidgets; STD_list::iterator it; unsigned int numof_pars=block.numof_pars(); JcampDxClass* ldrptr; // fill list with subwidgets for(unsigned int i=0;iisUserDefParameter() && (ldrptr->get_parmode()!=hidden)) { JDXwidget* ldrwidget=0; JcampDxBlock* blockdummy=ldrptr->cast(blockdummy); if(blockdummy) { unsigned int cols4block=1; if(blockdummy->numof_pars()>5) cols4block=2; ldrwidget=new JDXwidget(*ldrptr,cols4block,this,false,omittext); } else ldrwidget=new JDXwidget(*ldrptr,1,this,false,omittext); subwidgets.push_back(ldrwidget); } } unsigned int n_widget_rows=0; unsigned int rowheight=0; unsigned int colstart=0; // calculate n_widget_rows layout for(it=subwidgets.begin(); it!=subwidgets.end(); ++it) { unsigned int colwidth=(*it)->get_cols(); if( (colstart+colwidth) > 2 ) { // goto new row n_widget_rows+=rowheight; colstart=0; rowheight=0; } ODINLOG(odinlog,normalDebug) << "rows(" << (*it)->get_label() << ")=" << (*it)->get_rows() << STD_endl; if ( (*it)->get_rows() > rowheight ) rowheight=(*it)->get_rows(); colstart+=colwidth; } n_widget_rows+=rowheight; ODINLOG(odinlog,normalDebug) << "n_widget_rows/columns" << n_widget_rows << "/" << columns << STD_endl; unsigned int rows=(n_widget_rows/columns); // if(n_widget_rows%columns) rows++; rows++; unsigned int irow=0; unsigned int icolumn=0; rowheight=0; colstart=0; grid = new GuiGridLayout( this, rows , columns*2); ODINLOG(odinlog,normalDebug) << "creating " << rows << "x" << columns*2 << " grid" << STD_endl; for(it=subwidgets.begin(); it!=subwidgets.end(); ++it) { unsigned int colwidth=(*it)->get_cols(); if( (colstart+colwidth) > 2 ) { // goto new row irow+=rowheight; colstart=0; rowheight=0; } // rowheight=(*it)->get_rows(); if ( (*it)->get_rows() > rowheight ) rowheight=(*it)->get_rows(); if( (irow+rowheight) > rows ) { icolumn++; irow=0; } unsigned int coloffset=2*icolumn+colstart; unsigned int rowoffset=irow; colstart+=colwidth; int rowstart=rowoffset; // int rowend=rowoffset+rowheight-1; // int colstart=coloffset; // int colend=coloffset+colwidth-1; ODINLOG(odinlog,normalDebug) << (*it)->get_label() << " at " << "(" << rowstart << "-" << coloffset << "," << rowheight << "-" << colwidth << ")" << STD_endl; grid->add_widget( (*it), rowoffset, coloffset, GuiGridLayout::Center, rowheight, colwidth ); connect((*it),SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); connect(this,SIGNAL(updateSubWidget()),(*it),SLOT(updateWidget())); connect(this,SIGNAL(deleteSubDialogs()),(*it),SLOT(deleteDialogs())); } } void JcampDxBlockGrid::updateWidget() { for(STD_list::iterator it=subdialogs.begin(); it!=subdialogs.end(); ++it) { (*it)->updateWidget(); } emit updateSubWidget(); } void JcampDxBlockGrid::deleteDialogs() { emit deleteSubDialogs(); } void JcampDxBlockGrid::createDialog() { Log odinlog(&val,"createDialog"); JDXwidgetDialog* dlg=new JDXwidgetDialog(val,1,this); subdialogs.push_back(dlg); connect(dlg,SIGNAL(valueChanged()), this,SLOT(emitValueChanged())); emit valueChanged(); } ///////////////////////////////////////////////////////////////////////////// JcampDxBlockScrollView::JcampDxBlockScrollView(JcampDxBlock& block,unsigned int columns,QWidget *parent,const char* omittext) { Log odinlog(&block,"JcampDxBlockScrollView(...)"); jdxgrid=new JcampDxBlockGrid(block,columns,parent,omittext); connect(jdxgrid,SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); scroll=new GuiScroll(jdxgrid,parent); } JcampDxBlockScrollView::~JcampDxBlockScrollView() { delete scroll; } ///////////////////////////////////////////////////////////////////////////// JcampDxBlockWidget::JcampDxBlockWidget(JcampDxBlock& jdxblock,unsigned int columns,QWidget *parent,bool doneButton,bool is_dialog,const char* omittext, bool storeLoadButtons, bool readonly) : QGroupBox(jdxblock.get_label().c_str(), parent ), parblock(jdxblock) { Log odinlog(&jdxblock,"JcampDxBlockWidget(...)"); pb_done=0; pb_edit=0; pb_store=0; pb_load=0; grid=0; jdxscroll=0; noeditlist=0; if(jdxblock.is_embedded() || is_dialog) { int height=1; if(doneButton || storeLoadButtons) height=2; grid=new GuiGridLayout(this, height, 3); // if(jdxblock.get_parmode()==noedit) { if(readonly) { ODINLOG(odinlog,normalDebug) << "noedit mode" << STD_endl; svector columns; columns.resize(4); columns[0]="Name"; columns[1]="Value"; columns[2]="Unit"; columns[3]="Description"; noeditlist=new GuiListView(this, columns); grid->add_widget( noeditlist->get_widget(), 0, 0, GuiGridLayout::Default, 1, 3); unsigned int n=jdxblock.numof_pars(); noedititems.resize(n); for(unsigned int i=0; iset_default(true); pb_dummy->get_widget()->hide(); } if(doneButton) { pb_done = new GuiButton( this, this, SLOT(emitDone()), "Done" ); pb_done->set_default(false); grid->add_widget( pb_done->get_widget(), 1, 2, GuiGridLayout::Center ); // connect( pb_done->get_widget(), SIGNAL(clicked()), this,SLOT(emitDone()) ); } if(storeLoadButtons) { pb_store = new GuiButton( this, this, SLOT(storeBlock()), "Store ..." ); pb_load = new GuiButton( this, this, SLOT(loadBlock()), "Load ..." ); pb_store->set_default(false); pb_load->set_default(false); grid->add_widget( pb_store->get_widget(), 1, 0, GuiGridLayout::Center ); grid->add_widget( pb_load->get_widget(), 1, 1, GuiGridLayout::Center ); // connect( pb_store->get_widget(), SIGNAL(clicked()), this,SLOT(storeBlock()) ); // connect( pb_load->get_widget(), SIGNAL(clicked()), this,SLOT(loadBlock()) ); } } else { // if(block.is_embedded()) jdxscroll=new JcampDxBlockScrollView(jdxblock,columns,0,omittext); connect(jdxscroll,SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); grid=new GuiGridLayout( this, 1 , 1); pb_edit = new GuiButton( this, this, SLOT(createDialog()), "Edit" ); grid->add_widget( pb_edit->get_widget(), 0, 0, GuiGridLayout::Center ); // connect( pb_edit->get_widget(), SIGNAL(clicked()), this,SLOT(createDialog()) ); } } void JcampDxBlockWidget::createDialog() { Log odinlog("JcampDxBlockWidget","createDialog"); ODINLOG(odinlog,normalDebug) << "jdxscroll=" << jdxscroll << STD_endl; if(jdxscroll) jdxscroll->createDialog(); } JcampDxBlockWidget::~JcampDxBlockWidget() { if(pb_done) delete pb_done; if(pb_store) delete pb_store; if(pb_load) delete pb_load; if(grid) delete grid; if(jdxscroll) delete jdxscroll; if(noeditlist) delete noeditlist; for(int i=0; i odinlog(&ldr,"JDXwidgetDialog(...)"); grid=new GuiGridLayout(GuiDialog::get_widget(), 2, 1); jdx=new JcampDxBlockWidget(ldr,columns,GuiDialog::get_widget(),true,true, "", false, readonly); grid->add_widget( jdx, 0, 0 ); connect(jdx,SIGNAL(valueChanged()),this,SLOT(emitChanged())); connect(jdx,SIGNAL(doneButtonPressed()), this,SLOT(callDone()) ); GuiDialog::show(); #if QT_VERSION > 299 if(modal) GuiDialog::exec(); #endif } JDXwidgetDialog::~JDXwidgetDialog() { delete jdx; delete grid; } void JDXwidgetDialog::updateWidget() { jdx->updateWidget(); } void JDXwidgetDialog::callDone() { emit finished(); GuiDialog::done(); } void JDXwidgetDialog::emitChanged() { emit valueChanged(); } odin-1.8.5/odinqt/complex1d.cpp0000644000175000017500000002056211322062347013302 00000000000000#include // for mouse events #include "complex1d.h" #include "plot.h" complexfloatBox1D::complexfloatBox1D(const float *data1,const float *data2,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, float min_x, float max_x, bool detachable) : QGroupBox(name, parent ) { Log odinlog("complexfloatBox1D","complexfloatBox1D(const float* ...)"); common_init(name,fixed_size,data1,data2,xAxisLabel,yAxisLabelLeft,yAxisLabelRight,detachable); refresh(data1,data2,n,min_x,max_x); } complexfloatBox1D::complexfloatBox1D(const double *data1,const double *data2,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, float min_x, float max_x, bool detachable) : QGroupBox(name, parent ) { Log odinlog("complexfloatBox1D","complexfloatBox1D(const double* ...)"); common_init(name,fixed_size,data1,data2,xAxisLabel,yAxisLabelLeft,yAxisLabelRight,detachable); refresh(data1,data2,n,min_x,max_x); } void complexfloatBox1D::common_init(const char *name, bool fixed_size, bool data1, bool data2, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, bool detachable) { Log odinlog("complexfloatBox1D","common_init()"); detached=0; data1_ptr=0; data2_ptr=0; if(name) name_cache=name; if(xAxisLabel) xAxisLabel_cache=xAxisLabel; if(yAxisLabelLeft) yAxisLabelLeft_cache=yAxisLabelLeft; if(yAxisLabelRight) yAxisLabelRight_cache=yAxisLabelRight; detachable_cache=detachable; if(fixed_size) setFixedSize(_ARRAY_WIDGET_WIDTH_,_ARRAY_WIDGET_HEIGHT_); else setMinimumSize(_ARRAY_WIDGET_WIDTH_,_ARRAY_WIDGET_HEIGHT_); grid=new GuiGridLayout( this, 1, 1); plotter = new GuiPlot(this,fixed_size); ODINLOG(odinlog,normalDebug) << "xAxisLabel/yAxisLabelLeft/yAxisLabelRight=" << xAxisLabel << "/" << yAxisLabelLeft << "/" << yAxisLabelRight << STD_endl; plotter->set_x_axis_label(xAxisLabel); const char* data1_label=0; if(data1) data1_label=yAxisLabelLeft; const char* data2_label=0; if(data2) data1_label=yAxisLabelRight; plotter->set_y_axis_label(data1_label,data2_label); curveid1=0; curveid2=0; if(data1) curveid1 = plotter->insert_curve(false); if(data2) curveid2 = plotter->insert_curve(true); connect( plotter, SIGNAL(plotMousePressed(const QMouseEvent&)), SLOT(mousePressedInPlot(const QMouseEvent&)) ); connect( plotter, SIGNAL(plotMouseReleased(const QMouseEvent&)), SLOT(mouseReleasedInPlot(const QMouseEvent&)) ); grid->add_widget( plotter->get_widget(), 0, 0 ); } void complexfloatBox1D::create_x_cache(float min_x, float max_x, int n) { min_x_cache=min_x; max_x_cache=max_x; n_cache=n; int i; x_cache.resize(n); if(min_x odinlog("complexfloatBox1D","refresh(const float* ...)"); int i; ODINLOG(odinlog,normalDebug) << "data1/data2/n/min_x/max_x=" << data1 << "/" << data2 << "/" << n << "/" << min_x << "/" << max_x << STD_endl; create_x_cache(min_x, max_x, n); const double* x_arr=x_cache.c_array(); // call c_array only once data1_ptr=data2_ptr=0; if(data1) { data1_cache.resize(n); for(i=0; iset_curve_data(curveid1, x_arr, data1_ptr, n, nset_curve_data(curveid1, x_arr, data1_ptr, n, nset_curve_data(curveid2, x_arr, data2_ptr, n, nreplot(); if(detached) detached->refresh(data1_ptr,data2_ptr,n,min_x,max_x); } void complexfloatBox1D::mousePressedInPlot(const QMouseEvent& qme) { Log odinlog("complexfloatBox1D","mouseReleasedInPlot"); if(left_button(&qme,false)) { x_pressed=qme.x(); y_pressed=qme.y(); ODINLOG(odinlog,normalDebug) << "x_pressed/y_pressed=" << x_pressed << "/" << y_pressed << STD_endl; } if(right_button(&qme,false)) { GuiPopupMenu pm(this); pm.insert_item("Autoscale", this, SLOT(autoscale()), Qt::Key_F1); if(detachable_cache) pm.insert_item("Detach", this, SLOT(detach()), Qt::Key_F2); pm.popup(plotter->get_widget()->mapToGlobal(qme.pos())); } } void complexfloatBox1D::autoscale() { plotter->autoscale(); } void complexfloatBox1D::detach() { if(!detached) delete detached; detached=new DetachedComplexfloatBox1D(data1_ptr,data2_ptr,n_cache,this, name_cache.c_str(), false, xAxisLabel_cache.c_str(), yAxisLabelLeft_cache.c_str(), yAxisLabelRight_cache.c_str(), min_x_cache, max_x_cache); } void complexfloatBox1D::mouseReleasedInPlot(const QMouseEvent& qme) { Log odinlog("complexfloatBox1D","mouseReleasedInPlot"); // plotter->enable_outline(false); if(left_button(&qme,false)) { int x_released=qme.x(); int y_released=qme.y(); ODINLOG(odinlog,normalDebug) << "x_released/y_released=" << x_released << "/" << y_released << STD_endl; int low_x=x_pressed; if(x_releasedupp_x) upp_x=x_released; int upp_y=y_pressed; if(y_released>upp_y) upp_y=y_released; double x_axis_low=plotter->get_x(low_x); double x_axis_upp=plotter->get_x(upp_x); if(x_axis_lowset_x_axis_scale(x_axis_low,x_axis_upp); double y1_axis_low=plotter->get_y(upp_y); // reverse y-direction double y1_axis_upp=plotter->get_y(low_y); if(y1_axis_lowset_y_axis_scale(y1_axis_low,y1_axis_upp); ODINLOG(odinlog,normalDebug) << "y1_axis_low/y1_axis_upp=" << y1_axis_low << "/" << y1_axis_upp << STD_endl; double y2_axis_low=plotter->get_y(upp_y,true); // reverse y-direction double y2_axis_upp=plotter->get_y(low_y,true); if(y2_axis_lowset_y_axis_scale(y2_axis_low,y2_axis_upp,true); plotter->replot(); } } complexfloatBox1D::~complexfloatBox1D(){ delete plotter; delete grid; if(detached) delete detached; } ////////////////////////////////////////////////////////////////////////////////// void DetachedComplexfloatBox1D::create_grid() { grid = new GuiGridLayout( GuiDialog::get_widget(), 1, 1 ); grid->add_widget( cfb, 0, 0, GuiGridLayout::Center ); GuiDialog::show(); } DetachedComplexfloatBox1D::DetachedComplexfloatBox1D(const double *data1, const double *data2, int n,complexfloatBox1D *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, float min_x, float max_x) : GuiDialog(parent,name,false) { Log odinlog("DetachedComplexfloatBox1D","DetachedComplexfloatBox1D"); ODINLOG(odinlog,normalDebug) << "yAxisLabelLeft/xAxisLabel=" << yAxisLabelLeft << "/" << xAxisLabel << STD_endl; cfb=new complexfloatBox1D(data1, data2, n, GuiDialog::get_widget(), name, fixed_size, xAxisLabel, yAxisLabelLeft, yAxisLabelRight, min_x, max_x); create_grid(); } void DetachedComplexfloatBox1D::refresh(const double *data1,const double *data2,int n, float min_x, float max_x) { cfb->refresh(data1,data2,n,min_x,max_x); } DetachedComplexfloatBox1D::~DetachedComplexfloatBox1D() { delete grid; delete cfb; } odin-1.8.5/odinqt/odinqt.cpp0000644000175000017500000010642311363773557012726 00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if QT_VERSION > 0x03FFFF #define QT_VERSION_4 #else #define QT_VERSION_3 #endif #ifdef QT_VERSION_4 #include #include #include #include #include #include #include #include #else #include #include #include #include #endif #include "odinqt.h" #include "odinqt_callback.h" #include const char* OdinQt::get_compName() {return "OdinQt";} LOGGROUNDWORK(OdinQt) /////////////////////////////////////////////////// const char* c_str(const QString& qs) { if(qs.isEmpty()) return ""; #ifdef QT_VERSION_4 return qs.toAscii().constData(); #else return qs; #endif } int layout_border_size() { #ifdef QT_VERSION_4 return 0; #else return (3*QFontInfo(QFont(_FONT_TYPE_, _FONT_SIZE_)).pixelSize()/2); #endif } void init_label(QLabel* ql) { ql->setFrameStyle( QFrame::Box | QFrame::Sunken ); ql->setIndent( 0 ); #ifdef QT_VERSION_4 ql->setCursor(Qt::CrossCursor); #else ql->setCursor(Qt::crossCursor); #endif } bool left_button(const QMouseEvent* qme, bool return_current_state) { #ifdef QT_VERSION_4 if(return_current_state) return (qme->buttons() & Qt::LeftButton); else return (qme->button() & Qt::LeftButton); #else if(return_current_state) return (qme->state() & Qt::LeftButton); else return (qme->button() & Qt::LeftButton); #endif } bool right_button(const QMouseEvent* qme, bool return_current_state) { #ifdef QT_VERSION_4 if(return_current_state) return (qme->buttons() & Qt::RightButton); else return (qme->button() & Qt::RightButton); #else if(return_current_state) return (qme->state() & Qt::RightButton); else return (qme->button() & Qt::RightButton); #endif } bool middle_button(const QMouseEvent* qme, bool return_current_state) { #ifdef QT_VERSION_4 if(return_current_state) return (qme->buttons() & Qt::MidButton); else return (qme->button() & Qt::MidButton); #else if(return_current_state) return (qme->state() & Qt::MidButton); else return (qme->button() & Qt::MidButton); #endif } void add_tooltip(QWidget* w, const char* txt) { #ifdef QT_VERSION_4 w->setToolTip(txt); #else QToolTip::add(w,txt); #endif } void set_platform_defaults(QWidget* w, bool enable) { #ifdef Q_WS_MAC #ifdef QT_VERSION_4 w->setAttribute(Qt::WA_MacMetalStyle,enable); #endif #endif } STD_string get_save_filename(const char* caption, const char* startwith, const char* filter, QWidget* parent) { #ifdef QT_VERSION_4 QFileDialog::Options opts=0; #ifdef Q_WS_MAC opts=QFileDialog::DontUseNativeDialog; // native dialog does not work well, e.g. with symlinks #endif QString fname=QFileDialog::getSaveFileName(parent, caption, startwith, filter, 0, opts); #else QString fname=QFileDialog::getSaveFileName(startwith, filter, parent, "", caption); #endif return c_str(fname); } STD_string get_open_filename(const char* caption, const char* startwith, const char* filter, QWidget* parent) { #ifdef QT_VERSION_4 QFileDialog::Options opts=0; #ifdef Q_WS_MAC opts=QFileDialog::DontUseNativeDialog; // native dialog does not work well, e.g. with symlinks #endif QString fname=QFileDialog::getOpenFileName(parent, caption, startwith, filter, 0, opts); #else QString fname=QFileDialog::getOpenFileName(startwith, filter, parent, "", caption); #endif return c_str(fname); } STD_string get_directory(const char* caption, const char* startwith, QWidget* parent) { #ifdef QT_VERSION_4 QFileDialog::Options opts=QFileDialog::ShowDirsOnly; #ifdef Q_WS_MAC opts|=QFileDialog::DontUseNativeDialog; // native dialog does not work well, e.g. with symlinks #endif QString dname=QFileDialog::getExistingDirectory (parent, caption, startwith,opts); #else QString dname=QFileDialog::getExistingDirectory(startwith, parent, "", caption, true); #endif return c_str(dname); } bool message_question(const char* text, const char* caption, QWidget* parent, bool ask, bool error) { int result=0; if(ask) { // using QMessageBox::Ok and QMessageBox::Cancel does not work on Suse 9,10, // i.e. the order of buttons is mixed up due a patch to Qt, so we do it manually: QString okstr("Ok"); QString cancelstr("Cancel"); #if QT_VERSION > 0x030FFF result=QMessageBox::question(parent, caption, text, okstr, cancelstr); #else result=QMessageBox::information(parent, caption, text, okstr, cancelstr); #endif } else { if(error) result=QMessageBox::critical(parent, caption, text); else result=QMessageBox::information(parent, caption, text); } return (result==0); // return true if default button, which is 'Ok' , is clicked } /////////////////////////////////////////////////// int paintdevice_height(const QPaintDevice* qpd) { #ifdef QT_VERSION_4 return qpd->height(); #else QPaintDeviceMetrics metrics(qpd); return metrics.height(); #endif } int paintdevice_width(const QPaintDevice* qpd) { #ifdef QT_VERSION_4 return qpd->width(); #else QPaintDeviceMetrics metrics(qpd); return metrics.width(); #endif } /////////////////////////////////////////////////// svector get_possible_image_fileformats() { #ifdef QT_VERSION_4 QList fmtlist=QImageReader::supportedImageFormats(); int nfmts=fmtlist.size(); #else QStrList fmtlist=QImageIO::outputFormats(); int nfmts=fmtlist.count(); #endif svector result; result.resize(nfmts); for(int ifmt=0; ifmtsetMargin(layout_border_size()); } GuiGridLayout::~GuiGridLayout() { delete qgl; } void GuiGridLayout::add_widget(QWidget *w, int row, int column, Alignment alignment, int rowSpan, int columnSpan ) { #ifdef QT_VERSION_4 Qt::Alignment align=0; if(alignment==VCenter) align=Qt::AlignVCenter; if(alignment==VCenter) align=Qt::AlignVCenter; qgl->addWidget(w, row, column, rowSpan, columnSpan, align ); #else int align=0; if(alignment==VCenter) align=Qt::AlignVCenter; if(alignment==Center) align=Qt::AlignCenter; if(rowSpan==1 && columnSpan==1) qgl->addWidget( w, row, column, align ); else qgl->addMultiCellWidget( w, row, row+rowSpan-1, column, column+columnSpan-1, align ); #endif } void GuiGridLayout::set_col_stretch(int col, int factor) { #ifdef QT_VERSION_4 qgl->setColumnStretch(col,factor); #else qgl->setColStretch(col,factor); #endif } void GuiGridLayout::set_row_stretch(int row, int factor) { qgl->setRowStretch(row,factor); } void GuiGridLayout::set_col_minsize(int col, int minsize) { #ifdef QT_VERSION_4 qgl->setColumnMinimumWidth(col, minsize); #else qgl->addColSpacing(col, minsize); #endif } void GuiGridLayout::set_row_minsize(int row, int minsize) { #ifdef QT_VERSION_4 qgl->setRowMinimumHeight(row, minsize); #else qgl->addRowSpacing(row, minsize); #endif } /////////////////////////////////////////////////// GuiButton::GuiButton(QWidget *parent, QObject* receiver, const char* member, const char *onlabel,const char *offlabel, bool initstate) { ontext=onlabel; offtext=offlabel; qpb = new QPushButton(parent); if(onlabel && offlabel) { #ifdef QT_VERSION_4 qpb->setCheckable(true); #else qpb->setToggleButton(true); #endif set_toggled(initstate); // set initial text } else { if(ontext) qpb->setText(ontext); } qpb->setAutoDefault(false); // connect( qpb, SIGNAL(toggled(bool)), SLOT(setToggled(bool)) ); qpb->setFixedHeight( qpb->sizeHint().height() ); qpb->setFixedWidth( qpb->sizeHint().width() ); sd=new SlotDispatcher(this,receiver,member); } void GuiButton::set_text(bool state) { if(state) qpb->setText( ontext ); else qpb->setText( offtext ); } void GuiButton::set_toggled(bool state) { if(!(ontext && offtext)) return; set_text(state); #ifdef QT_VERSION_4 qpb->setChecked (state); #else qpb->setOn (state); #endif } void GuiButton::set_default(bool state) { qpb->setDefault (state); } QWidget* GuiButton::get_widget() { return qpb; } bool GuiButton::is_on() const { #ifdef QT_VERSION_4 return qpb->isChecked(); #else return qpb->isOn(); #endif } GuiButton::~GuiButton() { delete sd; delete qpb; } ///////////////////////////////////////////////// GuiLineEdit::GuiLineEdit(QWidget *parent, QObject* receiver, const char* member, int width, int height) { qle=new QLineEdit(parent); if(width>0 && height>0) qle->setFixedSize(width,height); sd=new SlotDispatcher(this,receiver,member); } GuiLineEdit::~GuiLineEdit() { delete sd; delete qle; } void GuiLineEdit::set_text(const char* txt) {qle->setText(txt);} const char* GuiLineEdit::get_text() const {return c_str(qle->text());} bool GuiLineEdit::is_modified() { #ifdef QT_VERSION_4 bool result=qle->isModified(); qle->setModified(false); #else bool result=qle->edited(); qle->setEdited(false); #endif return result; } QWidget* GuiLineEdit::get_widget() {return qle;} /////////////////////////////////////////////////// GuiPopupMenu::GuiPopupMenu(QWidget *parent) : id(0) { #ifdef QT_VERSION_4 qm=new QMenu(parent); #else qpm=new QPopupMenu(parent); #endif } GuiPopupMenu::~GuiPopupMenu() { /* // never deleted #ifdef QT_VERSION_4 delete qm; #else delete qpm; #endif */ } void GuiPopupMenu::insert_item(const char* text, const QObject* receiver, const char* member, int accel) { #ifdef QT_VERSION_4 qm->addAction(text, receiver, member, accel); #else id++; qpm->insertItem(text, receiver, member, accel, id); #endif } void GuiPopupMenu::insert_separator() { #ifdef QT_VERSION_4 qm->addSeparator(); #else qpm->insertSeparator(); #endif } void GuiPopupMenu::popup(const QPoint& p) { #ifdef QT_VERSION_4 qm->exec(p); // synchronous popup #else qpm->exec(p); // synchronous popup #endif } /////////////////////////////////////////////////// GuiSlider::GuiSlider(QWidget *parent, int minValue, int maxValue, int pageStep, int value, int tickInterval) : modified(false) { #ifdef QT_VERSION_4 qs=new QSlider(Qt::Horizontal, parent); qs->setRange(minValue, maxValue); qs->setPageStep(pageStep); qs->setValue(value); qs->setTickPosition(QSlider::TicksBelow); qs->setFocusPolicy( Qt::TabFocus ); #else qs=new QSlider(minValue, maxValue, pageStep, value, QSlider::Horizontal, parent, "QSlider" ); qs->setFocusPolicy( QWidget::TabFocus ); qs->setTickmarks( QSlider::Below ); #endif qs->setMinimumSize(2*SLIDER_CELL_WIDTH,SLIDER_CELL_HEIGHT); qs->setTickInterval(tickInterval ); } int GuiSlider::get_value() const {return qs->value();} void GuiSlider::set_value(int val) {modified=true; qs->setValue(val);} GuiSlider::~GuiSlider() { delete qs; } /////////////////////////////////////////////////// void GuiComboBox::set_names(const svector& names) { #ifdef QT_VERSION_4 for (unsigned int i=0; iinsertItem(i, names[i].c_str()); #else for (unsigned int i=0; iinsertItem( names[i].c_str() ); #endif set_current_item(0); } void GuiComboBox::common_init(QWidget* parent, const svector& names) { #ifdef QT_VERSION_4 qcb = new QComboBox(parent); qcb->setEditable(false); qcb->setSizeAdjustPolicy(QComboBox::AdjustToContents); // Width to fit all entries #else qcb = new QComboBox( FALSE, parent, "comboBox" ); qcb->setFixedWidth(qcb->sizeHint().width()); #endif qcb->setFixedHeight(qcb->sizeHint().height()); set_names(names); } GuiComboBox::GuiComboBox(QWidget* parent, const svector& names) { common_init(parent,names); } GuiComboBox::GuiComboBox(GuiToolBar* parent, const svector& names) { common_init(parent->get_widget(),names); #ifdef QT_VERSION_4 parent->qtb->addWidget(qcb); #endif } void GuiComboBox::set_current_item(int index) { #ifdef QT_VERSION_4 qcb->setCurrentIndex(index); #else qcb->setCurrentItem(index); #endif } int GuiComboBox::get_current_item() const { #ifdef QT_VERSION_4 return qcb->currentIndex(); #else return qcb->currentItem(); #endif } GuiComboBox::~GuiComboBox() { delete qcb; } /////////////////////////////////////////////////// GuiPainter::GuiPainter(QPixmap* qpm) { qpm_cache=qpm; qp=new QPainter(qpm); qp->setPen(_ARRAY_SELECTION_COLOR_); #ifndef QT_VERSION_4 qp->setFont(QFont(_FONT_TYPE_,_FONT_SIZE_)); #endif } GuiPainter::~GuiPainter() { delete qp; } void GuiPainter::moveTo(int x, int y) { #ifdef QT_VERSION_4 x_cache=x; y_cache=y; #else qp->moveTo(x,y); #endif } void GuiPainter::lineTo(int x, int y) { #ifdef QT_VERSION_4 qp->drawLine(x_cache,y_cache,x,y); x_cache=x; y_cache=y; #else qp->lineTo(x,y); #endif } void GuiPainter::repaint(QLabel* dst) { #ifdef QT_VERSION_4 // qp->drawPixmap(0,0,*qpm_cache); bool active=qp->isActive(); if(active) qp->end(); dst->setPixmap(*qpm_cache); if(active) { qp->begin(qpm_cache); qp->setPen(_ARRAY_SELECTION_COLOR_); } #else bitBlt( dst, 2, 2, qpm_cache ); #endif } bool GuiPainter::begin(QPixmap* qpm) { return qp->begin(qpm); } bool GuiPainter::end() { return qp->end(); } void GuiPainter::setPen(const char* pencolor, int linewidth, bool dotted, float lightdark) { Qt::PenStyle ps=Qt::SolidLine; if(dotted) ps=Qt::DotLine; QColor color(pencolor); int lightfactor=100+int(lightdark*90+0.5); QPen pen(color.light(lightfactor)); pen.setWidth(linewidth); pen.setStyle(ps); qp->setPen(pen); } void GuiPainter::fillRect( int x, int y, int w, int h, const QColor& col) { // Transparent: // QBrush qb(col); // qb.setStyle(Qt::Dense4Pattern); // qp->fillRect(QRect(x,y,w,h),qb); qp->fillRect(x,y,w,h,col); } void GuiPainter::drawRect(int x, int y, int w, int h) { qp->drawRect(x,y,w,h); } void GuiPainter::drawText( int x, int y, const QString& txt, const QColor& col) { qp->setPen( col); qp->drawText( x, y, txt); } QRegion* GuiPainter::draw_region(const STD_list& plist) { QRegion* rgn=0; if(plist.size()<3) return rgn; #ifdef QT_VERSION_4 QPolygon qpg(plist.size()); unsigned int index=0; for(STD_list::const_iterator it=plist.begin(); it!=plist.end(); ++it) { qpg.setPoint(index, it->x(), it->y()); index++; } rgn=new QRegion(qpg,Qt::WindingFill); #else QPointArray qpa(plist.size()); unsigned int index=0; for(STD_list::const_iterator it=plist.begin(); it!=plist.end(); ++it) { qpa.setPoint(index, it->x(), it->y()); index++; } rgn=new QRegion(qpa,TRUE); #endif qp->setClipRegion(*rgn); qp->fillRect (0,0,qpm_cache->width(),qpm_cache->height(),QBrush(QColor(_ARRAY_SELECTION_COLOR_),Qt::DiagCrossPattern)); return rgn; } /////////////////////////////////////////////////// GuiApplication::GuiApplication(int argc, char *argv[]) { // Create pristine copy of cmdline args for Qt before anything else argc4qt=argc; argv4qt=new char*[argc]; for(int iarg=0; iarg odinlog("GuiApplication","GuiApplication"); ODINLOG(odinlog,normalDebug) << "argc/argv=" << argc << "/" << argv << STD_endl; argc_cache=argc; argv_cache=argv; qa=new QApplication(argc4qt,argv4qt); #ifndef QT_VERSION_4 qa->setFont(QFont(_FONT_TYPE_, _FONT_SIZE_)); #endif // setting text color back to normal, even if noedit QPalette pal=qa->palette(); #ifdef QT_VERSION_4 pal.setColor(QPalette::Disabled, QPalette::Foreground, pal.color ( QPalette::Active, QPalette::Foreground ) ); pal.setColor(QPalette::Disabled, QPalette::Text, pal.color ( QPalette::Active, QPalette::Text ) ); qa->setPalette(pal); #else pal.setColor(QColorGroup::Foreground, pal.color ( QPalette::Normal, QColorGroup::Foreground ) ); pal.setColor(QColorGroup::Text, pal.color ( QPalette::Normal, QColorGroup::Text ) ); qa->setPalette(pal,true); #endif ODINLOG(odinlog,normalDebug) << "GuiApplication::argc/argv()=" << GuiApplication::argc() << "/" << GuiApplication::argv() << STD_endl; } int GuiApplication::start(QWidget* mainwidget) { #ifndef QT_VERSION_4 qa->setMainWidget(mainwidget); #endif // mainwidget->show(); return qa->exec(); } QObject* GuiApplication::get_object() {return qa;} void GuiApplication::quit() {qApp->quit();} int GuiApplication::argc() {return argc_cache;} char** GuiApplication::argv() {return argv_cache;} void GuiApplication::process_events() {qApp->processEvents();} GuiApplication::~GuiApplication() { qa->quit(); delete qa; // We must delete it to avoid error message when starting as edit widget in Paravision } int GuiApplication::argc4qt; char** GuiApplication::argv4qt; int GuiApplication::argc_cache; char** GuiApplication::argv_cache; /////////////////////////////////////////////////// GuiMainWindow::GuiMainWindow(QWidget* parent) { statusIcon=0; statusText=0; qmw=new QMainWindow(parent); // set_platform_defaults(qmw); // does not work because it alters attributes of all widgets } GuiMainWindow::~GuiMainWindow() { delete qmw; if(statusIcon) delete statusIcon; if(statusText) delete statusText; } void GuiMainWindow::show(QWidget* central_widget, bool show_toolbutton_text) { set_status_message("Ready ...", 2000); // necessary to show status bar in the first place #ifdef QT_VERSION_4 if(show_toolbutton_text) qmw->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); #else qmw->setUsesTextLabel(show_toolbutton_text); #endif central_widget->setFocus(); qmw->setCentralWidget(central_widget); qmw->show(); } void GuiMainWindow::set_caption(const char* text) { STD_string captext(text); #ifdef QT_VERSION_4 qmw->setWindowTitle(captext.c_str()); #else qmw->setCaption(captext.c_str()); #endif } void GuiMainWindow::set_status_message(const char* text, int timeout_ms) { if(statusText) statusText->setText(text); else { #ifdef QT_VERSION_4 qmw->statusBar()->showMessage(text,timeout_ms); #else if(timeout_ms) qmw->statusBar()->message(text); else qmw->statusBar()->message(text,timeout_ms); #endif } } void GuiMainWindow::set_status_xpm(const char** xpm) { QPixmap qp(xpm); if(!statusIcon) { statusIcon=new QLabel(qmw->statusBar()); statusText=new QLabel(qmw->statusBar()); statusText->setMinimumWidth(qmw->width()-qp.width()); #ifdef QT_VERSION_4 qmw->statusBar()->addPermanentWidget(statusIcon); qmw->statusBar()->addPermanentWidget(statusText); #else qmw->statusBar()->addWidget(statusIcon,1,true); qmw->statusBar()->addWidget(statusText,1,true); #endif } statusIcon->setPixmap(qp); } QWidget* GuiMainWindow::get_widget() {return qmw;} void GuiMainWindow::insert_menu( const char* text, GuiPopupMenu* gpm) { #ifdef QT_VERSION_4 gpm->qm->setTitle(text); qmw->menuBar()->addMenu(gpm->qm); #else qmw->menuBar()->insertItem(text, gpm->qpm); #endif } void GuiMainWindow::insert_menu_separator() { #ifdef QT_VERSION_4 qmw->menuBar()->addSeparator(); #else qmw->menuBar()->insertSeparator(); #endif } void GuiMainWindow::close() { qmw->close(); } /////////////////////////////////////////////////// GuiScroll::GuiScroll(QWidget* child, QWidget* parent) { #ifdef QT_VERSION_4 qsa=new QScrollArea(parent); qsa->setWidget(child); qsa->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); qsa->setMinimumWidth(child->width()); #else qsv=new QScrollView(parent); qsv->addChild(child); qsv->setHScrollBarMode(QScrollView::AlwaysOff); qsv->setMinimumWidth(child->width()); #endif } QWidget* GuiScroll::get_widget() { #ifdef QT_VERSION_4 return qsa; #else return qsv; #endif } GuiScroll::~GuiScroll() { #ifdef QT_VERSION_4 delete qsa; #else delete qsv; #endif } /////////////////////////////////////////////////// class QDialogDerived : public QDialog { public: QDialogDerived(GuiDialog* user, QWidget *parent, const char* caption, bool modal) : #ifdef QT_VERSION_4 QDialog(parent) { QDialog::setModal(modal); QDialog::setWindowTitle(caption); #else QDialog(parent,"",modal) { QDialog::setCaption(caption); #endif user_cache=user; } void call_done(int r) { QDialog::done(r); } protected: void paintEvent(QPaintEvent* event) { // overloaded from QWidget QDialog::paintEvent(event); user_cache->repaint(); } void closeEvent(QCloseEvent* event) { // overloaded from QWidget QDialog::closeEvent(event); user_cache->close(); } private: GuiDialog* user_cache; }; GuiDialog::GuiDialog(QWidget *parent, const char* caption, bool modal) { qd=new QDialogDerived(this, parent, caption, modal); } void GuiDialog::show() { qd->show(); } void GuiDialog::cancel() { qd->call_done(0); } void GuiDialog::done() { qd->call_done(1); // GuiDialog::hide(); // deleting causes segfault. why? I dunno ... } void GuiDialog::hide() {qd->hide();} int GuiDialog::exec() {return qd->exec();} QWidget* GuiDialog::get_widget() {return qd;} GuiDialog::~GuiDialog() { delete qd; } ///////////////////////////////////////////////// GuiProgressDialog::GuiProgressDialog(QWidget *parent, bool modal, int total_steps) { #ifdef QT_VERSION_4 qpd=new QProgressDialog("", "Cancel", 0, total_steps, parent); qpd->setModal(modal); #else qpd=new QProgressDialog("", "Cancel", total_steps, parent, "progress", modal); #endif if(total_steps) qpd->setMinimumDuration(1000); else qpd->setMinimumDuration(100); // zero value produces event-timing problems in Qt set_progress(0); } void GuiProgressDialog::set_progress(int progr) { #ifdef QT_VERSION_4 qpd->setValue(progr); #else qpd->setProgress(progr); #endif } int GuiProgressDialog::get_progress() const { #ifdef QT_VERSION_4 return qpd->value(); #else return qpd->progress(); #endif } void GuiProgressDialog::set_total_steps(int steps) { #ifdef QT_VERSION_4 qpd->setMaximum(steps); #else qpd->setTotalSteps(steps); #endif } bool GuiProgressDialog::was_cancelled() const { #ifdef QT_VERSION_4 return qpd->wasCanceled(); #else return qpd->wasCancelled(); #endif } void GuiProgressDialog::reset() { qpd->reset(); set_progress(0); } void GuiProgressDialog::set_text(const char* txt) { qpd->setLabelText(txt); } void GuiProgressDialog::show() { qpd->show(); } void GuiProgressDialog::hide() { qpd->hide(); } GuiProgressDialog::~GuiProgressDialog() { delete qpd; } ///////////////////////////////////////////////// GuiImage::GuiImage(unsigned char* data, int width, int height, bool colormap) { Log odinlog("GuiImage","GuiImage"); ODINLOG(odinlog,normalDebug) << "width/height/colormap=" << width << "/" << height << "/" << colormap << STD_endl; #ifdef QT_VERSION_4 qi=new QImage( data, width, height, QImage::Format_Indexed8); qi->setNumColors (256); #else qi=new QImage( data, width, height, 8, 0, 256, QImage::IgnoreEndian); #endif QColor qc; for(int i=0; i<256; i++) { if(colormap) { int hue=int(240.0*(1.0-float(i)/255.0)); qc.setHsv(hue,255,255); qi->setColor(i, qc.rgb() ); if(i==0) qi->setColor(0, qRgb(0,0,0) ); // lowest value black } else qi->setColor(i, qRgb(i,i,i) ); // simple gray scale } } QPixmap* GuiImage::create_pixmap() const { #ifdef QT_VERSION_4 return new QPixmap(QPixmap::fromImage(*qi)); #else QPixmap* qpm=new QPixmap(); qpm->convertFromImage(*qi); return qpm; #endif } GuiImage::~GuiImage() { delete qi; } ///////////////////////////////////////////////// GuiListView::GuiListView(QWidget *parent, const svector& column_labels, int first_column_width, int min_height, GuiListViewCallback* callback, bool tree) { #ifdef QT_VERSION_4 QStringList qsl; for(unsigned int i=0; i1) width_factor=2; if(tree) { qtrw=new QTreeWidget(parent); qtrw->setColumnCount(column_labels.size()); qtrw->setHeaderLabels(qsl); qtrw->setSortingEnabled(false); if(min_height>0) qtrw->setMinimumHeight(min_height); if(first_column_width>0) qtrw->setMinimumWidth(width_factor*first_column_width); qtrw->header()->resizeSection(0, first_column_width); } else { qtw=new QTableWidget(parent); qtw->setColumnCount(column_labels.size()); qtw->setHorizontalHeaderLabels(qsl); if(min_height>0) qtw->setMinimumHeight(min_height); if(first_column_width>0) { qtw->setMinimumWidth(width_factor*first_column_width); qtw->horizontalHeader()->resizeSection(0, first_column_width); } } #else qlv=new QListView(parent); for(unsigned int i=0; iaddColumn (column_labels[i].c_str()); } if(first_column_width>0) { qlv->setColumnWidthMode(0,QListView::Manual); qlv->setColumnWidth(0,first_column_width); } if(min_height>0) { qlv->setMinimumHeight(min_height); } qlv->setSorting(-1); #endif sd=0; if(callback) sd=new SlotDispatcher(this, callback); } QWidget* GuiListView::get_widget() { #ifdef QT_VERSION_4 if(qtrw) return qtrw; if(qtw) return qtw; return 0; #else return qlv; #endif } GuiListView::~GuiListView() { delete sd; #ifdef QT_VERSION_4 if(qtrw) delete qtrw; if(qtw) delete qtw; #else delete qlv; #endif } ///////////////////////////////////////////////// #ifndef QT_VERSION_4 void create_qstring_list(STD_vector& label, const svector& column_entries) { int ncols=column_entries.size(); if(ncols>8) ncols=8; label.resize(8); for(int i=0; i odinlog("GuiListItem","GuiListItem"); common_init(); #ifdef QT_VERSION_4 int ncols=column_entries.size(); if(!ncols) return; if(parent->qtrw) { // tree view qtrwi=new QTreeWidgetItem(parent->qtrw); for(int icol=0; icolsetText(icol, column_entries[icol].c_str()); } parent_qtrw=parent->qtrw; parent->qtrw->expandItem(qtrwi); //#warning GuiListItem: Implement me: setOpen(true), setSelected(false) } else { qtwi=new QTableWidgetItem[ncols]; int row=parent->qtw->rowCount(); parent->qtw->setRowCount(row+1); for(int icol=0; icolqtw->setItem(row, icol, &(qtwi[icol])); } if(checkable) { qtwi[0].setFlags(qtwi[0].flags() | Qt::ItemIsUserCheckable); Qt::CheckState state=Qt::Unchecked; if(initstate) state=Qt::Checked; qtwi[0].setCheckState(state); } (*tablemap)[&(qtwi[0])]=this; } #else QListViewItem* last=parent->qlv->lastItem(); if(checkable) { qcli=new QCheckListItem (parent->qlv, column_entries[0].c_str(), QCheckListItem::CheckBox); qcli->setOn(initstate); } else { STD_vector label; create_qstring_list(label,column_entries); ODINLOG(odinlog,normalDebug) << "parent->qlv=" << parent->qlv << STD_endl; qlvi=new QListViewItem(parent->qlv, label[0], label[1], label[2], label[3], label[4], label[5], label[6], label[7]); ODINLOG(odinlog,normalDebug) << "qlvi=" << qlvi << STD_endl; if(last) qlvi->moveItem(last); // append at end qlvi->setSelected(false); qlvi->setOpen(true); (*listmap)[qlvi]=this; } #endif } GuiListItem::GuiListItem(GuiListItem* parent, GuiListItem* after, const svector& column_entries) { Log odinlog("GuiListItem","GuiListItem"); common_init(); #ifdef QT_VERSION_4 QTreeWidgetItem* parent_qtrwi=0; if(parent) parent_qtrwi=parent->qtrwi; QTreeWidgetItem* after_qtrwi=0; if(after) after_qtrwi=after->qtrwi; qtrwi=new QTreeWidgetItem(parent_qtrwi, after_qtrwi); for(int icol=0; icolsetText(icol, column_entries[icol].c_str()); } parent_qtrw=parent->parent_qtrw; if(parent_qtrw) parent_qtrw->expandItem(qtrwi); //#warning GuiListItem: Implement me: setOpen(true) #else STD_vector label; create_qstring_list(label,column_entries); QListViewItem* parent_qlvi=0; if(parent) parent_qlvi=parent->qlvi; ODINLOG(odinlog,normalDebug) << "parent/parent_qlvi=" << parent << "/" << parent_qlvi << STD_endl; if(after && after->qlvi) { ODINLOG(odinlog,normalDebug) << "after->qlvi=" << after->qlvi << STD_endl; qlvi=new QListViewItem(parent_qlvi, after->qlvi, label[0], label[1], label[2], label[3], label[4], label[5], label[6], label[7]); } else { ODINLOG(odinlog,normalDebug) << "after=0" << STD_endl; qlvi=new QListViewItem(parent_qlvi, label[0], label[1], label[2], label[3], label[4], label[5], label[6], label[7]); } qlvi->setOpen(true); #endif } bool GuiListItem::is_checked() const { #ifdef QT_VERSION_4 if(qtwi) return ((qtwi[0].checkState())==Qt::Checked); #else if(qcli) return qcli->isOn(); #endif return false; } const char* GuiListItem::get_text() const { #ifdef QT_VERSION_4 if(qtwi) return c_str(qtwi[0].text()); #else if(qcli) return c_str(qcli->text()); #endif return ""; } GuiListItem::~GuiListItem() { #ifdef QT_VERSION_4 if(qtwi) delete[] qtwi; if(qtrwi) delete qtrwi; #else if(qlvi) delete qlvi; if(qcli) delete qcli; #endif } void GuiListItem::init_static() { #ifdef QT_VERSION_4 tablemap=new STD_map; #else listmap=new STD_map; #endif } void GuiListItem::destroy_static() { #ifdef QT_VERSION_4 delete tablemap; #else delete listmap; #endif } STD_map* GuiListItem::listmap; STD_map* GuiListItem::tablemap; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; /////////////////////////////////////////////////////////// GuiProgressBar::GuiProgressBar(QWidget *parent, int total_steps) { #ifdef QT_VERSION_4 qpb=new QProgressBar(parent); qpb->setMinimum(0); qpb->setMaximum(total_steps); #else qpb=new QProgressBar (total_steps, parent); #endif } GuiProgressBar::~GuiProgressBar() { delete qpb; } void GuiProgressBar::set_progress(int progr) { #ifdef QT_VERSION_4 qpb->setValue(progr); #else qpb->setProgress(progr); #endif } void GuiProgressBar::set_min_width(int w) { qpb->setMinimumWidth(w); } QWidget* GuiProgressBar::get_widget() { return qpb; } ////////////////////////////////////////////////////////////////////// GuiScrollBar::GuiScrollBar(QWidget* parent) { qsb=new QScrollBar(Qt::Horizontal, parent); } GuiScrollBar::~GuiScrollBar() { delete qsb; } void GuiScrollBar::set_values(int min, int max, int linestep, int pagestep, int value) { #ifdef QT_VERSION_4 qsb->setMinimum(min); qsb->setMaximum(max); qsb->setSingleStep(linestep); #else qsb->setMinValue(min); qsb->setMaxValue(max); qsb->setLineStep(linestep); #endif qsb->setPageStep(pagestep); qsb->setValue(value); } QScrollBar* GuiScrollBar::get_widget() { return qsb; } ///////////////////////////////////////////////// GuiToolBar::GuiToolBar(GuiMainWindow* parent, const char* label) { qtb=new QToolBar(label, parent->qmw); #ifdef QT_VERSION_4 parent->qmw->addToolBar(qtb); #endif } GuiToolBar::~GuiToolBar() { delete qtb; } QWidget* GuiToolBar::get_widget() { return qtb; } void GuiToolBar::add_separator() { qtb->addSeparator(); } ///////////////////////////////////////////////// GuiToolButton::GuiToolButton(GuiToolBar* parent, const char** xpm, const char* label, QObject* receiver, const char* member, bool checkable, bool initstate ) { #ifdef QT_VERSION_4 qtb=new QToolButton(parent->qtb); if(xpm) qtb->setIcon(QPixmap(xpm)); qtb->setCheckable(checkable); parent->qtb->addWidget(qtb); #else qtb=new QToolButton(parent->qtb); if(xpm) qtb->setIconSet(QPixmap(xpm)); qtb->setToggleButton(checkable); #endif set_on(initstate); if(xpm) set_tooltip(label); else set_label(label); sd=new SlotDispatcher(this,receiver,member); } GuiToolButton::~GuiToolButton() { Log odinlog("GuiToolButton","~GuiToolButton"); ODINLOG(odinlog,normalDebug) << "Deleting sd" << STD_endl; delete sd; #ifndef QT_VERSION_4 ODINLOG(odinlog,normalDebug) << "Deleting qtb" << STD_endl; delete qtb; // will be done by the parent toolbar on Qt4 #endif } bool GuiToolButton::is_on() const { #ifdef QT_VERSION_4 return qtb->isChecked(); #else return qtb->isOn(); #endif } void GuiToolButton::set_on(bool flag) { #ifdef QT_VERSION_4 qtb->setChecked(flag); #else qtb->setOn(flag); #endif } void GuiToolButton::set_enabled(bool flag) { qtb->setEnabled(flag); } void GuiToolButton::set_label(const char* text) { #ifdef QT_VERSION_4 qtb->setText(text); #else qtb->setTextLabel(text); #endif } void GuiToolButton::set_tooltip(const char* text) { add_tooltip(qtb,text); } ///////////////////////////////////////////////// GuiPrinter::GuiPrinter() { qp=new QPrinter(QPrinter::HighResolution); qp->setOrientation(QPrinter::Landscape); } bool GuiPrinter::setup(QWidget* parent) { #ifdef QT_VERSION_4 QPrintDialog* qpd=new QPrintDialog(qp,parent); return bool(qpd->exec()); #else return qp->setup(parent); #endif } QPaintDevice* GuiPrinter::get_device() { return qp; } GuiPrinter::~GuiPrinter() { delete qp; } ///////////////////////////////////////////////// #define TEXTVIEW_MAXLINES 1000 GuiTextView::GuiTextView(QWidget* parent, int minwidth, int minheight) { qte=new QTextEdit(parent); qte->setReadOnly(true); qte->setMinimumSize(minwidth, minheight); #ifdef QT_VERSION_4 qte->document()->setMaximumBlockCount(TEXTVIEW_MAXLINES); // only available for Qt 4.2 or later versions qte->setLineWrapMode(QTextEdit::NoWrap); #else qte->setTextFormat(Qt::LogText); #if QT_VERSION > 0x0301FF qte->setMaxLogLines(TEXTVIEW_MAXLINES); #endif #endif } GuiTextView::~GuiTextView() { delete qte; } void GuiTextView::set_text(const char* txt) { #ifdef QT_VERSION_4 qte->setPlainText(txt); #else qte->setText(txt); #endif scroll_end(); } void GuiTextView::append_text(const char* txt) { qte->append(txt); scroll_end(); } void GuiTextView::scroll_end() { #ifdef QT_VERSION_4 QTextCursor qtc(qte->textCursor()); qtc.movePosition(QTextCursor::End); qtc.movePosition(QTextCursor::StartOfLine); qte->setTextCursor(qtc); qte->ensureCursorVisible(); #else qte->setContentsPos(0,qte->contentsHeight()+TEXTVIEW_MAXLINES); #endif } QWidget* GuiTextView::get_widget() { return qte; } odin-1.8.5/odinqt/jdxwidget.cpp0000644000175000017500000007550211363773557013424 00000000000000 // Include Qt stuff first to avoid ambiguities with 'debug' symbol #include "intedit.h" #include "floatedit.h" #include "float1d.h" #include "complex1d.h" #include "float3d.h" #include "boolbutton.h" #include "enumbox.h" #include "stringbox.h" #include "jdxwidget.h" #include "jdxblockwidget.h" #include #include #include #include #include /** * * Helper class to analayze the value range of a (scalar) JDX parameter */ class RangeHelper { public: double minval; double maxval; RangeHelper(const JcampDxClass& ldr) { minval=ldr.get_minval(); maxval=ldr.get_maxval(); } bool has_range() { if(maxval>minval) return true; else return false; } double get_stepsize(unsigned int maxsteps) { Log odinlog("RangeHelper","get_stepsize"); double result=fabs(maxval-minval)/double(maxsteps); double mantisse=log10(result); mantisse=int(mantisse-1.0); result=double(int(result*pow(10.0,-mantisse)))*pow(10.0,mantisse); ODINLOG(odinlog,normalDebug) << "minval=" << minval << STD_endl; ODINLOG(odinlog,normalDebug) << "maxval=" << maxval << STD_endl; ODINLOG(odinlog,normalDebug) << "mantisse=" << mantisse << STD_endl; ODINLOG(odinlog,normalDebug) << "stepsize=" << result << STD_endl; return result; } }; ///////////////////////////////////////////////////////////////////////// JDXwidget::JDXwidget(JcampDxClass& ldr,unsigned int columns, QWidget *parent, bool doneButton, const char* omittext, bool storeLoadButtons ) : QWidget(parent), val(ldr) { Log odinlog(&val,"JDXwidget(...)"); vport=this; widget_cache=0; blockwidget=0; intslider=0; intedit=0; floatslider=0; floatedit=0; enumwidget=0; boolwidget=0; floatArrempty=0; floatArrwidget1=0; floatArredit=0; // doubleArrwidget1=0; floatArrwidget2=0; complexArrwidget=0; stringwidget=0; filenamewidget=0; funcwidget=0; formulawidget=0; triplewidget=0; grid=0; rows=1; cols=1; if(columns<1) columns=1; bool cast_success=true; ldrlabel_uncut=replaceStr(ldr.get_label(),omittext,"",allOccurences); ldrlabel=ldrlabel_uncut; label_cut=false; if(ldrlabel.length()>_MAX_LABEL_LENGTH_) { label_cut=true; ldrlabel=ldrlabel_uncut.substr(0,_MAX_LABEL_LENGTH_)+"..."; } STD_string unit(ldr.get_unit()); if(unit!="") ldrlabel+=" ["+unit+"]"; ODINLOG(odinlog,normalDebug) << "ldrlabel/omittext=" << ldrlabel << "/" << omittext << STD_endl; grid=new GuiGridLayout( vport, 1, 1, false); ODINLOG(odinlog,normalDebug) << "grid & layout done" << STD_endl; /*---------------- JDX types BEGIN ------------------------*/ /*---------------- JcampDxBlock ------------------------*/ JcampDxBlock* dumblock=ldr.cast(dumblock); if(dumblock) { label_cut=false; if(dumblock->is_embedded()) cols=2; blockwidget=new JcampDxBlockWidget(*dumblock,columns,vport,doneButton,false,omittext,storeLoadButtons); ODINLOG(odinlog,normalDebug) << "JcampDxBlock: JcampDxBlockWidget done" << STD_endl; GuiGridLayout::Alignment alignment = GuiGridLayout::Default; if(dumblock->numof_pars()<_MAX_SUBWIDGETS_FOR_ALIGNCENT_) alignment=GuiGridLayout::VCenter; set_widget(blockwidget ,alignment, true); ODINLOG(odinlog,normalDebug) << "JcampDxBlock: set_widget done" << STD_endl; connect(blockwidget,SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); connect(blockwidget,SIGNAL(doneButtonPressed()),this,SLOT(emitDone())); ODINLOG(odinlog,normalDebug) << "JcampDxBlock: connect done" << STD_endl; } ODINLOG(odinlog,normalDebug) << "JcampDxBlock done" << STD_endl; /*---------------- JDXint ------------------------*/ int* dumint=ldr.cast(dumint); if(dumint) { RangeHelper intrange(ldr); if(intrange.has_range() && ldr.get_parmode()==edit) { cols=2; long step=int(intrange.get_stepsize(_MAX_SLIDER_STEPS_)); if(step<1) step=1; ODINLOG(odinlog,normalDebug) << "processing >" << ldrlabel << "<" << STD_endl; intslider=new intScientSlider(int(intrange.minval),int(intrange.maxval),step,*dumint,vport,ldrlabel.c_str()); set_widget(intslider); connect(intslider,SIGNAL(intScientSliderValueChanged( int )),this,SLOT(changeJDXint( int ))); connect(this,SIGNAL(newintval( int )),intslider,SLOT(setintScientSliderValue( int ))); } else { intedit=new intLineBox(*dumint,vport,ldrlabel.c_str()); set_widget(intedit); connect(intedit,SIGNAL(intLineBoxValueChanged( int )),this,SLOT(changeJDXint( int ))); connect(this,SIGNAL(newintval( int )),intedit,SLOT(setintLineBoxValue( int ))); } } ODINLOG(odinlog,normalDebug) << "JDXint done" << STD_endl; /*---------------- JDXfloat & JDXdouble ------------------------*/ float* dumfloat=ldr.cast(dumfloat); double* dumdouble=ldr.cast(dumdouble); if(dumfloat || dumdouble ) { float val=0.0; if(dumfloat) val=(*dumfloat); if(dumdouble) val=(*dumdouble); RangeHelper floatrange(ldr); if(floatrange.has_range() && ldr.get_parmode()==edit) { cols=2; floatslider=new floatScientSlider(floatrange.minval,floatrange.maxval,floatrange.get_stepsize(_MAX_SLIDER_STEPS_),val,_FLOAT_DIGITS_,vport,ldrlabel.c_str()); set_widget(floatslider); connect(floatslider,SIGNAL(floatScientSliderValueChanged( float )),this,SLOT(changeJDXfloat( float ))); connect(this,SIGNAL(newfloatval( float )),floatslider,SLOT(setfloatScientSliderValue( float ))); } else { floatedit=new floatLineBox(val,_FLOAT_DIGITS_,vport,ldrlabel.c_str()); set_widget(floatedit); connect(floatedit,SIGNAL(floatLineBoxValueChanged( float )),this,SLOT(changeJDXfloat( float ))); connect(this,SIGNAL(newfloatval( float )),floatedit,SLOT(setfloatLineBoxValue( float ))); } } ODINLOG(odinlog,normalDebug) << "JDXfloat & JDXdouble done" << STD_endl; /*---------------- JDXenum ------------------------*/ JDXenum* dumenum=ldr.cast(dumenum); if(dumenum) { enumwidget=new enumBox(dumenum->get_alternatives(),vport,ldrlabel.c_str()); enumwidget->setValue(dumenum->get_item_index()); set_widget(enumwidget); ODINLOG(odinlog,normalDebug) << "widget done" << STD_endl; connect(enumwidget,SIGNAL(newVal( int )), this,SLOT(changeJDXenum( int ))); connect(this,SIGNAL(newenumval( int )),enumwidget,SLOT(setValue( int ))); ODINLOG(odinlog,normalDebug) << "connect done" << STD_endl; } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXenum done" << STD_endl; /*---------------- JDXbool ------------------------*/ bool* dumbool=ldr.cast(dumbool); if(dumbool) { boolwidget=new buttonBox("Yes","No",*dumbool, vport, ldrlabel.c_str()); set_widget(boolwidget); connect(boolwidget,SIGNAL(buttonToggled(bool)), this,SLOT(changeJDXbool( bool ))); connect(this,SIGNAL(newboolval( bool )),boolwidget,SLOT(setToggleState( bool ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXbool done" << STD_endl; /*---------------- JDXaction ------------------------*/ JDXaction* dumaction=ldr.cast(dumaction); if(dumaction && (dumaction->get_parmode()==edit) ) { actionwidget=new buttonBox("Now",vport,ldrlabel.c_str()); set_widget(actionwidget); connect(actionwidget,SIGNAL(buttonClicked()), this,SLOT(changeJDXaction())); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXaction done" << STD_endl; /*---------------- JDXfloatArr ------------------------*/ farray* dumfarray=ldr.cast(dumfarray); if(dumfarray) { create_or_update_floatArrwidget(*dumfarray,true); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXfloatArr done" << STD_endl; /*---------------- JDXdoubleArr ------------------------*/ darray* dumdarray=ldr.cast(dumdarray); if(dumdarray) { ODINLOG(odinlog,normalDebug) << "dumdarray=" << (void*)dumdarray << "/" << STD_string(dumdarray->get_extent()) << STD_endl; farray farr(dumdarray->get_extent()); for(unsigned int i=0; idim()=" << dumcarray->dim() << STD_endl; if(dumcarray->dim()==1) { fvector ampvec=amplitude(*dumcarray); fvector phavec=phase(*dumcarray); rows=3; cols=2; ODINLOG(odinlog,normalDebug) << "rows/cols=" << rows << "/" << cols << STD_endl; ArrayScale x_axprops=val.get_gui_props().scale[xPlotScale]; ArrayScale y1_axprops=val.get_gui_props().scale[yPlotScaleLeft]; ArrayScale y2_axprops=val.get_gui_props().scale[yPlotScaleRight]; bool fixedsize=val.get_gui_props().fixedsize; complexArrwidget=new complexfloatBox1D(ampvec.c_array(),phavec.c_array(),dumcarray->length(),vport,ldrlabel.c_str(),fixedsize, x_axprops.get_label_with_unit().c_str(), y1_axprops.get_label_with_unit().c_str(), y2_axprops.get_label_with_unit().c_str(), x_axprops.minval,x_axprops.maxval,val.get_gui_props().fixedsize); set_widget(complexArrwidget, GuiGridLayout::Default, true); connect(this,SIGNAL(newcomplexArr( const float*, const float*, int, float, float)), complexArrwidget,SLOT(refresh( const float*, const float*, int, float, float))); } } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXcomplexArr done" << STD_endl; /*---------------- JDXfunction ------------------------*/ JDXfilter("dummy"); // created dummy to force initialization of registered_functions (in USING_WIN32/DLL) ODINLOG(odinlog,normalDebug) << "Testing for function" << STD_endl; JDXfunction* dumfunc=ldr.cast(dumfunc); if(dumfunc) { ODINLOG(odinlog,normalDebug) << "LDR is function" << STD_endl; cols=2; funcwidget=new enumBox(dumfunc->get_alternatives(),vport,ldrlabel.c_str(),true,true); ODINLOG(odinlog,normalDebug) << "funcwidget done" << STD_endl; funcwidget->setValue(dumfunc->get_function_index()); ODINLOG(odinlog,normalDebug) << "setValue done" << STD_endl; set_widget(funcwidget); ODINLOG(odinlog,normalDebug) << "set_widget done" << STD_endl; connect(funcwidget,SIGNAL(newVal( int )), this,SLOT(changeJDXfunction( int ))); connect(funcwidget,SIGNAL(edit()), this,SLOT(editJDXfunction())); connect(funcwidget,SIGNAL(info()), this,SLOT(infoJDXfunction())); connect(this,SIGNAL(newfuncval( int )),funcwidget,SLOT(setValue( int ))); ODINLOG(odinlog,normalDebug) << "connect done" << STD_endl; } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXfunction done" << STD_endl; /*---------------- JDXstring ------------------------*/ STD_string* dumstring=ldr.cast(dumstring); if(dumstring) { cols=2; stringwidget=new stringBox(dumstring->c_str(),vport,ldrlabel.c_str()); set_widget(stringwidget); connect(stringwidget,SIGNAL(stringBoxTextEntered( const char* )), this,SLOT(changeJDXstring( const char* ))); connect(this,SIGNAL(newstringval( const char* )),stringwidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXstring done" << STD_endl; /*---------------- JDXfileName ------------------------*/ JDXfileName* dumfileName=ldr.cast(dumfileName); if(dumfileName) { cols=2; filenamewidget=new stringBox(dumfileName->c_str(),vport,ldrlabel.c_str(),"Browse"); set_widget(filenamewidget); connect(filenamewidget,SIGNAL(stringBoxTextEntered( const char* )), this,SLOT(changeJDXfileName( const char* ))); connect(filenamewidget,SIGNAL(stringBoxButtonPressed()), this,SLOT(browseJDXfileName())); connect(this,SIGNAL(newfilenameval( const char* )),filenamewidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXfileName done" << STD_endl; /*---------------- JDXformula ------------------------*/ JDXformula* dumformula=ldr.cast(dumformula); if(dumformula) { cols=2; formulawidget=new stringBox(dumformula->c_str(),vport,ldrlabel.c_str(),"Syntax"); set_widget(formulawidget); connect(formulawidget,SIGNAL(stringBoxTextEntered( const char* )), this,SLOT(changeJDXformula( const char* ))); connect(formulawidget,SIGNAL(stringBoxButtonPressed()), this,SLOT(infoJDXformula())); connect(this,SIGNAL(newformulaval( const char* )),formulawidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXformula done" << STD_endl; /*---------------- JDXtriple ------------------------*/ JDXtriple* dumtriple=ldr.cast(dumtriple); if(dumtriple) { cols=2; triplewidget=new floatLineBox3D((*dumtriple)[0],(*dumtriple)[1],(*dumtriple)[2],_FLOAT_DIGITS_,vport,ldrlabel.c_str()); set_widget(triplewidget); connect(triplewidget,SIGNAL(floatLineBox3DValueChanged(float,float,float)), this,SLOT(changeJDXtriple(float,float,float))); connect(this,SIGNAL(newtripleval(float,float,float)),triplewidget,SLOT(setfloatLineBox3DValue(float,float,float))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "JDXtriple done" << STD_endl; /*---------------- JDX types swith END ------------------------*/ if(!cast_success) ODINLOG(odinlog,normalDebug) << "Unable to proces parameter >" << ldrlabel << "<" << STD_endl; return; } void JDXwidget::write_pixmap(const char* fname, const char* format, bool dump_all) const { if(floatArrwidget2) floatArrwidget2->write_pixmap(fname, format, dump_all); } void JDXwidget::write_map_legend(const char* fname, const char* format) const { if(floatArrwidget2) floatArrwidget2->write_map_legend(fname, format); } JDXwidget::~JDXwidget(){ // do not acces 'val' here because it might be deleted already if(blockwidget) delete blockwidget; if(intslider) delete intslider; if(intedit) delete intedit; if(floatslider) delete floatslider; if(floatedit) delete floatedit; if(enumwidget) delete enumwidget; if(boolwidget) delete boolwidget; if(floatArrempty) delete floatArrempty; if(floatArrwidget1) delete floatArrwidget1; if(floatArredit) delete floatArredit; if(floatArrwidget2) delete floatArrwidget2; // if(doubleArrwidget1) delete doubleArrwidget1; if(complexArrwidget) delete complexArrwidget; if(funcwidget) delete funcwidget; if(stringwidget) delete stringwidget; if(filenamewidget) delete filenamewidget; if(formulawidget) delete formulawidget; if(triplewidget) delete triplewidget; if(grid) delete grid; } STD_string JDXwidget::get_label() const {return val.get_label();} void JDXwidget::set_widget(QWidget *widget, GuiGridLayout::Alignment alignment, bool override_enabled) { Log odinlog(&val,"set_widget"); widget_cache=widget; parameterMode parmode=val.get_parmode(); ODINLOG(odinlog,normalDebug) << "parmode(" << ldrlabel << ")=" << parmode << STD_endl; if(parmode==hidden) return; bool enabled=true; if(parmode>=noedit) enabled=false; if(override_enabled) enabled=true; ODINLOG(odinlog,normalDebug) << "enabled=" << enabled << STD_endl; widget_cache->setEnabled(enabled); ODINLOG(odinlog,normalDebug) << "parameterMode done" << STD_endl; bool show_tooltip=label_cut; STD_string tooltip=ldrlabel_uncut; STD_string descr=val.get_description(); if(descr!="") { tooltip+=": "+descr; tooltip=justificate(tooltip); show_tooltip=true; } if(show_tooltip) add_tooltip(widget_cache,tooltip.c_str()); grid->add_widget( widget, 0, 0, alignment); widget->show(); } unsigned int JDXwidget::get_sizedfarray_size_and_factor(unsigned int& nx, unsigned int& ny, unsigned int& nz) const { Log odinlog(&val,"get_sizedfarray_size_and_factor"); PixmapProps pixprops=val.get_gui_props().pixmap; int dim=sizedfarray.dim(); nx=sizedfarray.size(dim-1); ny=sizedfarray.size(dim-2); nz=1; if(dim==3) nz=sizedfarray.size(dim-3); unsigned int factor=1; ODINLOG(odinlog,normalDebug) << "ny/nx=" << ny << "/" << nx << STD_endl; ODINLOG(odinlog,normalDebug) << "minsize/maxsize=" << pixprops.minsize << "/" << pixprops.maxsize << STD_endl; if (nx >= ny) factor=(unsigned int)secureDivision(pixprops.minsize,ny); else factor=(unsigned int)secureDivision(pixprops.minsize,nx); if(!factor) factor=1; if( (factor*nx) > pixprops.maxsize) factor=(unsigned int)secureDivision(pixprops.maxsize,nx); if( (factor*ny) > pixprops.maxsize) factor=(unsigned int)secureDivision(pixprops.maxsize,ny); if(!factor) factor=1; return factor; } void JDXwidget::create_or_update_floatArrwidget(const farray& arr, bool initial) { Log odinlog(&val,"create_or_update_floatArrwidget"); rows=2; cols=2; ArrayScale x_axprops=val.get_gui_props().scale[xPlotScale]; ArrayScale y_axprops=val.get_gui_props().scale[yPlotScaleLeft]; sizedfarray=arr; sizedfarray.autosize(); unsigned int newdim=sizedfarray.dim(); unsigned int newsize=sizedfarray.total(); if(newdim==3) newdim=2; // treat 2D and 3D equally if(newsize==0) newdim=0; // treat zero size as zero dim ODINLOG(odinlog,normalDebug) << "newdim/newsize=" << newdim << "/" << newsize << STD_endl; if(!initial) { unsigned int olddim=oldfarraysize.dim(); unsigned int oldsize=oldfarraysize.total(); if(olddim==3) olddim=2; // treat 2D and 3D equally bool delete_old=false; if(newdim!=olddim) delete_old=true; if(newdim==1 && (newsize!=oldsize) && (newsize==1 || oldsize==1)) delete_old=true; if(newdim>1 && sizedfarray.get_extent()!=oldfarraysize) delete_old=true; ODINLOG(odinlog,normalDebug) << "newdim/olddim/newsize/oldsize/delete_old=" << newdim << "/" << olddim << "/" << newsize << "/" << oldsize << "/" << delete_old << STD_endl; if(delete_old) { if(floatArrempty) {floatArrempty->hide(); delete floatArrempty; floatArrempty=0;} if(floatArrwidget1) {floatArrwidget1->hide(); delete floatArrwidget1; floatArrwidget1=0;} if(floatArredit) {floatArredit->hide(); delete floatArredit; floatArredit=0;} if(floatArrwidget2) {floatArrwidget2->hide(); delete floatArrwidget2; floatArrwidget2=0;} } } if(newdim==0) { if(!floatArrempty) { floatArrempty=new QLabel(this); floatArrempty->setText((ldrlabel+"(Empty)").c_str()); set_widget(floatArrempty); } } if(newdim==1) { if(newsize==1) { rows=1; cols=1; if(floatArredit) { emit newfloatval( sizedfarray[0] ); } else { floatArredit=new floatLineBox(sizedfarray[0],_FLOAT_DIGITS_,vport,ldrlabel.c_str()); set_widget(floatArredit); connect(floatArredit,SIGNAL(floatLineBoxValueChanged( float )),this,SLOT(changeJDXfloat( float ))); connect(this,SIGNAL(newfloatval( float )),floatArredit,SLOT(setfloatLineBoxValue( float ))); } } if(newsize>1) { rows=3; ODINLOG(odinlog,normalDebug) << "x_label/unit=" << x_axprops.label << "/" << x_axprops.unit << STD_endl; ODINLOG(odinlog,normalDebug) << "y_label/unit=" << y_axprops.label << "/" << y_axprops.unit << STD_endl; if(floatArrwidget1) { emit newfloatArr1( sizedfarray.c_array(), sizedfarray.length(), x_axprops.minval,x_axprops.maxval ); } else { floatArrwidget1=new floatBox1D(sizedfarray.c_array(),sizedfarray.length(),vport,ldrlabel.c_str(),val.get_gui_props().fixedsize, x_axprops.get_label_with_unit().c_str(),y_axprops.get_label_with_unit().c_str(), x_axprops.minval,x_axprops.maxval,val.get_gui_props().fixedsize); set_widget(floatArrwidget1, GuiGridLayout::Default, true); connect(this,SIGNAL(newfloatArr1( const float*, int, float, float)), floatArrwidget1,SLOT(refresh( const float*, int, float, float))); } } } if(newdim==2) { ArrayScale dispscale=val.get_gui_props().scale[displayScale]; ODINLOG(odinlog,normalDebug) << "dispscale.minval/maxval=" << dispscale.minval << "/" << dispscale.maxval << STD_endl; if(val.get_gui_props().pixmap.autoscale) { dispscale.minval=sizedfarray.minvalue(); dispscale.maxval=sizedfarray.maxvalue(); ODINLOG(odinlog,normalDebug) << "Autoscaling with min/max=" << dispscale.minval << "/" << dispscale.maxval << STD_endl; sizedfarray.normalize(); } if(floatArrwidget2) { ODINLOG(odinlog,normalDebug) << "Emitting new c_array" << STD_endl; emit newfloatArr2( sizedfarray.c_array(),dispscale.minval,dispscale.maxval); mapfarray=val.get_gui_props().pixmap.overlay_map; // mapfarray.normalize(); if(mapfarray.total()) { ODINLOG(odinlog,normalDebug) << "New overlay_map" << STD_endl; float mapmin, mapmax; val.get_gui_props().pixmap.get_overlay_range(mapmin, mapmax); emit newfloatArrMap(mapfarray.c_array(), mapmin, mapmax, val.get_gui_props().pixmap.overlay_rectsize); } } else { unsigned int nx,ny,nz; unsigned int factor=get_sizedfarray_size_and_factor(nx,ny,nz); bool colormap=val.get_gui_props().pixmap.color; overlay_map=val.get_gui_props().pixmap.overlay_map; // create local copy for c_array() bool olm_firescale=val.get_gui_props().pixmap.overlay_firescale; float olm_rectsize=val.get_gui_props().pixmap.overlay_rectsize; const float* olm=0; int olm_x=1; int olm_y=1; int olm_z=1; float olm_upp=0.0; float olm_low=0.0; if(overlay_map.length()) { val.get_gui_props().pixmap.get_overlay_range(olm_low, olm_upp); // olm_upp=overlay_map.maxvalue(); // olm_low=overlay_map.minvalue(); // overlay_map.normalize(); olm=overlay_map.c_array(); int olm_dim=overlay_map.dim(); if(olm_dim>2) olm_z=overlay_map.size(olm_dim-3); if(olm_dim>1) olm_y=overlay_map.size(olm_dim-2); if(olm_dim>0) olm_x=overlay_map.size(olm_dim-1); ODINLOG(odinlog,normalDebug) << "olm/olm_z/olm_y/olm_x=" << olm << "/" << olm_z << "/" << olm_y << "/" << olm_x << STD_endl; } floatArrwidget2=new floatBox3D(sizedfarray.c_array(),dispscale.minval,dispscale.maxval,nx,ny,nz,factor,vport,ldrlabel.c_str(), olm,olm_low,olm_upp,olm_x,olm_y,olm_z,olm_firescale,olm_rectsize,colormap); set_widget(floatArrwidget2, GuiGridLayout::Default, true); connect(floatArrwidget2,SIGNAL(clicked(int,int,int)),this,SLOT(emitClicked(int, int, int))); connect(floatArrwidget2,SIGNAL(newProfile(const float*, int, bool, int)),this,SLOT(emitNewProfile(const float*, int, bool, int))); connect(floatArrwidget2,SIGNAL(newMask(const float*, int)),this,SLOT(emitNewMask(const float*, int))); connect(this,SIGNAL(newfloatArr2( const float*, float, float)),floatArrwidget2,SLOT(refresh( const float*, float, float))); connect(this,SIGNAL(newfloatArrMap( const float*, float, float, float)),floatArrwidget2,SLOT(refreshMap( const float*, float, float, float ))); } } oldfarraysize=sizedfarray.get_extent(); } void JDXwidget::emitValueChanged() { emit valueChanged(); } void JDXwidget::emitDone() { emit doneButtonPressed(); } void JDXwidget::updateWidget() { Log odinlog(&val,"updateWidget"); emit updateSubWidget(); if(blockwidget) blockwidget->updateWidget(); // for all 1D/2D plots, get again, might have been changed ArrayScale x_axprops=val.get_gui_props().scale[xPlotScale]; PixmapProps pixprops=val.get_gui_props().pixmap; if(intslider || intedit) { ODINLOG(odinlog,normalDebug) << "newintval(" << val.get_label() << ")=" << val.printvalstring() << STD_endl; emit newintval( atoi(val.printvalstring().c_str()) ); } if(floatslider || floatedit) { float* dumfloat=val.cast(dumfloat); double* dumdouble=val.cast(dumdouble); float floatval=0.0; if(dumfloat) floatval=(*dumfloat); if(dumdouble) floatval=(*dumdouble); emit newfloatval( floatval ); } if(enumwidget) { JDXenum* dumenum=val.cast(dumenum); if(dumenum) emit newenumval( dumenum->get_item_index() ); } if(boolwidget) { bool* dumbool=val.cast(dumbool); if(dumbool) emit newboolval(*dumbool); } if(complexArrwidget) { carray* dumcarray=val.cast(dumcarray); if(dumcarray) { if(dumcarray->dim()==1) { fvector ampvec=amplitude(*dumcarray); fvector phavec=phase(*dumcarray); emit newcomplexArr( ampvec.c_array(), phavec.c_array(), dumcarray->length(), x_axprops.minval,x_axprops.maxval); } } } if(floatArrempty || floatArrwidget1 || floatArrwidget2 || floatArredit) { farray* dumfarray=val.cast(dumfarray); if(dumfarray) { create_or_update_floatArrwidget(*dumfarray,false); } darray* dumdarray=val.cast(dumdarray); if(dumdarray) { ODINLOG(odinlog,normalDebug) << "dumdarray=" << (void*)dumdarray << "/" << STD_string(dumdarray->get_extent()) << STD_endl; farray farr(dumdarray->get_extent()); for(unsigned int i=0; iget_function_index() ); ODINLOG(odinlog,normalDebug) << "get_function_index()=" << dumfunc->get_function_index() << STD_endl; for(STD_list::iterator it=subdialogs.begin(); it!=subdialogs.end(); ++it) { (*it)->updateWidget(); } } if(stringwidget) { STD_string* dumstring=val.cast(dumstring); if(dumstring) { const char* str=dumstring->c_str(); ODINLOG(odinlog,normalDebug) << "str=" << str << STD_endl; emit newstringval(str); } } if(filenamewidget) { JDXfileName* dumfileName=val.cast(dumfileName); if(dumfileName) emit newfilenameval( dumfileName->c_str() ); } if(formulawidget) { JDXformula* dumformula=val.cast(dumformula); if(dumformula) emit newformulaval( dumformula->c_str() ); } if(triplewidget) { JDXtriple* dumtriple=val.cast(dumtriple); if(dumtriple) emit newtripleval( (*dumtriple)[0],(*dumtriple)[1],(*dumtriple)[2] ); } } void JDXwidget::deleteDialogs() { emit deleteSubDialogs(); for(STD_list::iterator it=subdialogs.begin(); it!=subdialogs.end(); ++it) { (*it)->hide(); // delete (*it); } subdialogs.clear(); } void JDXwidget::changeJDXint( int newval ) { int* dumint=val.cast(dumint); if(dumint) (*dumint)=newval; long* dumlong=val.cast(dumlong); if(dumlong) (*dumlong)=newval; emit valueChanged(); } void JDXwidget::changeJDXfloat( float newval ) { Log odinlog(&val,"changeJDXfloat"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; float* dumfloat=val.cast(dumfloat); if(dumfloat) (*dumfloat)=newval; double* dumdouble=val.cast(dumdouble); if(dumdouble) (*dumdouble)=newval; farray* dumfarray=val.cast(dumfarray); if(dumfarray && dumfarray->length()) dumfarray[0]=newval; darray* dumdarray=val.cast(dumdarray); if(dumdarray && dumdarray->length()) dumdarray[0]=newval; // STD_string dummy=JDXdouble(newval).printvalstring(); // val.parsevalstring(dummy); ODINLOG(odinlog,normalDebug) << "val=" << val.printvalstring() << STD_endl; emit valueChanged(); } void JDXwidget::changeJDXenum( int newval ) { JDXenum* dumenum=val.cast(dumenum); if(dumenum) dumenum->set_item_index(newval); emit valueChanged(); } void JDXwidget::changeJDXbool( bool newval ) { bool* dumbool=val.cast(dumbool); if(dumbool) (*dumbool)=newval; emit valueChanged(); } void JDXwidget::changeJDXaction() { JDXaction* dumaction=val.cast(dumaction); if(dumaction) dumaction->trigger_action(); emit valueChanged(); } void JDXwidget::changeJDXfunction( int newval ) { Log odinlog(&val,"changeJDXfunction"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; deleteDialogs(); JDXfunction* dumfunc=val.cast(dumfunc); if(dumfunc) dumfunc->set_function(newval); emit valueChanged(); } void JDXwidget::changeJDXstring( const char* newval ) { Log odinlog(&val,"changeJDXstring"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; STD_string* dumstring=val.cast(dumstring); if(dumstring) { STD_string newval_str=STD_string(newval); // direct assignment gives bogus results on MacOS 10.4 with GCC4 and std::string (*dumstring)=newval_str; ODINLOG(odinlog,normalDebug) << "newval_str/dumstring=" << newval_str << "/" << (*dumstring) << STD_endl; } emit valueChanged(); } void JDXwidget::changeJDXfileName( const char* newval ) { JDXfileName* dumfilename=val.cast(dumfilename); if(dumfilename) { STD_string newvalstr(newval); (*dumfilename)=newvalstr; } emit valueChanged(); } void JDXwidget::changeJDXformula( const char* newval ) { JDXformula* dumformula=val.cast(dumformula); if(dumformula) (*dumformula)=newval; emit valueChanged(); } void JDXwidget::changeJDXtriple( float xval,float yval,float zval ) { JDXtriple* dumtriple=val.cast(dumtriple); if(dumtriple) { (*dumtriple)[0]=xval; (*dumtriple)[1]=yval; (*dumtriple)[2]=zval; } emit valueChanged(); } void JDXwidget::browseJDXfileName() { Log odinlog(&val,"browseJDXfileName"); JDXfileName* dumfilename=val.cast(dumfilename); if(dumfilename) { STD_string suffix=dumfilename->get_suffix(); ODINLOG(odinlog,normalDebug) << "suffix=" << suffix << STD_endl; if(suffix!="") suffix=STD_string(val.get_label())+" (*."+suffix+")"; STD_string startdir=dumfilename->get_defaultdir(); // local copy for c_str() ODINLOG(odinlog,normalDebug) << "startdir/suffix=" << startdir << "/" << suffix << STD_endl; STD_string fname; if(dumfilename->is_dir()) fname=get_directory("Please select a directory", startdir.c_str(), vport); else fname=get_open_filename("Please select a file", startdir.c_str(), suffix.c_str(), vport); if (fname!="") { (*dumfilename)=fname; filenamewidget->setstringBoxText(fname.c_str()); } } emit valueChanged(); } void JDXwidget::infoJDXformula() { JDXformula* dumformula=val.cast(dumformula); if(dumformula) { message_question((justificate(dumformula->get_syntax(),0,false,_INFOBOX_LINEWIDTH_)).c_str(), val.get_label().c_str(), vport); } emit valueChanged(); } void JDXwidget::editJDXfunction() { JDXfunction* dumfunc=val.cast(dumfunc); if(dumfunc) { JDXwidgetDialog* dlg=new JDXwidgetDialog(*(dumfunc->get_funcpars_block()),1,vport); subdialogs.push_back(dlg); connect(dlg,SIGNAL(valueChanged()), this,SLOT(emitValueChanged())); } emit valueChanged(); } void JDXwidget::infoJDXfunction() { JDXfunction* dumfunc=val.cast(dumfunc); if(dumfunc) { message_question((justificate(dumfunc->get_funcdescription(),0,false,_INFOBOX_LINEWIDTH_)).c_str(), (dumfunc->get_label()+STD_string(" info")).c_str(), vport); } } odin-1.8.5/odinqt/stringbox.h0000644000175000017500000000322511322062347013067 00000000000000/*************************************************************************** intedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STRINGBOX_H #define STRINGBOX_H #include #include "odinqt.h" /** * This class contains a QlineEdit to display a string * in a nice box with a label. */ class stringBox : public QGroupBox { Q_OBJECT public: stringBox(const char* text, QWidget *parent, const char *name, const char *buttontext=0); ~stringBox(); public slots: void setstringBoxText( const char* text ); private slots: void reportTextChanged(); void reportButtonClicked(); signals: void stringBoxTextEntered( const char* text ); void stringBoxButtonPressed(); private: GuiGridLayout* grid; GuiLineEdit* le; GuiButton* pb; }; #endif odin-1.8.5/odinqt/Makefile.am0000644000175000017500000000231011322062347012725 00000000000000 libodinqt_la_LDFLAGS = -no-undefined -release $(VERSION) $(GUILIBS) libodinqt_la_LIBADD = ../odinpara/libodinpara.la if GUI_ENABLED INCLUDES = $(all_includes) # Auto-generate any needed moc files %_moc.cpp: %.h $(MOC) -o $@ $< lib_LTLIBRARIES = libodinqt.la library_includedir=$(includedir)/odinqt library_include_HEADERS = \ odinqt.h odinqt_callback.h \ boolbutton.h \ complex1d.h \ enumbox.h \ float1d.h \ float2d.h \ float3d.h \ floatedit.h \ intedit.h \ plot.h \ stringbox.h \ jdxwidget.h \ jdxblockwidget.h libodinqt_la_SOURCES = \ odinqt.h odinqt.cpp odinqt_callback.h odinqt_callback_moc.cpp \ boolbutton.h boolbutton.cpp boolbutton_moc.cpp \ complex1d.h complex1d.cpp complex1d_moc.cpp \ enumbox.h enumbox.cpp enumbox_moc.cpp \ float1d.h float1d.cpp float1d_moc.cpp \ float2d.h float2d.cpp float2d_moc.cpp \ float3d.h float3d.cpp float3d_moc.cpp \ floatedit.h floatedit.cpp floatedit_moc.cpp \ intedit.h intedit.cpp intedit_moc.cpp \ plot.h plot.cpp plot_moc.cpp \ stringbox.h stringbox.cpp stringbox_moc.cpp \ jdxwidget.h jdxwidget.cpp jdxwidget_moc.cpp \ jdxblockwidget.h jdxblockwidget.cpp jdxblockwidget_moc.cpp dist-hook: -rm -rf $(distdir)/*_moc.cpp endif clean-local: -rm -f *_moc.cpp odin-1.8.5/odinqt/Makefile.in0000644000175000017500000005612311734622602012754 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = odinqt DIST_COMMON = $(am__library_include_HEADERS_DIST) \ $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(library_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libodinqt_la_DEPENDENCIES = ../odinpara/libodinpara.la am__libodinqt_la_SOURCES_DIST = odinqt.h odinqt.cpp odinqt_callback.h \ odinqt_callback_moc.cpp boolbutton.h boolbutton.cpp \ boolbutton_moc.cpp complex1d.h complex1d.cpp complex1d_moc.cpp \ enumbox.h enumbox.cpp enumbox_moc.cpp float1d.h float1d.cpp \ float1d_moc.cpp float2d.h float2d.cpp float2d_moc.cpp \ float3d.h float3d.cpp float3d_moc.cpp floatedit.h \ floatedit.cpp floatedit_moc.cpp intedit.h intedit.cpp \ intedit_moc.cpp plot.h plot.cpp plot_moc.cpp stringbox.h \ stringbox.cpp stringbox_moc.cpp jdxwidget.h jdxwidget.cpp \ jdxwidget_moc.cpp jdxblockwidget.h jdxblockwidget.cpp \ jdxblockwidget_moc.cpp @GUI_ENABLED_TRUE@am_libodinqt_la_OBJECTS = odinqt.lo \ @GUI_ENABLED_TRUE@ odinqt_callback_moc.lo boolbutton.lo \ @GUI_ENABLED_TRUE@ boolbutton_moc.lo complex1d.lo \ @GUI_ENABLED_TRUE@ complex1d_moc.lo enumbox.lo enumbox_moc.lo \ @GUI_ENABLED_TRUE@ float1d.lo float1d_moc.lo float2d.lo \ @GUI_ENABLED_TRUE@ float2d_moc.lo float3d.lo float3d_moc.lo \ @GUI_ENABLED_TRUE@ floatedit.lo floatedit_moc.lo intedit.lo \ @GUI_ENABLED_TRUE@ intedit_moc.lo plot.lo plot_moc.lo \ @GUI_ENABLED_TRUE@ stringbox.lo stringbox_moc.lo jdxwidget.lo \ @GUI_ENABLED_TRUE@ jdxwidget_moc.lo jdxblockwidget.lo \ @GUI_ENABLED_TRUE@ jdxblockwidget_moc.lo libodinqt_la_OBJECTS = $(am_libodinqt_la_OBJECTS) libodinqt_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libodinqt_la_LDFLAGS) $(LDFLAGS) -o $@ @GUI_ENABLED_TRUE@am_libodinqt_la_rpath = -rpath $(libdir) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libodinqt_la_SOURCES) DIST_SOURCES = $(am__libodinqt_la_SOURCES_DIST) am__library_include_HEADERS_DIST = odinqt.h odinqt_callback.h \ boolbutton.h complex1d.h enumbox.h float1d.h float2d.h \ float3d.h floatedit.h intedit.h plot.h stringbox.h jdxwidget.h \ jdxblockwidget.h HEADERS = $(library_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ libodinqt_la_LDFLAGS = -no-undefined -release $(VERSION) $(GUILIBS) libodinqt_la_LIBADD = ../odinpara/libodinpara.la @GUI_ENABLED_TRUE@INCLUDES = $(all_includes) @GUI_ENABLED_TRUE@lib_LTLIBRARIES = libodinqt.la @GUI_ENABLED_TRUE@library_includedir = $(includedir)/odinqt @GUI_ENABLED_TRUE@library_include_HEADERS = \ @GUI_ENABLED_TRUE@odinqt.h odinqt_callback.h \ @GUI_ENABLED_TRUE@boolbutton.h \ @GUI_ENABLED_TRUE@complex1d.h \ @GUI_ENABLED_TRUE@enumbox.h \ @GUI_ENABLED_TRUE@float1d.h \ @GUI_ENABLED_TRUE@float2d.h \ @GUI_ENABLED_TRUE@float3d.h \ @GUI_ENABLED_TRUE@floatedit.h \ @GUI_ENABLED_TRUE@intedit.h \ @GUI_ENABLED_TRUE@plot.h \ @GUI_ENABLED_TRUE@stringbox.h \ @GUI_ENABLED_TRUE@jdxwidget.h \ @GUI_ENABLED_TRUE@jdxblockwidget.h @GUI_ENABLED_TRUE@libodinqt_la_SOURCES = \ @GUI_ENABLED_TRUE@odinqt.h odinqt.cpp odinqt_callback.h odinqt_callback_moc.cpp \ @GUI_ENABLED_TRUE@boolbutton.h boolbutton.cpp boolbutton_moc.cpp \ @GUI_ENABLED_TRUE@complex1d.h complex1d.cpp complex1d_moc.cpp \ @GUI_ENABLED_TRUE@enumbox.h enumbox.cpp enumbox_moc.cpp \ @GUI_ENABLED_TRUE@float1d.h float1d.cpp float1d_moc.cpp \ @GUI_ENABLED_TRUE@float2d.h float2d.cpp float2d_moc.cpp \ @GUI_ENABLED_TRUE@float3d.h float3d.cpp float3d_moc.cpp \ @GUI_ENABLED_TRUE@floatedit.h floatedit.cpp floatedit_moc.cpp \ @GUI_ENABLED_TRUE@intedit.h intedit.cpp intedit_moc.cpp \ @GUI_ENABLED_TRUE@plot.h plot.cpp plot_moc.cpp \ @GUI_ENABLED_TRUE@stringbox.h stringbox.cpp stringbox_moc.cpp \ @GUI_ENABLED_TRUE@jdxwidget.h jdxwidget.cpp jdxwidget_moc.cpp \ @GUI_ENABLED_TRUE@jdxblockwidget.h jdxblockwidget.cpp jdxblockwidget_moc.cpp all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu odinqt/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu odinqt/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libodinqt.la: $(libodinqt_la_OBJECTS) $(libodinqt_la_DEPENDENCIES) $(libodinqt_la_LINK) $(am_libodinqt_la_rpath) $(libodinqt_la_OBJECTS) $(libodinqt_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boolbutton.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/boolbutton_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/complex1d.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/complex1d_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enumbox.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/enumbox_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float1d.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float1d_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float2d.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float2d_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float3d.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/float3d_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floatedit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/floatedit_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intedit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intedit_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxblockwidget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxblockwidget_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxwidget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxwidget_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinqt.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinqt_callback_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plot.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plot_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringbox.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stringbox_moc.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-library_includeHEADERS: $(library_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(library_includedir)" || $(MKDIR_P) "$(DESTDIR)$(library_includedir)" @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(library_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(library_includedir)" || exit $$?; \ done uninstall-library_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(library_includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(library_includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @GUI_ENABLED_FALSE@dist-hook: distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-library_includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool clean-local ctags dist-hook \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-libLTLIBRARIES \ install-library_includeHEADERS install-man install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS # Auto-generate any needed moc files @GUI_ENABLED_TRUE@%_moc.cpp: %.h @GUI_ENABLED_TRUE@ $(MOC) -o $@ $< @GUI_ENABLED_TRUE@dist-hook: @GUI_ENABLED_TRUE@ -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odinqt/complex1d.h0000644000175000017500000000743111322062347012747 00000000000000/*************************************************************************** complex1d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COMPLEX1D_H #define COMPLEX1D_H #include #include "odinqt.h" #define SYMBOL_MAX_NUMOF_POINTS 20 class GuiPlot; // forward declaration class DetachedComplexfloatBox1D; // forward declaration /** * QLabel containing a plotted complex array (2 curves) */ class complexfloatBox1D : public QGroupBox { Q_OBJECT public: complexfloatBox1D(const float *data1, const float *data2, int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel=0, const char *yAxisLabelLeft=0, const char *yAxisLabelRight=0, float min_x=0.0, float max_x=0.0, bool detachable=false); complexfloatBox1D(const double *data1,const double *data2,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel=0, const char *yAxisLabelLeft=0, const char *yAxisLabelRight=0, float min_x=0.0, float max_x=0.0, bool detachable=false); ~complexfloatBox1D(); public slots: void refresh(const float *data1,const float *data2,int n, float min_x, float max_x); void refresh(const float *data1,const float *data2,int n) {refresh(data1,data2,n,0.0,0.0);} void refresh(const double *data1,const double *data2,int n, float min_x, float max_x); void refresh(const double *data1,const double *data2,int n) {refresh(data1,data2,n,0.0,0.0);} private slots: void autoscale(); void detach(); void mousePressedInPlot(const QMouseEvent& qme); void mouseReleasedInPlot(const QMouseEvent& qme); private: void common_init(const char *name, bool fixed_size, bool data1, bool data2, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, bool detachable); void create_x_cache(float min_x, float max_x, int n); long curveid1; long curveid2; dvector data1_cache; dvector data2_cache; dvector x_cache; const double* data1_ptr; const double* data2_ptr; // Use strings to cache labels since original arrays may be outdated STD_string name_cache; STD_string xAxisLabel_cache; STD_string yAxisLabelLeft_cache; STD_string yAxisLabelRight_cache; float min_x_cache; float max_x_cache; int n_cache; bool detachable_cache; GuiGridLayout *grid; GuiPlot* plotter; int x_pressed,y_pressed; DetachedComplexfloatBox1D* detached; }; /////////////////////////////////////////////////////////////////// class DetachedComplexfloatBox1D : public GuiDialog { public: DetachedComplexfloatBox1D(const double *data1,const double *data2,int n,complexfloatBox1D *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabelLeft, const char *yAxisLabelRight, float min_x, float max_x); ~DetachedComplexfloatBox1D(); void refresh(const double *data1,const double *data2,int n, float min_x, float max_x); private: void create_grid(); GuiGridLayout *grid; complexfloatBox1D* cfb; }; #endif odin-1.8.5/odinqt/float1d.cpp0000644000175000017500000000361411322062347012737 00000000000000/*************************************************************************** float1d.cpp - description ------------------- begin : Tue Jul 11 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "float1d.h" floatBox1D::floatBox1D(const float *data,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabel, float min_x, float max_x, bool detachable) : complexfloatBox1D(data,0,n,parent,name, fixed_size, xAxisLabel, yAxisLabel, 0, min_x, max_x, detachable ) { } floatBox1D::floatBox1D(const double *data,int n,QWidget *parent, const char *name, bool fixed_size, const char *xAxisLabel, const char *yAxisLabel, float min_x, float max_x, bool detachable) : complexfloatBox1D(data,0,n,parent,name, fixed_size, xAxisLabel, yAxisLabel, 0, min_x, max_x, detachable ) { } void floatBox1D::refresh(const float* data,int n, float min_x, float max_x) { complexfloatBox1D::refresh(data,0,n, min_x, max_x ); } void floatBox1D::refresh(const double* data,int n, float min_x, float max_x) { complexfloatBox1D::refresh(data,0,n, min_x, max_x ); } odin-1.8.5/odinqt/float2d.cpp0000644000175000017500000003721111322062347012740 00000000000000#include // for mouse events #include #include #include "float2d.h" #include #include #define LOGMAP_FACTOR 2 #define LEGEND_DIGITS 3 #define MAX_LOGMAP_HUE 70.0 #define MAX_MAP_HUE 270.0 #define X_ENUM 0 #define Y_ENUM 1 #define CROSSHAIR_SIZE 4 #define MAP_RECT_SIZE 0.8 void floatArray2pixbuff(unsigned char* imagebuff, const float* farray, int nx, int ny, int coarseFactor, int scalespace) { Log odinlog("floatLabel2D","floatArray2pixbuff"); int nx_aligned=((nx*coarseFactor+scalespace+3)/4)*4; // 32-bit aligned lines for QImage ODINLOG(odinlog,normalDebug) << "nx_aligned/nx/ny/coarseFactor/scalespace=" << nx_aligned << "/" << nx << "/" << ny << "/" << coarseFactor << "/" << scalespace << STD_endl; int i,j; // Draw data for (j = 0; j < ny; j++) { int jrev=ny-1-j; for (i = 0; i < nx; i++) { float floatval = farray[j * nx + i]; if (floatval > 1.0) floatval = 1.0; if (floatval < 0.0) floatval = 0.0; unsigned char byteval = (unsigned char) (255.0 * floatval); for (int jj = 0; jj < coarseFactor; jj++) { for (int ii = 0; ii < coarseFactor; ii++) { imagebuff[(jrev * coarseFactor + jj) * nx_aligned + (i * coarseFactor + ii)] = byteval; } } } // Draw scale float floatval = float(j)/float(ny-1); unsigned char byteval = (unsigned char) (255.0 * floatval + 0.5); for (i = (nx*coarseFactor); i < nx_aligned; i++) { for (int jj = 0; jj < coarseFactor; jj++) { imagebuff[(jrev * coarseFactor + jj) * nx_aligned + i] = byteval; } } } } floatLabel2D::floatLabel2D(const float *data, float lowbound, float uppbound, unsigned int nx, unsigned int ny, unsigned int coarseFactor, QWidget *parent, const char *name, const float *overlay_map, float lowbound_map, float uppbound_map, unsigned int nx_map, unsigned int ny_map, bool map_firescale, float map_rectsize, bool colormap) : QLabel(parent ) { Log odinlog("floatLabel2D","floatLabel2D"); ODINLOG(odinlog,normalDebug) << "nx/ny/coarseFactor=" << nx << "/" << ny << "/" << coarseFactor << STD_endl; colormap_cache=colormap; pixmap=0; legend_pixmap=0; nx_cache=nx; ny_cache=ny; nx_map_cache=nx_map; ny_map_cache=ny_map; fire_map_cache=map_firescale; lowbound_map_cache=lowbound_map; uppbound_map_cache=uppbound_map; ODINLOG(odinlog,normalDebug) << "lowbound_map_cache/uppbound_map_cache=" << lowbound_map_cache << "/" << uppbound_map_cache << STD_endl; lowbound_cache=lowbound; uppbound_cache=uppbound; scalespace_cache=0; if(uppbound>lowbound) scalespace_cache=scale_width(lowbound,uppbound); roi_mask=new float[nx_cache*ny_cache]; profile_x=new float[nx_cache]; for(i=0;isetFixedSize( (nx*coarseFactor+scalespace_cache)+this->frameWidth()*2,ny*coarseFactor+this->frameWidth()*2 ); connect(this,SIGNAL(clicked(int,int)),this,SLOT(drawcross(int,int))); refresh(data, lowbound, uppbound); refreshMap(overlay_map, lowbound_map, uppbound_map_cache, map_rectsize); } void floatLabel2D::init_pixmap(bool clear) { Log odinlog("floatLabel2D","init_pixmap"); if(clear || !pixmap) { if(pixmap) delete pixmap; floatArray2pixbuff(imagebuff, data_cache, nx_cache,ny_cache,coarseFactor_cache,scalespace_cache); GuiImage img( imagebuff, nx_cache*coarseFactor_cache+scalespace_cache, ny_cache*coarseFactor_cache, colormap_cache); pixmap = img.create_pixmap(); GuiPainter gp(pixmap); draw_scale_text(gp, 3*_FONT_SIZE_/2, uppbound_cache); draw_scale_text(gp, ny_cache*coarseFactor_cache-_FONT_SIZE_/2, lowbound_cache); gp.end(); } } void floatLabel2D::set_pixmap() { Log odinlog("floatLabel2D","set_pixmap"); // bitBlt( this, 2, 2, pixmap ); ODINLOG(odinlog,normalDebug) << "pixmap=" << (void*)pixmap << STD_endl; this->setPixmap(*pixmap); } int floatLabel2D::scale_width(float lowbound, float uppbound) { return 0.8*STD_max(ftos(lowbound,LEGEND_DIGITS).length(),ftos(uppbound,LEGEND_DIGITS).length())*_FONT_SIZE_; } void floatLabel2D::draw_text(GuiPainter& gp, int xpos, int ypos, const char* txt) const { gp.drawText(xpos+1,ypos+1,txt,"Black"); gp.drawText(xpos, ypos, txt,"White"); } void floatLabel2D::draw_scale_text(GuiPainter& gp, int ypos, float val) const { draw_text(gp, nx_cache*coarseFactor_cache, ypos, ftos(val,LEGEND_DIGITS).c_str()); } void floatLabel2D::refresh(const float* data, float lowbound, float uppbound) { data_cache=data; lowbound_cache=lowbound; uppbound_cache=uppbound; init_pixmap(); set_pixmap(); } void floatLabel2D::write_pixmap(const char* fname, const char* format) const { if(pixmap && fname) pixmap->save (fname,toupperstr(format).c_str()); } int floatLabel2D::get_map_hue(float relval) const { float hue_factor=1.0; if(fire_map_cache) hue_factor=0.25; else relval=1.0-relval; relval=STD_max(float(0.0),relval); relval=STD_min(float(1.0),relval); if (fire_map_cache) { // fmri coloring // adjust balance between red, orange and yellow ... more red, less orange if (relval < 0.25) // more red relval = 0.0; else if ((relval > 0.6) && (relval < 0.7)) // small transition orange to yellow relval = (0.7 - 7.0 / 15.0) / 0.1 * (relval - 0.6) + 7.0 / 15.0; else if (relval > 0.7) relval = relval; else relval = (relval - 0.25) * (4.0 / 3.0); } return MAX_MAP_HUE*hue_factor*relval; } int floatLabel2D::get_map_value(float relval) const { if ((relval < 0.4) && (fire_map_cache)) // darken lower values -> dark red return 255-255*(0.4 - relval); else return 255; } int floatLabel2D::get_map_saturation(float relval) const { if ((relval > 0.8) && (fire_map_cache)) // remove saturation for highest values -> white color return 255-255*(relval-0.8)*5; else return 255; } QLabel* floatLabel2D::get_map_legend(QWidget *parent) const { QLabel* result=new QLabel(parent); int width=6*_FONT_SIZE_; // if(!fire_map_cache) width=scale_width(lowbound_map_cache,uppbound_map_cache); int height=ny_cache*coarseFactor_cache; legend_pixmap = new QPixmap(width,height); GuiPainter *legend_painter = new GuiPainter(legend_pixmap); QColor qc; QColor qc_txt("Black"); for(int iy=0; iyfillRect (0,iy,width,1,qc); draw_text(*legend_painter, 0, 1.5*_FONT_SIZE_, ftos(uppbound_map_cache,LEGEND_DIGITS).c_str()); draw_text(*legend_painter, 0, ny_cache*coarseFactor_cache-_FONT_SIZE_/2, ftos(lowbound_map_cache,LEGEND_DIGITS).c_str()); } result->setPixmap(*legend_pixmap); return result; } void floatLabel2D::write_map_legend(const char* fname, const char* format) const { if(legend_pixmap && fname) legend_pixmap->save(fname, toupperstr(format).c_str()); } void floatLabel2D::refreshMap(const float* map, float map_lowbound, float map_uppbound, float map_rectsize) { Log odinlog("floatLabel2D","refreshMap"); ODINLOG(odinlog,normalDebug) << "map=" << (void*)map << STD_endl; ODINLOG(odinlog,normalDebug) << "map_lowbound/map_uppbound=" << map_lowbound << "/" << map_uppbound << STD_endl; if(!map) return; init_pixmap(); GuiPainter *painter = new GuiPainter(pixmap); float regridfactor_x=float(nx_cache)/float(nx_map_cache); float regridfactor_y=float(ny_cache)/float(ny_map_cache); if(map_rectsize<0.1) map_rectsize=0.1; if(map_rectsize>1.0) map_rectsize=1.0; int width =int(map_rectsize*float(coarseFactor_cache)*regridfactor_x+0.5); if(width<=0) width=1; int height=int(map_rectsize*float(coarseFactor_cache)*regridfactor_y+0.5); if(height<=0) height=1; ODINLOG(odinlog,normalDebug) << "regridfactor_x/regridfactor_y/width/height=" << regridfactor_x << "/" << regridfactor_y << "/" << width << "/" << height << STD_endl; QColor qc; for(unsigned int iym=0; iymmap_lowbound && mapval<=map_uppbound) { float relval=secureDivision(mapval-map_lowbound,map_uppbound-map_lowbound); qc.setHsv(get_map_hue(relval),get_map_saturation(relval),get_map_value(relval)); int lx=int(float(ixm)*regridfactor_x*float(coarseFactor_cache)+0.5); int ly=int(float(ny_map_cache-1-iym)*regridfactor_y*float(coarseFactor_cache)+0.5); painter->fillRect (lx,ly,width,height,qc); } } } painter->end(); set_pixmap(); delete painter; } void floatLabel2D::mousePressEvent(QMouseEvent *e) { Log odinlog("floatLabel2D","mousePressEvent"); if ( left_button(e,false) ) { ODINLOG(odinlog,normalDebug) << "left_button" << STD_endl; roi_polygon.clear(); roi_painter = new GuiPainter(pixmap); roi_painter->moveTo(e->x(),e->y()); mouse_moved=false; } if( middle_button(e,false) ) { ODINLOG(odinlog,normalDebug) << "middle_button" << STD_endl; drawprofil(labelxpos2xpos(e->x()),X_ENUM); } if( right_button(e,false) ) { ODINLOG(odinlog,normalDebug) << "right_button" << STD_endl; drawprofil(labelypos2ypos(e->y()),Y_ENUM); } } void floatLabel2D::mouseReleaseEvent (QMouseEvent *e) { Log odinlog("floatLabel2D","mouseReleaseEvent"); if ( left_button(e,false) ) { ODINLOG(odinlog,normalDebug) << "Qt::LeftButton used" << STD_endl; roi_painter->end(); delete roi_painter; if(mouse_moved) { ODINLOG(odinlog,normalDebug) << "calling drawroi()" << STD_endl; drawroi(); } else { int xcross=labelxpos2xpos(e->x()); int ycross=labelypos2ypos(e->y()); if(xcross>=0 && xcross=0 && ycrossx(),e->y())); roi_painter->lineTo(e->x(),e->y()); roi_painter->repaint(this); mouse_moved=true; } } int floatLabel2D::check_range(int val, int min, int max) { int result=val; if(result=max) result=max-1; return result; } int floatLabel2D::xpos2labelxpos(int pos) { int result=int((float(pos)+0.5)*float(coarseFactor_cache)); return result; // return check_range(result, 0, nx_cache*coarseFactor_cache); // does not work with out-of-FOV slices in geoedit } int floatLabel2D::ypos2labelypos(int pos) { int result=int((float(ny_cache)-1.0-float(pos)+0.5)*float(coarseFactor_cache)); return result; // return check_range(result, 0, ny_cache*coarseFactor_cache); // does not work with out-of-FOV slices in geoedit } int floatLabel2D::labelxpos2xpos(int pos) { int result=(pos/coarseFactor_cache); return check_range(result, 0, nx_cache); } int floatLabel2D::labelypos2ypos(int pos) { int result=(ny_cache-1-pos/coarseFactor_cache); return check_range(result, 0, ny_cache); } int floatLabel2D::xypos2index(int xpos,int ypos) { int result=ypos*nx_cache+xpos; return check_range(result, 0, nx_cache*ny_cache); } void floatLabel2D::drawprofil(int clickpos,int direction) { Log odinlog("floatLabel2D","drawprofil"); unsigned int j; int ix,iy,profpos; init_pixmap(); GuiPainter *painter = new GuiPainter(pixmap); painter->setPen("Green"); switch (direction) { case X_ENUM: painter->moveTo(xpos2labelxpos(clickpos),0);painter->lineTo(xpos2labelxpos(clickpos),ny_cache*coarseFactor_cache); break; case Y_ENUM: painter->moveTo(0,ypos2labelypos(clickpos));painter->lineTo(nx_cache*coarseFactor_cache,ypos2labelypos(clickpos)); break; } ODINLOG(odinlog,normalDebug) << "moveTo done" << STD_endl; painter->setPen("Red"); switch (direction) { case X_ENUM: ODINLOG(odinlog,normalDebug) << "X point" << STD_endl; profpos=int((float)(nx_cache-1)*data_cache[xypos2index(clickpos,0)]); ix=xpos2labelxpos(profpos); iy=ypos2labelypos(0); painter->moveTo(ix,iy); if(ny_cache) profile_y[0]=data_cache[xypos2index(clickpos,0)]; for(j=1; jlineTo(ix,iy); } emit newProfile(profile_y,ny_cache,false,clickpos); break; case Y_ENUM: ODINLOG(odinlog,normalDebug) << "Y point" << STD_endl; ix=xpos2labelxpos(0); profpos=int((float)(ny_cache-1)*data_cache[xypos2index(0,clickpos)]); iy=ypos2labelypos(profpos); ODINLOG(odinlog,normalDebug) << "profpos/iy=" << profpos << "/" << iy << STD_endl; painter->moveTo(ix,iy); if(nx_cache) profile_x[0]=data_cache[xypos2index(0,clickpos)]; for(j=1; jlineTo(ix,iy); } emit newProfile(profile_x,nx_cache,true,clickpos); break; } painter->end(); ODINLOG(odinlog,normalDebug) << "painter done" << STD_endl; set_pixmap(); delete painter; } void floatLabel2D::drawcross(int xpos,int ypos) { Log odinlog("floatLabel2D","drawcross"); ODINLOG(odinlog,normalDebug) << "xpos/ypos=" << xpos << "/" << ypos << STD_endl; // position will be centered on voxel by the transformation functions int centerx=xpos2labelxpos(xpos); int centery=ypos2labelypos(ypos); ODINLOG(odinlog,normalDebug) << "centerx/centery=" << centerx << "/" << centery << STD_endl; init_pixmap(); GuiPainter *painter = new GuiPainter(pixmap); painter->setPen(_ARRAY_SELECTION_COLOR_); painter->moveTo(centerx-CROSSHAIR_SIZE,centery); painter->lineTo(centerx+CROSSHAIR_SIZE,centery); painter->moveTo(centerx,centery-CROSSHAIR_SIZE); painter->lineTo(centerx,centery+CROSSHAIR_SIZE); painter->end(); set_pixmap(); delete painter; } void floatLabel2D::drawroi() { Log odinlog("floatLabel2D","mouseReleaseEvent"); init_pixmap(); GuiPainter *painter = new GuiPainter(pixmap); QRegion* rgn=painter->draw_region(roi_polygon); painter->end(); set_pixmap(); delete painter; if(rgn) { for(unsigned int iy=0; iycontains ( QPoint(xpos2labelxpos(ix),ypos2labelypos(iy)) ) ) roi_mask[iy*nx_cache+ix]=1.0; else roi_mask[iy*nx_cache+ix]=0.0; } } // for(unsigned int i=0; i<(nx_cache*ny_cache); i++) roi_mask[i]=secureDivision(roi_mask[i],double(npoints)); delete rgn; ODINLOG(odinlog,normalDebug) << "emitting newMask" << STD_endl; emit newMask(roi_mask); } } floatLabel2D::~floatLabel2D(){ delete[] imagebuff; // delete[] data_cache; delete[] profile_x; delete[] profile_y; delete[] roi_mask; } odin-1.8.5/odinqt/odinqt_callback.h0000644000175000017500000000554011322062347014164 00000000000000#include #include #include #include #include #include "odinqt.h" #if QT_VERSION > 0x03FFFF #define QT_VERSION_4 #else #if QT_VERSION > 299 #define QT_VERSION_3 #else #define QT_VERSION_PRE3 #endif #endif /** * This class dispatches calls of Qt slots to virtual member functions */ class SlotDispatcher : public QObject { Q_OBJECT public: SlotDispatcher(GuiListView* glv, GuiListViewCallback* glv_cb) { glv_cache=glv; glv_cb_cache=glv_cb; #ifdef QT_VERSION_4 connect(glv->get_widget(), SIGNAL(itemClicked(QTableWidgetItem*)), this, SLOT(qtwi_clicked(QTableWidgetItem*)) ); #else connect(glv->get_widget(), SIGNAL(clicked(QListViewItem*)), this, SLOT(qlvi_clicked(QListViewItem*)) ); #endif } SlotDispatcher(GuiToolButton* gtb, QObject* receiver, const char* member) { if(receiver) connect(gtb->qtb, SIGNAL(clicked()), receiver, member ); } SlotDispatcher(GuiButton* gb, QObject* receiver, const char* member) { if(receiver) connect(gb->qpb, SIGNAL(clicked()), receiver, member ); } SlotDispatcher(GuiLineEdit* gle, QObject* receiver, const char* member) { if(receiver) { #ifdef QT_VERSION_4 connect(gle->qle, SIGNAL(editingFinished()), receiver, member ); #else #ifdef QT_VERSION_3 connect(gle->qle, SIGNAL(lostFocus()), receiver, member ); // only available on Qt3 #endif connect(gle->qle, SIGNAL(returnPressed()), receiver, member ); #endif } } public slots: void qlvi_clicked(QListViewItem* item) { #ifndef QT_VERSION_4 Log odinlog("SlotDispatcher","qlvi_clicked"); ODINLOG(odinlog,normalDebug) << "item=" << item << STD_endl; if(!glv_cb_cache) return; GuiListItem* itemptr=0; GuiListItem(); // create listmap ODINLOG(odinlog,normalDebug) << "GuiListItem(); done" << STD_endl; STD_map::iterator it=GuiListItem::listmap->find(item); if(it!=GuiListItem::listmap->end()) itemptr=it->second; ODINLOG(odinlog,normalDebug) << "itemptr=" << itemptr << STD_endl; glv_cb_cache->clicked(itemptr); #endif } void qtwi_clicked(QTableWidgetItem* item) { #ifdef QT_VERSION_4 Log odinlog("SlotDispatcher","qtwi_clicked"); ODINLOG(odinlog,normalDebug) << "item=" << item << STD_endl; if(!glv_cb_cache) return; GuiListItem* itemptr=0; GuiListItem(); // create tablemap ODINLOG(odinlog,normalDebug) << "GuiListItem(); done" << STD_endl; STD_map::iterator it=GuiListItem::tablemap->find(item); if(it!=GuiListItem::tablemap->end()) itemptr=it->second; ODINLOG(odinlog,normalDebug) << "itemptr=" << itemptr << STD_endl; glv_cb_cache->clicked(itemptr); #endif } private: void common_int() { glv_cache=0; glv_cb_cache=0; } GuiListView* glv_cache; GuiListViewCallback* glv_cb_cache; }; odin-1.8.5/odinqt/float3d.cpp0000644000175000017500000000737311670202077012751 00000000000000#include #include "float3d.h" floatBox3D::floatBox3D(const float *data, float lowbound, float uppbound, long int nx, long int ny, long int nz, int coarseFactor, QWidget *parent, const char *name, const float *overlay_map, float lowbound_map, float uppbound_map, unsigned int nx_map, unsigned int ny_map, unsigned int nz_map, bool map_firescale, float map_rectsize, bool colormap) : QGroupBox(name,parent) { Log odinlog("floatBox3D","floatBox3D"); data_cache=data; oneimagesize=nx*ny; nz_cache=nz; lowbound_cache=lowbound; uppbound_cache=uppbound; map_cache=0; onemapsize=0; lowbound_map_cache=lowbound_map; uppbound_map_cache=uppbound_map; rectsize_map_cache=map_rectsize; if(overlay_map) { if(nz==nz_map) { map_cache=overlay_map; onemapsize=nx_map*ny_map; ODINLOG(odinlog,normalDebug) << "map_cache/onemapsize/nz_map=" << map_cache << "/" << onemapsize << "/" << nz_map << STD_endl; } else { ODINLOG(odinlog,errorLog) << "Cannot handle overlay_map with nz(" << nz_map << ") differing from data's nz(" << nz << ")" << STD_endl; } } int nrow=1; if(nz>1) nrow++; int ncol=2; if(overlay_map) ncol++; grid=new GuiGridLayout( this, nrow, ncol); label = new floatLabel2D(data,lowbound,uppbound,nx,ny,coarseFactor,this,name,overlay_map,lowbound_map,uppbound_map,nx_map,ny_map,map_firescale,map_rectsize,colormap); grid->add_widget( label, 0, 0, GuiGridLayout::Default, 1, 2 ); connect(label,SIGNAL(clicked(int,int)),this,SLOT(emitClicked(int,int))); connect(label,SIGNAL(newProfile(const float *, int, bool, int)),this,SLOT(emitNewProfile(const float *, int, bool, int))); connect(label,SIGNAL(newMask(const float *)),this,SLOT(emitNewMask(const float *))); maplegend=0; if(overlay_map) { maplegend = label->get_map_legend(this); if(maplegend) grid->add_widget( maplegend, 0, 2 ); } zslider=0; zval=0; if(nz>1) { zslider=new GuiSlider(this, 0, nz-1, 1, 0, 1); connect(zslider->get_widget(), SIGNAL(valueChanged(int)), this, SLOT(changez(int))); grid->add_widget( zslider->get_widget(), 1, 0 ); zval=new QLabel(this); grid->add_widget( zval, 1, 1 ); // set size according to max num of digits zval->setMinimumWidth(_FONT_SIZE_*int(log10(nz-1)+1)); zval->setNum(0); } mask3d=new float[nx*ny*nz]; for(int i=0; irefresh(data_cache+iz*oneimagesize,lowbound_cache,uppbound_cache); if(map_cache) label->refreshMap(map_cache+iz*onemapsize,lowbound_map_cache,uppbound_map_cache,rectsize_map_cache); } void floatBox3D::write_pixmap(const char* fname, const char* format, bool dump_all) const { if(dump_all) { for(int iz=0; iz1) onefname+=itos(iz,nz_cache-1); onefname+="."+::tolowerstr(format); label->write_pixmap( onefname.c_str(), format); } repaint_slice(get_current_z()); } else { label->write_pixmap(fname,format); } } void floatBox3D::refresh(const float* data, float lowbound, float uppbound) { data_cache=data; label->refresh(data_cache+oneimagesize*get_current_z(),lowbound,uppbound); lowbound_cache=lowbound; uppbound_cache=uppbound; } void floatBox3D::changez(int iz) { Log odinlog("floatBox3D","changez"); repaint_slice(iz); repaint(); if(zval) zval->setNum(iz); } int floatBox3D::get_current_z() const { if(zslider) return zslider->get_value(); return 0; } floatBox3D::~floatBox3D() { if(zslider) delete zslider; if(zval) delete zval; if(maplegend) delete maplegend; delete label; delete grid; delete[] mask3d; } odin-1.8.5/odinqt/plot.h0000644000175000017500000001051111322062347012022 00000000000000/*************************************************************************** plot.h - description ------------------- begin : Mon Aug 1 2005 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PLOT_H #define PLOT_H #include // Include Qt stuff first to avoid ambiguities with 'debug' symbol #include "odinqt.h" // forward declarations class QwtPlot; class QwtPlotCurve; class QwtPlotMarker; class QwtPlotGrid; class QRect; class QwtWheel; class QwtScaleDraw; class GuiPlotPicker; // work around different declarations of QwtDoubleRect #if QT_VERSION >= 0x040000 class QRectF; typedef QRectF QwtDoubleRect; #else class QwtDoubleRect; #endif ///////////////////////////////////////////////// /** * Abstraction of a plotting widget */ class GuiPlot : public QObject { Q_OBJECT public: GuiPlot(QWidget *parent, bool fixed_size=false, int width=_ARRAY_WIDGET_WIDTH_-20, int height=_ARRAY_WIDGET_HEIGHT_-20); ~GuiPlot(); void set_x_axis_label(const char *xAxisLabel, bool omit=false); void set_y_axis_label(const char *yAxisLabelLeft, const char *yAxisLabelRight=0); long insert_curve(bool use_right_y_axis=false, bool draw_spikes=false, bool baseline=false); long insert_marker(const char* label, double x, bool outline=false, bool horizontal=false, bool animate=false); void remove_marker(long id); void set_marker_pos(long id, double x); // memory NOT managed by GuiPlot void set_curve_data(long curveid, const double* x, const double* y, int n, bool symbol=false); void replot(); void autoscale(); void autoscale_y(double& maxBound); void rescale_y(double maxBound); void clear(); void remove_markers(); double get_x(int x_pixel) const; double get_y(int y_pixel, bool right_axes=false) const; long closest_curve(int x, int y, int& dist) const; void highlight_curve(long id, bool flag); void set_x_axis_scale(double lbound, double ubound); void set_y_axis_scale(double lbound, double ubound, bool right_axes=false); void set_curve_pen(long id, const char* color, int width=1); void set_rect_outline_style(); void set_line_outline_style(bool horizontal); void enable_axes(bool flag); void enable_grid(bool flag); void print(QPainter* painter, const QRect& rect) const; QWidget* get_widget(); signals: void plotMousePressed(const QMouseEvent&); void plotMouseReleased(const QMouseEvent&); void plotMouseMoved(const QMouseEvent&); private slots: void emit_plotMousePressed(const QMouseEvent& qme); void emit_plotMouseReleased(const QMouseEvent& qme); void emit_plotMouseMoved(const QMouseEvent& qme); private: friend class GuiPlotPicker; void set_axis_label(int axisId, const char* label, bool omit, int alignment); QwtPlot* qwtplotter; GuiPlotPicker* picker; // Use functions with check to access curve_map/marker_map QwtPlotCurve* get_curve(long id); QwtPlotMarker* get_marker(long id); // to emulate Qwt4 behaviour on Qwt5 STD_map curve_map; STD_map marker_map; QwtPlotGrid* plotgrid; int canvas_framewidth; long baseline_id_cache; }; //////////////////////////////////////////////////////////// /** * Abstraction of a slider wheel */ class GuiWheel : public QObject { Q_OBJECT public: GuiWheel(QWidget *parent); ~GuiWheel(); void set_range(double min, double max); void set_value(double newval); QWidget* get_widget(); signals: void valueChanged(double); private slots: void emit_valueChanged(double newval); private: QwtWheel* wheel; }; #endif odin-1.8.5/odinqt/boolbutton.h0000644000175000017500000000325211322062347013237 00000000000000/*************************************************************************** boolbutton.h - description ------------------- begin : Sun Jul 16 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BOOLBUTTON_H #define BOOLBUTTON_H #include #include "odinqt.h" /** *This class provides a button with a nice frame */ class buttonBox : public QGroupBox { Q_OBJECT public: buttonBox(const char *text, QWidget *parent, const char *buttonlabel); buttonBox(const char *ontext,const char *offtext, bool initstate, QWidget *parent, const char *buttonlabel); ~buttonBox(); bool is_on() const {return gb->is_on();} public slots: void setToggleState(bool); private slots: void reportclicked(); void setButtonState(); signals: void buttonClicked(); void buttonToggled(bool); private: GuiGridLayout* grid; GuiButton* gb; }; #endif odin-1.8.5/odinqt/enumbox.h0000644000175000017500000000323111322062347012522 00000000000000/*************************************************************************** enumbox.h - description ------------------- begin : Tue May 29 2001 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ENUMBOX_H #define ENUMBOX_H #include #include "odinqt.h" /** * This class provides a combobox with a nice frame */ class enumBox : public QGroupBox { Q_OBJECT public: enumBox(const svector& items,QWidget *parent,const char *name,bool editButton=false,bool infoButton=false); ~enumBox(); public slots: void setValue( int val ); signals: void newVal( int val ); void edit(); void info(); private slots: void emitNewVal(int val); void reportEditClicked(); void reportInfoClicked(); private: int old_val; GuiComboBox* cb; GuiButton* pb_edit; GuiButton* pb_info; GuiGridLayout* grid; }; #endif odin-1.8.5/odinqt/intedit.h0000644000175000017500000000557011322062347012515 00000000000000/*************************************************************************** intedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef INTEDIT_H #define INTEDIT_H #include #include "odinqt.h" /** * This class implements a line edit with int values only. */ class intLineEdit : public QObject { Q_OBJECT public: intLineEdit(int minValue, int maxValue, int value, QWidget *parent, const char *name, int width, int height ); ~intLineEdit(); QWidget* get_widget() {return gle->get_widget();} public slots: void setintLineEditValue( int value ); private slots: void emitSignal( ); signals: void intLineEditValueChanged( int value ); private: void set_value(int value); GuiLineEdit* gle; }; //////////////////////////////////////////////////////////// /** * This class contains a intlineedit to display an int value * in a nice box with a label. */ class intLineBox : public QGroupBox { Q_OBJECT public: intLineBox(int value, QWidget *parent, const char *name); ~intLineBox(); public slots: void setintLineBoxValue( int value ); private slots: void emitSignal( int value ); signals: void intLineBoxValueChanged( int value ); void SignalToChild( int value ); private: GuiGridLayout* grid; intLineEdit *le; }; //////////////////////////////////////////////////////////// /** * This class implements a slider useful for scientific applications * by composing a QSlider(int values) and a intLineEdit into one widget. */ class intScientSlider : public QGroupBox { Q_OBJECT public: intScientSlider(int minValue, int maxValue, int Step, int value, QWidget *parent, const char *name); ~intScientSlider(); public slots: void setintScientSliderValue( int value ); private slots: void emitSignal( int value ); signals: void intScientSliderValueChanged( int value ); private: int value; GuiSlider* slider; GuiGridLayout* grid; intLineEdit *le; }; //////////////////////////////////////////////////////////// #endif odin-1.8.5/odinqt/plot.cpp0000644000175000017500000004573211322062347012372 00000000000000#include // for mouse events #include "plot.h" #ifdef HAVE_QWT_QT4_QWT_GLOBAL_H // For Debian #include #include #include #include #include #include #if QWT_VERSION > 0x04FFFF #include #include #include #include #include #include #else #include #endif #else #include #include #include #include #include #include #if QWT_VERSION > 0x04FFFF #include #include #include #include #include #include #else #include #endif #endif class GuiPlotPrintFilter : public QwtPlotPrintFilter { public: GuiPlotPrintFilter(long baseline_id) : baseline_id_cache(baseline_id) {} private: long baseline_id_cache; // overloading virtual functions from QwtPlotPrintFilter #if QWT_VERSION > 0x04FFFF QColor color(const QColor &c, Item item) const { QColor result=QwtPlotPrintFilter::color(c,item); // default #else QColor color(const QColor &c, Item item, int id = -1) const { QColor result=QwtPlotPrintFilter::color(c,item,id); // default #endif if(item==QwtPlotPrintFilter::Curve) result=QColor("Black"); if(item==QwtPlotPrintFilter::CurveSymbol) result=QColor("Black"); if(item==QwtPlotPrintFilter::Marker) result=QColor("Black"); if(item==QwtPlotPrintFilter::MajorGrid) result=QColor("Gray").light(130); if(item==QwtPlotPrintFilter::MinorGrid) result=QColor("Gray").light(150); #if QWT_VERSION > 041 if(item==QwtPlotPrintFilter::CanvasBackground) result=QColor("White"); #else if(item==QwtPlotPrintFilter::Background) result=QColor("White"); #endif #if QWT_VERSION < 0x04FFFF if(item==QwtPlotPrintFilter::Curve && id==baseline_id_cache) result=QColor("Gray").dark(150); #endif return result; } #if QWT_VERSION > 0x04FFFF QFont font(const QFont &, Item item) const { #else QFont font(const QFont &, Item item, int id = -1) const { #endif return QFont(_FONT_TYPE_, 7); } }; //////////////////////////////////////////////////////////////////////////// struct GuiScaleDraw : QwtScaleDraw { // implementing virtual functions of QwtScaleDraw #if QWT_VERSION < 0x04FFFF QString label (double val) const {return get_str(val);} #else QwtText label (double val) const {return QString(get_str(val));} #endif private: const char* get_str(double val) const { bool vertical=false; #if QWT_VERSION < 0x04FFFF QwtScaleDraw::Orientation ort=orientation(); if(ort==QwtScaleDraw::Left || ort==QwtScaleDraw::Right) vertical=true; #else QwtScaleDraw::Alignment ort=alignment(); if(ort==QwtScaleDraw::LeftScale || ort==QwtScaleDraw::RightScale) vertical=true; #endif if(vertical) result=ftos(val,2,alwaysExp); else result=ftos(val,2,neverExp); return result.c_str(); } mutable STD_string result; }; //////////////////////////////////////////////////////////////////////////// class GuiPlotPicker : public QwtPlotPicker { public: GuiPlotPicker(QwtPlotCanvas* canvas, GuiPlot* plot4feedback) : QwtPlotPicker(canvas), plot(plot4feedback) {} protected: void widgetMousePressEvent(QMouseEvent* qme) { Log odinlog("GuiPlotPicker","widgetMousePressEvent"); QwtPlotPicker::widgetMousePressEvent(qme); plot->emit_plotMousePressed(*qme); ODINLOG(odinlog,normalDebug) << "widgetMousePressEvent" << STD_endl; } void widgetMouseReleaseEvent(QMouseEvent* qme) { Log odinlog("GuiPlotPicker","widgetMouseReleaseEvent"); QwtPlotPicker::widgetMouseReleaseEvent(qme); plot->emit_plotMouseReleased(*qme); ODINLOG(odinlog,normalDebug) << "widgetMouseReleaseEvent" << STD_endl; } void widgetMouseMoveEvent(QMouseEvent* qme) { QwtPlotPicker::widgetMouseMoveEvent(qme); plot->emit_plotMouseMoved(*qme); } private: GuiPlot* plot; }; //////////////////////////////////////////////////////////////////////////// GuiPlot::GuiPlot(QWidget *parent, bool fixed_size, int width, int height) { Log odinlog("GuiPlot","GuiPlot(...)"); baseline_id_cache=0; qwtplotter = new QwtPlot(parent); if(fixed_size) qwtplotter->setFixedSize (width,height); else qwtplotter->setMinimumSize(width,height); qwtplotter->resize(width,height); qwtplotter->plotLayout()->setAlignCanvasToScales(true); // to get mouse-move events qwtplotter->canvas()->setMouseTracking(true); // set default axis titles set_x_axis_label(0); set_y_axis_label(0,0); #if QWT_VERSION < 0x04FFFF qwtplotter->setAxisTitleFont(QwtPlot::xBottom,QFont(_FONT_TYPE_, _FONT_SIZE_)); qwtplotter->setAxisTitleFont(QwtPlot::yLeft, QFont(_FONT_TYPE_, _FONT_SIZE_)); qwtplotter->setAxisTitleFont(QwtPlot::yRight, QFont(_FONT_TYPE_, _FONT_SIZE_)); #endif qwtplotter->enableAxis(QwtPlot::xBottom,true); /* qwtplotter->setAxisLabelFormat(QwtPlot::yLeft,'e',1,10); qwtplotter->setAxisLabelFormat(QwtPlot::xBottom,'f',2); */ qwtplotter->setAxisScaleDraw(QwtPlot::yLeft, new GuiScaleDraw()); qwtplotter->setAxisScaleDraw(QwtPlot::xBottom, new GuiScaleDraw()); qwtplotter->setCanvasBackground(_ARRAY_BACKGROUND_COLOR_); #if QWT_VERSION > 0x04FFFF plotgrid=new QwtPlotGrid(); plotgrid->attach(qwtplotter); ODINLOG(odinlog,normalDebug) << "plotgrid=" << plotgrid << STD_endl; #endif enable_grid(true); #if QWT_VERSION < 0x04FFFF qwtplotter->enableLegend(false); qwtplotter->enableOutline(false); #endif canvas_framewidth=qwtplotter->canvas()->lineWidth(); picker=new GuiPlotPicker(qwtplotter->canvas(),this); picker->setRubberBandPen(QColor(_ARRAY_SELECTION_COLOR_)); set_rect_outline_style(); // do this after picker was initialized } void GuiPlot::set_axis_label(int axisId, const char* label, bool omit, int alignment) { Log odinlog("GuiPlot","set_axis_label"); ODINLOG(odinlog,normalDebug) << "axisId/label/omit/alignment=" << axisId << "/" << label << "/" << omit << "/" << alignment << STD_endl; if(!label || STD_string(label)=="") omit=true; if(omit) { #if QWT_VERSION > 0x04FFFF QwtText txt(""); txt.setFont(QFont(_FONT_TYPE_, 1)); qwtplotter->setAxisTitle(axisId,txt); #else qwtplotter->setAxisTitle(axisId,""); qwtplotter->setAxisTitleFont(axisId,QFont(_FONT_TYPE_, 1)); // make font zero size to save space in widget #endif } else { #if QWT_VERSION > 0x04FFFF QwtText txt(label); txt.setRenderFlags(alignment); qwtplotter->setAxisTitle(axisId,txt); #else qwtplotter->setAxisTitle(axisId,label); qwtplotter->setAxisTitleAlignment(axisId,alignment); #endif } } void GuiPlot::set_x_axis_label(const char *xAxisLabel, bool omit) { set_axis_label(QwtPlot::xBottom,xAxisLabel,omit,Qt::AlignRight); } void GuiPlot::set_y_axis_label(const char *yAxisLabelLeft, const char *yAxisLabelRight) { if(yAxisLabelLeft) set_axis_label(QwtPlot::yLeft, yAxisLabelLeft, false,Qt::AlignCenter); if(yAxisLabelRight) set_axis_label(QwtPlot::yRight,yAxisLabelRight,false,Qt::AlignCenter); if(yAxisLabelLeft) qwtplotter->enableAxis(QwtPlot::yLeft,true); if(yAxisLabelRight) qwtplotter->enableAxis(QwtPlot::yRight,true); } long GuiPlot::insert_curve(bool use_right_y_axis, bool draw_spikes, bool baseline) { Log odinlog("GuiPlot","insert_curve"); long result=0; int yaxis=QwtPlot::yLeft; if(use_right_y_axis) yaxis=QwtPlot::yRight; QPen curvepen(QColor(_ARRAY_FOREGROUND_COLOR1_)); if(use_right_y_axis || baseline) { curvepen=QColor(_ARRAY_FOREGROUND_COLOR2_); } #if QWT_VERSION > 0x04FFFF QwtPlotCurve* curve=new QwtPlotCurve(); curve->setAxis(QwtPlot::xBottom, yaxis); curve->setPen(curvepen); curve->attach(qwtplotter); result=curve_map.size()+1; curve_map[result]=curve; #else result=qwtplotter->insertCurve("",QwtPlot::xBottom,yaxis); qwtplotter->setCurvePen(result,curvepen); #endif if(draw_spikes) { #if QWT_VERSION > 0x04FFFF curve->setBaseline(0.0); curve->setStyle(QwtPlotCurve::Sticks); #else qwtplotter->setCurveBaseline(result,0.0); qwtplotter->setCurveStyle(result,QwtCurve::Sticks); #endif } if(baseline) baseline_id_cache=result; ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } long GuiPlot::insert_marker(const char* label, double x, bool outline, bool horizontal, bool animate) { Log odinlog("GuiPlot","insert_marker"); long result=0; ODINLOG(odinlog,normalDebug) << "label/x/outline/horizontal/animate=" << label << "/" << x << "/" << outline << "/" << horizontal << "/" << animate << STD_endl; int axis=QwtPlot::xBottom; if(horizontal) axis=QwtPlot::yLeft; QColor markcolor(QColor(_ARRAY_MARKER_COLOR_).light(_ARRAY_MARKER_BRIGHT_FACTOR_)); if(animate) markcolor=QColor("red"); if(outline) markcolor=QColor(_ARRAY_SELECTION_COLOR_); #if QWT_VERSION > 0x04FFFF QwtPlotMarker* marker=new QwtPlotMarker(); if(horizontal) { marker->setLineStyle(QwtPlotMarker::HLine); marker->setYValue(x); } else { marker->setLineStyle(QwtPlotMarker::VLine); marker->setXValue(x); } marker->setLinePen(QPen(markcolor)); #if QWT_VERSION > 0x04FFFF QwtText txt(label); txt.setColor(markcolor); txt.setRenderFlags(Qt::AlignTop); marker->setLabel(txt); #else marker->setLabelPen(QPen(markcolor)); marker->setLabelAlignment(Qt::AlignTop); marker->setLabel(QString(label)); #endif marker->attach(qwtplotter); result=marker_map.size()+1; marker_map[result]=marker; #else result=qwtplotter->insertLineMarker(label, axis); qwtplotter->setMarkerPen(result,QPen(markcolor)); if(horizontal) qwtplotter->setMarkerYPos(result,x); else qwtplotter->setMarkerXPos(result,x); #endif ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } void GuiPlot::remove_marker(long id) { Log odinlog("GuiPlot","remove_marker"); ODINLOG(odinlog,normalDebug) << "id=" << id << STD_endl; #if QWT_VERSION > 0x04FFFF QwtPlotMarker* qpm=get_marker(id); if(qpm) qpm->detach(); #else qwtplotter->removeMarker(id); #endif } void GuiPlot::set_marker_pos(long id, double x) { Log odinlog("GuiPlot","remove_marker"); ODINLOG(odinlog,normalDebug) << "id/x=" << id << "/" << x << STD_endl; #if QWT_VERSION > 0x04FFFF QwtPlotMarker* qpm=get_marker(id); if(qpm) qpm->setXValue(x); #else qwtplotter->setMarkerXPos(id,x); #endif } void GuiPlot::set_curve_data(long curveid, const double* x, const double* y, int n, bool symbol) { Log odinlog("GuiPlot","set_curve_data"); ODINLOG(odinlog,normalDebug) << "curveid/x/y/symbol=" << curveid << "/" << x << "/" << y << "/" << symbol << STD_endl; #if QWT_VERSION > 0x04FFFF QwtSymbol::Style symbstyle=QwtSymbol::NoSymbol; #else QwtSymbol::Style symbstyle=QwtSymbol::None; #endif if(symbol) { symbstyle=QwtSymbol::Ellipse; } QwtSymbol symb(symbstyle,QBrush(),QColor(_ARRAY_FOREGROUND_COLOR1_),QSize(PLOT_SYMBOLS_SIZE,PLOT_SYMBOLS_SIZE)); if(n) ODINLOG(odinlog,normalDebug) << "y[" << n/2 << "]=" << y[n/2] << STD_endl; #if QWT_VERSION > 0x04FFFF QwtPlotCurve* qpc=get_curve(curveid); if(qpc) { qpc->setSymbol(symb); qpc->setRawData(x, y, n); } #else qwtplotter->setCurveSymbol(curveid,symb); qwtplotter->setCurveRawData(curveid, x, y, n); #endif } void GuiPlot::replot() { Log odinlog("GuiPlot","replot"); ODINLOG(odinlog,normalDebug) << "replotting " << curve_map.size() << " curves and " << marker_map.size() << " markers" << STD_endl; qwtplotter->replot(); // qwtzoomer->setZoomBase(); } void GuiPlot::autoscale() { qwtplotter->setAxisAutoScale(QwtPlot::xBottom); qwtplotter->setAxisAutoScale(QwtPlot::yLeft); qwtplotter->setAxisAutoScale(QwtPlot::yRight); replot(); } void GuiPlot::autoscale_y(double& maxBound) { qwtplotter->setAxisAutoScale(QwtPlot::yLeft); qwtplotter->replot(); // seems to be neccessary for correct autoscaling, even if the curve is already added #if QWT_VERSION > 0x04FFFF #if QWT_VERSION > 0x0501FF double new_lbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->lowerBound(); double new_hbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->upperBound(); #else double new_lbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->lBound(); double new_hbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->hBound(); #endif #else double new_lbound=qwtplotter->axisScale(QwtPlot::yLeft)->lBound(); double new_hbound=qwtplotter->axisScale(QwtPlot::yLeft)->hBound(); #endif // symmetrical adjustment maxBound=STD_max(fabs(new_lbound),fabs(new_hbound)); new_lbound=-maxBound; new_hbound= maxBound; qwtplotter->setAxisScale(QwtPlot::yLeft, new_lbound, new_hbound); // switch back to manual scaling for scrolling replot(); } void GuiPlot::rescale_y(double maxBound) { qwtplotter->setAxisScale(QwtPlot::yLeft, -maxBound, maxBound); replot(); } void GuiPlot::clear() { Log odinlog("GuiPlot","clear()"); #if QWT_VERSION > 0x04FFFF for(STD_map::const_iterator curvit=curve_map.begin(); curvit!=curve_map.end(); ++curvit) { ODINLOG(odinlog,normalDebug) << "Detaching curve #" << curvit->first << STD_endl; curvit->second->detach(); ODINLOG(odinlog,normalDebug) << "Deleting curve #" << curvit->first << STD_endl; delete curvit->second; } ODINLOG(odinlog,normalDebug) << "Clearing curve cache" << STD_endl; curve_map.clear(); ODINLOG(odinlog,normalDebug) << "Removing markers" << STD_endl; remove_markers(); #endif qwtplotter->clear(); // do this after detaching curves } void GuiPlot::remove_markers() { #if QWT_VERSION > 0x04FFFF for(STD_map::const_iterator markit=marker_map.begin(); markit!=marker_map.end(); ++markit) { markit->second->detach(); delete markit->second; } marker_map.clear(); #else qwtplotter->removeMarkers(); #endif } double GuiPlot::get_x(int x_pixel) const { Log odinlog("GuiPlot","get_x"); double result=qwtplotter->invTransform(QwtPlot::xBottom,x_pixel+canvas_framewidth); ODINLOG(odinlog,normalDebug) << "result/x_pixel=" << result << "/" << x_pixel << STD_endl; return result;; } double GuiPlot::get_y(int y_pixel, bool right_axes) const { if(right_axes) return qwtplotter->invTransform(QwtPlot::yRight, y_pixel+canvas_framewidth); else return qwtplotter->invTransform(QwtPlot::yLeft, y_pixel+canvas_framewidth); } long GuiPlot::closest_curve(int x, int y, int& dist) const { #if QWT_VERSION > 0x04FFFF Log odinlog("GuiPlot","closest_curve"); long result=-1; double dmin = 1.0e10; double curvedist; QPoint pos(x,y); for(STD_map::const_iterator curvit=curve_map.begin(); curvit!=curve_map.end(); ++curvit) { curvit->second->closestPoint(pos,&curvedist); if(curvedistfirst; dist=int(curvedist); dmin=curvedist; } } ODINLOG(odinlog,normalDebug) << "result/dist" << result << "/" << dist << STD_endl; return result; #else return qwtplotter->closestCurve(x,y,dist); #endif } void GuiPlot::highlight_curve(long id, bool flag) { const char* color=_ARRAY_FOREGROUND_COLOR1_; if(flag) color=_ARRAY_HIGHLIGHT_COLOR_; set_curve_pen(id,color); } void GuiPlot::set_x_axis_scale(double lbound, double ubound) { Log odinlog("GuiPlot","set_x_axis_scale"); ODINLOG(odinlog,normalDebug) << "lbound/ubound=" << lbound << "/" << ubound << STD_endl; qwtplotter->setAxisScale(QwtPlot::xBottom,lbound,ubound); } void GuiPlot::set_y_axis_scale(double lbound, double ubound, bool right_axes) { if(right_axes) qwtplotter->setAxisScale(QwtPlot::yRight,lbound,ubound); else qwtplotter->setAxisScale(QwtPlot::yLeft, lbound,ubound); } void GuiPlot::set_curve_pen(long id, const char* color, int width) { QPen qp; qp.setColor(color); qp.setWidth(width); #if QWT_VERSION > 0x04FFFF QwtPlotCurve* qpc=get_curve(id); if(qpc) qpc->setPen(qp); #else qwtplotter->setCurvePen(id,qp); #endif } void GuiPlot::set_rect_outline_style() { picker->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::CornerToCorner | QwtPicker::DragSelection); picker->setRubberBand(QwtPicker::RectRubberBand); } void GuiPlot::set_line_outline_style(bool horizontal) { picker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::DragSelection); if(horizontal) picker->setRubberBand(QwtPicker::HLineRubberBand); else picker->setRubberBand(QwtPicker::VLineRubberBand); } void GuiPlot::enable_axes(bool flag) { qwtplotter->enableAxis(QwtPlot::xBottom,flag); qwtplotter->enableAxis(QwtPlot::yLeft,flag); } void GuiPlot::enable_grid(bool flag) { Log odinlog("GuiPlot","enable_grid"); if(flag) { QPen gridpen(QColor(_ARRAY_GRID_COLOR_).dark(_ARRAY_GRID_DARK_FACTOR_)); #if QWT_VERSION > 0x04FFFF ODINLOG(odinlog,normalDebug) << "plotgrid=" << plotgrid << STD_endl; plotgrid->setPen(gridpen); plotgrid->setMajPen(gridpen); plotgrid->setMinPen(gridpen); #else qwtplotter->setGridPen(gridpen); qwtplotter->setGridMajPen(gridpen); qwtplotter->setGridMinPen(gridpen); #endif } #if QWT_VERSION > 0x04FFFF plotgrid->enableX(flag); plotgrid->enableY(flag); #else qwtplotter->enableGridX(flag); qwtplotter->enableGridY(flag); #endif } void GuiPlot::print(QPainter* painter, const QRect& rect) const { GuiPlotPrintFilter pfilter(baseline_id_cache); qwtplotter->print(painter,rect,pfilter); } QWidget* GuiPlot::get_widget() {return qwtplotter;} void GuiPlot::emit_plotMousePressed(const QMouseEvent& qme) { emit plotMousePressed(qme); } void GuiPlot::emit_plotMouseReleased(const QMouseEvent& qme) { emit plotMouseReleased(qme); } void GuiPlot::emit_plotMouseMoved(const QMouseEvent& qme) { emit plotMouseMoved(qme); } QwtPlotCurve* GuiPlot::get_curve(long id) { STD_map::iterator it=curve_map.find(id); if(it==curve_map.end()) return 0; return it->second; } QwtPlotMarker* GuiPlot::get_marker(long id) { STD_map::iterator it=marker_map.find(id); if(it==marker_map.end()) return 0; return it->second; } GuiPlot::~GuiPlot() { Log odinlog("GuiPlot","~GuiPlot()"); clear(); #if QWT_VERSION > 0x04FFFF delete plotgrid; #endif delete picker; delete qwtplotter; } //////////////////////////////////////////////////////////////////////////// GuiWheel::GuiWheel(QWidget *parent) { wheel=new QwtWheel(parent); wheel->setOrientation(Qt::Vertical); connect( wheel, SIGNAL(valueChanged(double)), SLOT(emit_valueChanged(double)) ); } void GuiWheel::set_range(double min, double max) { wheel->setRange(min,max); } void GuiWheel::set_value(double newval) { wheel->fitValue(newval); } QWidget* GuiWheel::get_widget() {return wheel;} void GuiWheel::emit_valueChanged(double newval) {emit valueChanged(newval);} GuiWheel::~GuiWheel() { delete wheel; } odin-1.8.5/odinqt/floatedit.cpp0000644000175000017500000001424611322062347013363 00000000000000#include #include "floatedit.h" #include // for ftos #include floatLineEdit::floatLineEdit(float minValue, float maxValue, float value,int digits, QWidget *parent, const char *name, int width, int height ) { gle = new GuiLineEdit(parent, this, SLOT(emitSignal()), width, height); // minValue & maxValue unused so far: minValue=maxValue=0.0; digits_cache=digits; set_value(value); } floatLineEdit::~floatLineEdit() { delete gle; } void floatLineEdit::setfloatLineEditValue( float newValue ) { set_value(newValue); } void floatLineEdit::emitSignal() { if(gle->is_modified()) { value_cache=atof(gle->get_text()); set_value(value_cache); emit floatLineEditValueChanged(value_cache); } } void floatLineEdit::set_value(float value) { value_cache=value; gle->set_text( ftos(value_cache,digits_cache).c_str() ); } ////////////////////////////////////////////////////////////////////////// floatSlider::floatSlider(float minValue, float maxValue, float step, float value, QWidget *parent, const char *name ) { int nsteps=int((maxValue-minValue)/step+0.5); int ival=int((value-minValue)/step+0.5); gs=new GuiSlider( parent, 0, nsteps , 1, ival, nsteps/20); minValue_cache=minValue; step_cache=step; connect(gs->get_widget(),SIGNAL(valueChanged( int )),this,SLOT(emitSignal( int ))); } void floatSlider::setfloatSliderValue( float newValue ) { oldPosition=int((newValue-minValue_cache)/step_cache+0.5); gs->set_value(oldPosition); } void floatSlider::emitSignal( int newintvalue ) { Log odinlog("floatSlider","emitSignal"); ODINLOG(odinlog,normalDebug) << "newintvalue/oldPosition=" << newintvalue << "/" << oldPosition << STD_endl; if (!(newintvalue==oldPosition)) { float newfloatval=minValue_cache+newintvalue*step_cache; emit floatSliderValueChanged(newfloatval); } } QWidget* floatSlider::get_widget() {return gs->get_widget();} floatSlider::~floatSlider() { delete gs; } ////////////////////////////////////////////////////////////////////////// floatLineBox::floatLineBox(float value, int digits,QWidget *parent, const char *name ) : QGroupBox(name,parent) { grid=new GuiGridLayout( this, 1, 1); // Create connected floatSlider and floatLineEdit le = new floatLineEdit( 0.0, 0.0, value,digits, this, "LineEdit", TEXTEDIT_WIDTH, TEXTEDIT_HEIGHT); grid->add_widget(le->get_widget(), 0, 0); connect(le,SIGNAL(floatLineEditValueChanged( float )), this,SLOT(emitSignal( float ))); } void floatLineBox::setfloatLineBoxValue( float newvalue ) { le->setfloatLineEditValue(newvalue); } void floatLineBox::emitSignal( float newvalue ) { emit floatLineBoxValueChanged(newvalue); } floatLineBox::~floatLineBox(){ delete le; delete grid; } ////////////////////////////////////////////////////////////////////////// floatScientSlider::floatScientSlider(float minValue, float maxValue, float Step, float value, int digits, QWidget *parent, const char *name ) : QGroupBox(name, parent ) { grid=new GuiGridLayout(this, 1, 4); slider = new floatSlider( minValue, maxValue, Step, value, this, "Slider" ); le = new floatLineEdit( minValue, maxValue, value,digits, this, "LineEdit", SLIDER_CELL_WIDTH, SLIDER_CELL_HEIGHT ); grid->add_widget(slider->get_widget(), 0, 0, GuiGridLayout::Default, 1, 3 ); grid->add_widget(le->get_widget(), 0, 3); // connect slider and lineedit connect(slider, SIGNAL(floatSliderValueChanged( float )),le, SLOT(setfloatLineEditValue( float))); connect(le, SIGNAL(floatLineEditValueChanged( float )),slider, SLOT(setfloatSliderValue( float))); // Emit signal 'floatScientSliderValueChanged' to outer world connect(slider,SIGNAL(floatSliderValueChanged( float )),this,SLOT(emitSignal( float ))); connect(le,SIGNAL(floatLineEditValueChanged( float )),this,SLOT(emitSignal( float ))); } void floatScientSlider::setfloatScientSliderValue( float newvalue ) { slider->setfloatSliderValue(newvalue); le->setfloatLineEditValue(newvalue); } void floatScientSlider::emitSignal( float newvalue ) { emit floatScientSliderValueChanged(newvalue); } floatScientSlider::~floatScientSlider(){ delete le; delete slider; delete grid; } //////////////////////////////////////////////////////////////////// floatLineBox3D::floatLineBox3D(float xval, float yval, float zval, int digits,QWidget *parent, const char *name ) : QGroupBox(name,parent) { grid=new GuiGridLayout(this, 1, 3); xcache=xval; ycache=yval; zcache=zval; lex = new floatLineEdit( 0.0, 0.0, xval,digits,this, "lex", TEXTEDIT_WIDTH, TEXTEDIT_HEIGHT ); ley = new floatLineEdit( 0.0, 0.0, yval,digits,this, "ley", TEXTEDIT_WIDTH, TEXTEDIT_HEIGHT ); lez = new floatLineEdit( 0.0, 0.0, zval,digits,this, "lez", TEXTEDIT_WIDTH, TEXTEDIT_HEIGHT ); grid->add_widget( lex->get_widget(), 0, 0 ); grid->add_widget( ley->get_widget(), 0, 1 ); grid->add_widget( lez->get_widget(), 0, 2 ); connect(lex,SIGNAL(floatLineEditValueChanged( float )),this,SLOT(emitSignal_x( float ))); connect(ley,SIGNAL(floatLineEditValueChanged( float )),this,SLOT(emitSignal_y( float ))); connect(lez,SIGNAL(floatLineEditValueChanged( float )),this,SLOT(emitSignal_z( float ))); connect(this,SIGNAL(SignalToChild_x( float )),lex, SLOT(setfloatLineEditValue( float))); connect(this,SIGNAL(SignalToChild_y( float )),ley, SLOT(setfloatLineEditValue( float))); connect(this,SIGNAL(SignalToChild_z( float )),lez, SLOT(setfloatLineEditValue( float))); } void floatLineBox3D::setfloatLineBox3DValue( float xval, float yval, float zval ) { xcache=xval; ycache=yval; zcache=zval; emit SignalToChild_x( xval ); emit SignalToChild_y( yval ); emit SignalToChild_z( zval ); } void floatLineBox3D::emitSignal_x( float newvalue ) {xcache=newvalue; emit floatLineBox3DValueChanged(newvalue,ycache,zcache);} void floatLineBox3D::emitSignal_y( float newvalue ) {ycache=newvalue; emit floatLineBox3DValueChanged(xcache,newvalue,zcache);} void floatLineBox3D::emitSignal_z( float newvalue ) {zcache=newvalue; emit floatLineBox3DValueChanged(xcache,ycache,newvalue);} floatLineBox3D::~floatLineBox3D(){ delete lex; delete ley; delete lez; delete grid; } odin-1.8.5/odinqt/stringbox.cpp0000644000175000017500000000204511322062347013421 00000000000000#include "stringbox.h" stringBox::stringBox(const char* text,QWidget *parent, const char *name, const char *buttontext ) : QGroupBox(name,parent) { unsigned int ncol=1; if(buttontext) ncol++; grid=new GuiGridLayout( this, 1, ncol); le = new GuiLineEdit(this, this, SLOT(reportTextChanged())); grid->add_widget( le->get_widget(), 0, 0 ); // Create a push button pb=0; if(buttontext) { pb = new GuiButton( this, this, SLOT(reportButtonClicked()), buttontext ); grid->add_widget( pb->get_widget(), 0, 1, GuiGridLayout::VCenter ); } setstringBoxText(text); } void stringBox::reportButtonClicked() { emit stringBoxButtonPressed(); } void stringBox::reportTextChanged() { if(le->is_modified()) { emit stringBoxTextEntered(le->get_text()); } } void stringBox::setstringBoxText( const char* text ) { Log odinlog("stringBox","setstringBoxText"); ODINLOG(odinlog,normalDebug) << "text=" << text << STD_endl; le->set_text(text); } stringBox::~stringBox() { if(pb) delete pb; delete le; delete grid; } odin-1.8.5/odinqt/odinqt.h0000644000175000017500000003452411363773557012375 00000000000000/*************************************************************************** odinqt.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINQT_H #define ODINQT_H #include #include #include // for svector // global configuration #define _FONT_TYPE_ "helvetica" #define _ARRAY_WIDGET_WIDTH_ 270 #define _ARRAY_WIDGET_HEIGHT_ 180 #define _ARRAY_BACKGROUND_COLOR_ "Black" #define _ARRAY_FOREGROUND_COLOR1_ "White" #define _ARRAY_FOREGROUND_COLOR2_ "Grey" #define _ARRAY_GRID_COLOR_ "Green" #define _ARRAY_GRID_DARK_FACTOR_ 250 #define _ARRAY_SELECTION_COLOR_ "Yellow" #define _ARRAY_HIGHLIGHT_COLOR_ "Orange" #define _ARRAY_MARKER_COLOR_ "Blue" #define _ARRAY_MARKER_BRIGHT_FACTOR_ 180 #define _LAYOUT_STRETCH_FACTOR_ 1 #define SLIDER_CELL_WIDTH 75 #define SLIDER_CELL_HEIGHT 25 #define TEXTEDIT_WIDTH 75 #define TEXTEDIT_HEIGHT 25 #define PLOT_SYMBOLS_SIZE 5 // platform-specific configuration #ifdef USING_WIN32 #define _FONT_SIZE_ 8 #else #define _FONT_SIZE_ 10 #endif ///////////////////////////////////////////////// // forward declarations class QObject; class QWidget; class QString; class QGridLayout; class QPushButton; class QLineEdit; class QPopupMenu; class QMenu; class QKeySequence; class QPoint; class QSlider; class QComboBox; class QLabel; class QPainter; class QPixmap; class QMouseEvent; class QColor; class QString; class QRegion; class QApplication; class QScrollView; class QScrollArea; class QDialog; class QMainWindow; class QProgressDialog; class QImage; class QListView; class QListViewItem; class QCheckListItem; class QTableWidget; class QTableWidgetItem; class QTreeWidget; class QTreeWidgetItem; class QProgressBar; class QScrollBar; class QToolBar; class QToolButton; class QPrinter; class QPaintDevice; class QWizard; class QTextEdit; class QTextView; class SlotDispatcher; ///////////////////////////////////////////////// /** * Helper classfor debugging the OdinQt component */ class OdinQt { public: static const char* get_compName(); }; ///////////////////////////////////////////////// // Helper functions for Qt portability const char* c_str(const QString& qs); int layout_border_size(); void init_label(QLabel* ql); bool left_button(const QMouseEvent* qme, bool return_current_state); bool right_button(const QMouseEvent* qme, bool return_current_state); bool middle_button(const QMouseEvent* qme, bool return_current_state); void add_tooltip(QWidget* w, const char* txt); void set_platform_defaults(QWidget* w, bool enable=true); STD_string get_save_filename(const char* caption=0, const char* startwith="", const char* filter="", QWidget* parent=0); STD_string get_open_filename(const char* caption=0, const char* startwith="", const char* filter="", QWidget* parent=0); STD_string get_directory(const char* caption=0, const char* startwith="", QWidget* parent=0); bool message_question(const char* text, const char* caption, QWidget* parent, bool ask=false, bool error=false); int paintdevice_height(const QPaintDevice* qpd); int paintdevice_width(const QPaintDevice* qpd); svector get_possible_image_fileformats(); ///////////////////////////////////////////////// // Helper classes for Qt portability /** * Abstraction of a grid layout */ class GuiGridLayout { public: GuiGridLayout(QWidget *parent, int rows, int columns, bool margin=true); ~GuiGridLayout(); enum Alignment {Default, VCenter, Center}; void add_widget(QWidget *w, int row, int column, Alignment alignment=Default, int rowSpan=1, int columnSpan=1 ); void set_col_stretch(int col, int factor); void set_row_stretch(int row, int factor); void set_col_minsize(int col, int minsize); void set_row_minsize(int row, int minsize); private: QGridLayout* qgl; }; ///////////////////////////////////////////////// /** * Abstraction of a push button */ class GuiButton { public: GuiButton(QWidget *parent, QObject* receiver, const char* member, const char *onlabel, const char *offlabel=0, bool initstate=false); ~GuiButton(); void set_toggled(bool state); void set_text(bool state); void set_default(bool state); bool is_on() const; QWidget* get_widget(); private: friend class SlotDispatcher; QPushButton* qpb; SlotDispatcher* sd; const char* ontext; const char* offtext; }; ///////////////////////////////////////////////// /** * Abstraction of a text editing field */ class GuiLineEdit { public: GuiLineEdit(QWidget *parent, QObject* receiver, const char* member, int width=-1, int height=-1); ~GuiLineEdit(); void set_text(const char* txt); const char* get_text() const; bool is_modified(); QWidget* get_widget(); private: friend class SlotDispatcher; QLineEdit* qle; SlotDispatcher* sd; }; ///////////////////////////////////////////////// /** * Abstraction of a popup menu */ class GuiPopupMenu { public: GuiPopupMenu(QWidget *parent); ~GuiPopupMenu(); void insert_item(const char* text, const QObject* receiver, const char* member, int accel=0); void insert_separator(); void popup(const QPoint& p); private: friend class GuiMainWindow; QPopupMenu* qpm; // for Qt pre4 QMenu* qm; // for Qt4 int id; }; ///////////////////////////////////////////////// /** * Abstraction of a slider */ class GuiSlider { public: GuiSlider(QWidget *parent, int minValue, int maxValue, int pageStep, int value, int tickInterval); ~GuiSlider(); int get_value() const; void set_value(int val); bool modified_externally() const {bool result=modified; modified=false; return result;} QSlider* get_widget() {return qs;} private: QSlider* qs; mutable bool modified; }; ///////////////////////////////////////////////// class GuiToolBar; // forward declarion /** * Abstraction of a combo box */ class GuiComboBox { public: GuiComboBox(QWidget* parent, const svector& names); GuiComboBox(GuiToolBar* parent, const svector& names); ~GuiComboBox(); void set_names(const svector& names); void set_current_item(int index); int get_current_item() const; QComboBox* get_widget() {return qcb;} private: void common_init(QWidget* parent, const svector& names); QComboBox* qcb; }; ///////////////////////////////////////////////// /** * Abstraction of a painter */ class GuiPainter { public: GuiPainter(QPixmap* qpm); ~GuiPainter(); // forwarding functions to QPainter void moveTo(int x, int y); void lineTo(int x, int y); bool begin(QPixmap* qpm); bool end(); void setPen(const char* pencolor, int linewidth=1, bool dotted=false, float lightdark=0.0); void fillRect( int x, int y, int w, int h, const QColor& col); void drawRect(int x, int y, int w, int h); void drawText( int x, int y, const QString& txt, const QColor& col); QRegion* draw_region(const STD_list& plist); QPainter* get_painter() {return qp;} void repaint(QLabel* dst); private: QPainter* qp; QPixmap* qpm_cache; int x_cache, y_cache; }; ///////////////////////////////////////////////// /** * Abstraction of a GUI application */ class GuiApplication { public: GuiApplication(int argc=0, char *argv[]=0); ~GuiApplication(); int start(QWidget* mainwidget); QObject* get_object(); static void quit(); static int argc(); static char** argv(); static void process_events(); private: QApplication* qa; // Cache cmdline args separately for Qt and for later use static int argc_cache; static char** argv_cache; static int argc4qt; static char** argv4qt; }; ///////////////////////////////////////////////// /** * Abstraction of a GUI main window */ class GuiMainWindow { public: GuiMainWindow(QWidget* parent = 0); ~GuiMainWindow(); void show(QWidget* central_widget, bool show_toolbutton_text=false); void set_caption(const char* text); void set_status_message(const char* text, int timeout_ms=0); void set_status_xpm(const char** xpm); QWidget* get_widget(); void insert_menu( const char* text, GuiPopupMenu * gpm); void insert_menu_separator(); void close(); private: friend class GuiToolBar; QMainWindow* qmw; QLabel* statusIcon; QLabel* statusText; }; ///////////////////////////////////////////////// /** * Abstraction of a scrollable window/area */ class GuiScroll { public: GuiScroll(QWidget* child, QWidget* parent); ~GuiScroll(); QWidget* get_widget(); private: QScrollView* qsv; // for Qt pre4 QScrollArea* qsa; // for Qt4 }; ///////////////////////////////////////////////// class QDialogDerived; // to overload paintEvent /** * Abstraction of a dialog */ class GuiDialog { public: GuiDialog(QWidget *parent, const char* caption, bool modal=false); virtual ~GuiDialog(); QWidget* get_widget(); virtual void repaint() {} // overload to repaint dialog virtual void close() {} // overload to perform additional stuff when closing dialog void show(); void cancel(); void done(); void hide(); int exec(); private: QDialogDerived* qd; }; ///////////////////////////////////////////////// /** * Abstraction of a progress dialog */ class GuiProgressDialog { public: GuiProgressDialog(QWidget *parent, bool modal, int total_steps); ~GuiProgressDialog(); void set_progress(int progr); int get_progress() const; void set_total_steps(int steps); bool was_cancelled() const; void reset(); void set_text(const char* txt); void show(); void hide(); private: QProgressDialog* qpd; }; ///////////////////////////////////////////////// /** * Abstraction of an image class */ class GuiImage { public: GuiImage(unsigned char* data, int width, int height, bool colormap); ~GuiImage(); QPixmap* create_pixmap() const; private: QImage* qi; }; ///////////////////////////////////////////////// class GuiListItem; // forward declaration class GuiListViewCallback { public: virtual void clicked(GuiListItem* item) = 0; protected: GuiListViewCallback() {} }; /** * Abstraction of a list/tree view class */ class GuiListView { public: GuiListView(QWidget *parent, const svector& column_labels, int first_column_width=-1, int min_height=-1, GuiListViewCallback* callback=0, bool tree=false); ~GuiListView(); QWidget* get_widget(); private: friend class GuiListItem; QListView* qlv; // for Qt pre4 QTableWidget* qtw; // for Qt4 QTreeWidget* qtrw; // for Qt4 SlotDispatcher* sd; }; ///////////////////////////////////////////////// /** * Abstraction of a list/tree view item */ class GuiListItem : public StaticHandler { public: GuiListItem() {common_init();} // used for constructing listmap GuiListItem(GuiListView *parent, const svector& column_entries, bool checkable=false, bool initstate=false); GuiListItem(GuiListItem *parent, GuiListItem *after, const svector& column_entries); ~GuiListItem(); bool is_checked() const; const char* get_text() const; // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); private: friend class SlotDispatcher; void common_init(); QListViewItem* qlvi; // for Qt pre4 QCheckListItem* qcli; // for Qt pre4 QTableWidgetItem* qtwi; // for Qt4 QTreeWidgetItem* qtrwi; // for Qt4 QTreeWidget* parent_qtrw; // for Qt4 // global map to retrieve GuiListItem from QListViewItem static STD_map* listmap; // for Qt pre4 static STD_map* tablemap; // for Qt4 }; ///////////////////////////////////////////////// /** * Abstraction of a progress bar */ class GuiProgressBar { public: GuiProgressBar(QWidget *parent, int total_steps); ~GuiProgressBar(); void set_progress(int progr); void set_min_width(int w); QWidget* get_widget(); private: QProgressBar* qpb; }; ///////////////////////////////////////////////// /** * Abstraction of a scroll bar */ class GuiScrollBar { public: GuiScrollBar(QWidget* parent); ~GuiScrollBar(); void set_values(int min, int max, int linestep, int pagestep, int value); QScrollBar* get_widget(); private: QScrollBar* qsb; }; ///////////////////////////////////////////////// /** * Abstraction of a tool bar */ class GuiToolBar { public: GuiToolBar(GuiMainWindow* parent, const char* label); ~GuiToolBar(); QWidget* get_widget(); void add_separator(); private: friend class GuiToolButton; friend class GuiComboBox; QToolBar* qtb; }; ///////////////////////////////////////////////// /** * Abstraction of a tool button */ class GuiToolButton { public: GuiToolButton(GuiToolBar* parent, const char** xpm, const char* label, QObject* receiver, const char* member, bool checkable=false, bool initstate=false ); ~GuiToolButton(); bool is_on() const; void set_on(bool flag); void set_enabled(bool flag); void set_label(const char* text); void set_tooltip(const char* text); private: friend class SlotDispatcher; QToolButton* qtb; SlotDispatcher* sd; }; ///////////////////////////////////////////////// /** * Abstraction of a printer driver */ class GuiPrinter { public: GuiPrinter(); ~GuiPrinter(); bool setup(QWidget* parent); QPaintDevice* get_device(); private: QPrinter* qp; }; ///////////////////////////////////////////////// /** * Abstraction of a text viewer */ class GuiTextView { public: GuiTextView(QWidget* parent, int minwidth, int minheight); ~GuiTextView(); void set_text(const char* txt); void append_text(const char* txt); QWidget* get_widget(); private: void scroll_end(); QTextEdit* qte; }; #endif odin-1.8.5/odinseq/0000755000175000017500000000000011735135551011127 500000000000000odin-1.8.5/odinseq/seqacqread.h0000644000175000017500000001011011455553540013323 00000000000000/*************************************************************************** seqacqread.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQREAD_H #define SEQACQREAD_H #include #include #include #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Acquisition + readout gradient * * This class represents an acquisition window with a read gradient. */ class SeqAcqRead : public virtual SeqAcqInterface, public SeqParallel { // virtual functions of SeqFreqChanInterface are marhshalled to acq public: /** * Constructs an acquisition window with a simultaneous read gradient labeled 'object_label' and the * following properties: * - sweepwidth: The sampling frequency * - read_size: The desired matrix size in read direction * - fov: The Field of View * - gradchannel: The channel where the read gradient will be placed * - os_factor: See class 'SeqAcq' for explanation * - partial_fourier: The amount of partial Fourier undersampling (0=no undersampling, 1=half fourier) * - partial_fourier_at_end: If set to 'true', partial Fourier will omit data at the end of the readout * - nucleus: See class 'SeqAcq' for explanation * - phaselist: See class 'SeqAcq' for explanation * - freqlist: See class 'SeqAcq' for explanation * - timestep: The time resolution for the digitised ramps, the default is to * take minimum time step the scanner is capable of. * - rampmode: This parameter determines the shape of the ramp waveform */ SeqAcqRead(const STD_string& object_label,double sweepwidth,unsigned int read_size, float fov, direction gradchannel, float os_factor=1.0, float partial_fourier=0.0, bool partial_fourier_at_end=false, const STD_string& nucleus="", const dvector& phaselist=0, const dvector& freqlist=0, float timestep = 0.0, rampType rampmode = linear); /** * Constructs an acquisition window with read gradient which is a copy of 'sar' */ SeqAcqRead(const SeqAcqRead& sar); /** * Constructs an empty acquisition window with read gradient with the given label. */ SeqAcqRead(const STD_string& object_label="unnamedSeqAcqRead"); /** * This assignment operator will make this object become an exact copy of 'sar'. */ SeqAcqRead& operator = (const SeqAcqRead& sar); /** * Returns reference to read gradient. */ const SeqGradTrapez& get_readgrad() const {return read;} // marshalling virtual functions of SeqAcqInterface to acq, except: double get_acquisition_center() const; double get_acquisition_start() const; SeqAcqInterface& set_sweepwidth(double sw, float os_factor); // produce warning private: friend class SeqGradEcho; // overloaded for SeqAcqDeph const SeqVector* get_dephgrad(SeqGradChanParallel& dephobj, bool rephase) const; void build_seq(); void common_init(); float corrected_partfour; // helper during construction SeqAcq acq; SeqGradTrapez read; SeqDelay middelay; SeqGradDelay midgrad; SeqDelay tozero; SeqGradTrapez readdephgrad; SeqGradTrapez readrephgrad; }; /** @} */ #endif odin-1.8.5/odinseq/seqplot.h0000644000175000017500000001657311363773555012734 00000000000000/*************************************************************************** seqplot.h - description ------------------- begin : Sat Sep 25 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPLOT_H #define SEQPLOT_H #include // for units class RotMatrix; // forward declaration /** * @addtogroup odinseq_internals * @{ */ enum plotChannel {B1re_plotchan=0, B1im_plotchan, rec_plotchan, signal_plotchan, freq_plotchan, phase_plotchan, Gread_plotchan, Gphase_plotchan, Gslice_plotchan, numof_plotchan}; enum markType {no_marker=0, exttrigger_marker, halttrigger_marker, snapshot_marker, reset_marker, acquisition_marker, endacq_marker, excitation_marker, refocusing_marker, storeMagn_marker, recallMagn_marker, inversion_marker, saturation_marker, numof_markers }; static const char* markLabel[]={"none", "exttrigger", "halttrigger", "snapshot", "reset", "acquisition", "endacq", "excitation", "refocusing", "storeMagn", "recallMagn", "inversion", "saturation" }; enum timecourseMode {tcmode_curves=0, tcmode_plain, tcmode_slew_rate, tcmode_kspace, tcmode_M1, tcmode_M2, tcmode_b_trace, tcmode_backgr_kspace, tcmode_backgr_crossterm, tcmode_eddy_currents, numof_tcmodes}; static const char* timecourseLabel[]= {"Curves", "Plain", "Slew Rate", "k-Space", "1st Grad. Moment", "2nd Grad. Moment", "b-Value Trace", "Backgr. k-Space", "Backgr. Crossterm", "Eddy Currents"}; static const char* timecoursePrefix[]={"G", "G", "dG", "k", "M1", "M2", "b", "k", "c", "G"}; static const char* timecourseUnit[]= {ODIN_GRAD_UNIT, ODIN_GRAD_UNIT, ODIN_GRAD_UNIT"/"ODIN_TIME_UNIT, "rad/"ODIN_SPAT_UNIT, "rad*"ODIN_TIME_UNIT"/"ODIN_SPAT_UNIT, "rad*"ODIN_TIME_UNIT"^2/"ODIN_SPAT_UNIT, ODIN_TIME_UNIT"/"ODIN_SPAT_UNIT"^2", "rad/"ODIN_SPAT_UNIT, ODIN_TIME_UNIT"/"ODIN_SPAT_UNIT"^2", ODIN_GRAD_UNIT}; //////////////////////////////////////////////////////////////////// /** * Special data structure suitable to display a single curve in QwtPlot */ struct Curve4Qwt { Curve4Qwt() : size(0), x(0), y(0), spikes(false), has_freq_phase(false), gradmatrix(0) {} bool operator == (const Curve4Qwt&) const {return false;} // dummy operator bool operator < (const Curve4Qwt&) const {return false;} // dummy operator double get_bounds(bool endpoint) const {if(!size) return 0.0; if(endpoint) return x[size-1]; else return x[0];} const char* label; plotChannel channel; int size; double* x; double* y; bool spikes; // values will not be interpolated between points, draw sticks instead bool has_freq_phase; double freq; double phase; const RotMatrix* gradmatrix; }; //////////////////////////////////////////////////////////////////// /** * Special data structure suitable to display a simple marker in QwtPlot */ struct Marker4Qwt { bool operator == (const Marker4Qwt&) const {return false;} // dummy operator bool operator < (const Marker4Qwt&) const {return false;} // dummy operator double get_bounds(bool) const {return x;} const char* label; double x; markType type; }; //////////////////////////////////////////////////////////////////// /** * Special data structure suitable to display a marker with stored values in QwtPlot */ struct TimecourseMarker4Qwt { bool operator == (const TimecourseMarker4Qwt&) const {return false;} // dummy operator bool operator < (const TimecourseMarker4Qwt&) const {return false;} // dummy operator double get_bounds(bool) const {return x;} double x; double y[numof_plotchan]; markType type; }; //////////////////////////////////////////////////////////////////// /** * Special data structure suitable to hold digitized timecourses */ struct SeqTimecourseData { SeqTimecourseData() : size(0), x(0), n_rec_points(0) {for(int i=0; i::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime, double max_highres_interval ) const = 0; virtual void get_signal_curves(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const = 0; virtual void get_markers(STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const = 0; virtual bool timecourse_created(timecourseMode type) const = 0; virtual bool create_timecourses(timecourseMode type, const STD_string& nucleus, ProgressMeter* progmeter) const = 0; virtual const SeqTimecourseData* get_timecourse(timecourseMode type) const = 0; virtual const SeqTimecourseData* get_subtimecourse(timecourseMode type, double starttime, double endtime) const = 0; virtual void get_timecourse_markers(timecourseMode type, STD_list::const_iterator& result_begin, STD_list::const_iterator& result_end, double starttime, double endtime ) const = 0; virtual double get_total_duration() const = 0; virtual unsigned int n_frames() const = 0; virtual JcampDxBlock& get_opts(bool timecourse_opts, bool simulation_opts) const = 0; virtual void set_coilsdir(const STD_string& coilsdir) const = 0; virtual void add_signal_curve(const Curve4Qwt& signal_curve) const = 0; virtual bool monitor_simulation() const = 0; virtual bool simulate(const STD_string& fidfile, const STD_string& samplefile, ProgressMeter* progmeter, SeqSimFeedbackAbstract* feedback) const = 0; virtual bool has_curves_on_channel(plotChannel chan) const = 0; }; /** @} */ #endif odin-1.8.5/odinseq/seqpuls.h0000644000175000017500000003166611322062345012720 00000000000000/*************************************************************************** seqpuls.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPULS_H #define SEQPULS_H #include #include #include #include #define _MAX_PULSE_ATTENUATION_ 120.0 /** * @ingroup odinseq * Enum to specify the type of a pulse.It is essential for the calculation of k-space trajectories * and other stuff to specify this correctly for each object derived from 'SeqPulsInterface' * - excitation: An excitation pulse. * - refocusing: A refocusing pulse. * - storeMagn: Stores the magnetization in longitudinal direction (stimulated echo) * - recallMagn: Recalls the magnetization from the longitudinal direction (stimulated echo) * - inversion: An inversion pulse * - saturation: A saturation pulse */ enum pulseType {excitation=0, refocusing, storeMagn, recallMagn, inversion, saturation, numof_pulseTypes}; static const char* pulseTypeLabel[]={"excitation", "refocusing","storeMagn","recallMagn","inversion","saturation"}; /////////////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This is the abstract base class for all objects that have the * property of a generating an RF field */ class SeqPulsInterface : public virtual SeqTreeObj, public virtual SeqFreqChanInterface { public: /** * Sets the duration of the pulse. In case of a more complex pulse * that needs some extra commands before and after the actual pulse * will be played out, this function still sets the effective * duration, i.e. when the RF-field is non-zero */ virtual SeqPulsInterface& set_pulsduration(float pulsduration) {if(marshall) marshall->set_pulsduration(pulsduration); else marshall_error(); return *this;} /** * Returns the duration of the pulse. In case of a more complex pulse * that needs some extra commands before and after the actual pulse * will be played out, this function still returns the effective * duration, i.e. when the RF-field is applied */ virtual double get_pulsduration() const {if(marshall) return marshall->get_pulsduration(); else marshall_error(); return 0.0;} /** * Returns the flip angle of the pulse */ virtual float get_flipangle() const {if(marshall) return marshall->get_flipangle(); else marshall_error(); return 0.0;} /** * Sets the flip angle of the pulse */ virtual SeqPulsInterface& set_flipangle(float flipangle) {if(marshall) marshall->set_flipangle(flipangle); else marshall_error(); return *this;} /** * Sets a list of flip angles which can be iterated through by a loop * and the get_flipangle_vector() function */ SeqPulsInterface& set_flipangles(const fvector& flipangles); /** * Returns the list of actual flip angles which will be iterated * through by a loop in combination with the get_flipangle_vector() function */ fvector get_flipangles() const {return get_flipangle()*get_flipscales();} /** * Sets the power deposition (or pulse attenuation on Bruker) of the pulse */ virtual SeqPulsInterface& set_power(float pulspower) {if(marshall) marshall->set_power(pulspower); else marshall_error(); return *this;} /** * Returns the power deposition (or pulse attenuation on Bruker) of the pulse */ virtual float get_power() const {if(marshall) return marshall->get_power(); else marshall_error(); return 0.0;} /** * Sets the relative center of the pulse */ virtual SeqPulsInterface& set_rel_magnetic_center(float center) {if(marshall) marshall->set_rel_magnetic_center(center); else marshall_error(); return *this;} /** * Returns the relative center of the pulse */ virtual float get_rel_magnetic_center() const {if(marshall) return marshall->get_rel_magnetic_center(); else marshall_error(); return 0.0;} /** * Returns the absolute center of the pulse */ virtual float get_magnetic_center() const {if(marshall) return marshall->get_magnetic_center(); else marshall_error(); return 0.0;} /** * Sets the type of the pulse */ virtual SeqPulsInterface& set_pulse_type(pulseType type) {if(marshall) marshall->set_pulse_type(type); else marshall_error(); return *this;} /** * Returns the type of the pulse */ virtual pulseType get_pulse_type() const {if(marshall) return marshall->get_pulse_type(); else marshall_error(); return pulseType(0);} /** * Sets the reordering scheme of the flipangle vector */ virtual SeqPulsInterface& set_flipangle_reorder_scheme(reorderScheme scheme,unsigned int nsegments) {if(marshall) marshall->set_flipangle_reorder_scheme(scheme,nsegments); else marshall_error(); return *this;} /** * Returns a sequence vector to iterate over flipangles */ virtual const SeqVector& get_flipangle_vector() const {if(marshall) return marshall->get_flipangle_vector(); else marshall_error(); return get_dummyvec();} /** * Returns the reorder vector for flipangles */ virtual const SeqVector& get_flipangle_reorder_vector() const {if(marshall) return marshall->get_flipangle_vector(); else marshall_error(); return get_dummyvec();} protected: SeqPulsInterface() : marshall(0) {} virtual ~SeqPulsInterface() {} virtual void set_flipscales(const fvector& flipscales) {if(marshall) marshall->set_flipscales(flipscales); else marshall_error();} virtual fvector get_flipscales() const {if(marshall) return marshall->get_flipscales(); else marshall_error(); return fvector();} void set_marshall(SeqPulsInterface* mymarshall) {marshall=mymarshall;} // to be used in constructor code private: SeqPulsInterface* marshall; // for marshalling member functions to a sub-object }; /////////////////////////////////////////////////////////////////////////////////////// class SeqPuls; // forward declaration /** * @ingroup odinseq_internals * A vector class to iterate through a list of flip angles, only to be used by SeqPuls */ class SeqFlipAngVector : public SeqVector { public: SeqFlipAngVector(const STD_string& object_label, SeqPuls* flipangvec_user ) : SeqVector(object_label), user(flipangvec_user) {} // overloading virtual functions from SeqVector unsigned int get_vectorsize() const {return flipanglescale.size();} bool needs_unrolling_check() const {return true;} bool prep_iteration() const; svector get_vector_commands(const STD_string& iterator) const; fvector flipanglescale; private: // disable copying SeqFlipAngVector(const SeqFlipAngVector&) {} SeqFlipAngVector& operator = (const SeqFlipAngVector&) {return *this;} SeqPuls* user; }; /////////////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of RF pulses */ class SeqPulsDriver : public SeqDriverBase { public: SeqPulsDriver() {} virtual ~SeqPulsDriver() {} virtual bool prep_driver(const cvector& wave, double pulsduration, double pulscenter, float b1max, float power, float flipangle, const fvector& flipscales, pulseType plstype) = 0; virtual void event(eventContext& context, double start) const = 0; virtual double get_rf_energy() const = 0; virtual bool prep_flipangle_iteration(unsigned int count) = 0; virtual double get_predelay() const = 0; virtual double get_postdelay() const = 0; virtual STD_string get_program(programContext& context, unsigned int phaselistindex, int channel, const STD_string& iteratorcommand) const = 0; virtual STD_string get_instr_label() const = 0; virtual svector get_flipvector_commands(const STD_string& iterator) const =0; // virtual svector get_phase_commands(const STD_string& iterator) const =0; virtual void new_freq(double newfreq) const = 0; virtual bool has_new_freq() const = 0; virtual SeqPulsDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * * \brief RF pulse * * This class represents a shaped RF-pulse with a complex waveform */ class SeqPuls : public virtual SeqPulsInterface, public SeqObjBase, public SeqFreqChan, public SeqDur { public: /** * Constructs a pulse labeled 'object_label' with the following properties: * - wave: The complex waveform that will be played out * - pulsduration: The duration of the pulse * - pulspower: The power of the pulse in dB * - nucleus: This parameter determines the frequency at which the pulse will * be played out to be the resonance frequency of the specified nucleus * - phaselist: This is an array of phases at which the acquired pulse will be * modulated. Use the get_phaselist_vector() function to attach it to a loop. * - freqlist: This is an array of frequency offsets at which the pulse waveform * will be modulated. * - rel_magnetic_center: This parameter specifies the point in time that will be used * as the center of the pulse for timing calculations, e.g. for a spin-echo */ SeqPuls(const STD_string& object_label,const cvector& waveform,float pulsduration, float pulspower, const STD_string& nucleus="",const dvector& phaselist=0, const dvector& freqlist=0,float rel_magnetic_center=0.5); /** * Constructs an empty pulse with the given label. */ SeqPuls(const STD_string& object_label = "unnamedSeqPuls"); /** * Constructs a pulse which is a copy of 'sp' */ SeqPuls(const SeqPuls& sp); /** * This assignment operator will make this pulse become an exact copy of 'sp'. */ SeqPuls& operator = (const SeqPuls& sp); /** * Sets the complex waveform of the pulse */ SeqPuls& set_wave(const cvector& waveform); /** * Returns the complex RF waveform */ cvector get_wave() const {return wave;} /** * Returns the time offset within this object where the RF starts */ double get_pulsstart() const {return pulsdriver->get_predelay();} // overloading virtual functions from SeqPulsInterface SeqPulsInterface& set_pulsduration(float pulsduration); double get_pulsduration() const; float get_flipangle() const {return system_flipangle;} SeqPulsInterface& set_flipangle(float flipangle) {return set_system_flipangle(flipangle);} float get_power() const {return power;} SeqPulsInterface& set_power(float pulspower) {power=pulspower; return *this;} SeqPulsInterface& set_rel_magnetic_center(float center) {relmagcent=center; return *this;} float get_rel_magnetic_center() const {return relmagcent;} float get_magnetic_center() const; SeqPulsInterface& set_pulse_type(pulseType type); pulseType get_pulse_type() const; const SeqVector& get_flipangle_vector() const {return flipvec;} void set_flipscales(const fvector& flipscales) {flipvec.flipanglescale=flipscales;} fvector get_flipscales() const {return flipvec.flipanglescale;} SeqPulsInterface& set_flipangle_reorder_scheme(reorderScheme scheme,unsigned int nsegments) {flipvec.set_reorder_scheme(scheme,nsegments); return *this;} const SeqVector& get_flipangle_reorder_vector() const {return flipvec.get_reorder_vector();} // overloading virtual function from SeqTreeObj double get_duration() const; STD_string get_program(programContext& context) const; double get_rf_energy() const; STD_string get_properties() const; unsigned int event(eventContext& context) const; SeqValList get_freqvallist(freqlistAction action) const; // some helper functions to use SeqPulse together with OdinPulse/Pulsar SeqPuls& set_system_flipangle(float angle); SeqPuls& set_B1max(float b1max); float get_B1max() const {return B1max_mT;} private: friend class SeqFlipAngVector; // overloading virtual functions from SeqFreqChan double get_freqchan_duration() const {return get_pulsduration();} STD_string get_driver_instr_label() const {return pulsdriver->get_instr_label();} // overwriting virtual functions from SeqClass bool prep(); mutable SeqDriverInterface pulsdriver; cvector wave; float power; float system_flipangle; float B1max_mT; float relmagcent; pulseType plstype; SeqFlipAngVector flipvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqobjvec.h0000644000175000017500000000732511322062345013200 00000000000000/*************************************************************************** seqobjvec.h - description ------------------- begin : Mon Aug 9 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQOBJVEC_H #define SEQOBJVEC_H #include #include class SeqGradObjInterface; // forward declaration /** * @ingroup odinseq * * \brief Vector to loop over sequence objects * * This vector class is used to iterate over a list of other sequence objects. * To make use of it, append other sequence objects to this via the += operator and use it together with a loop: * \verbatim SeqObjVector objvec; SeqPuls alpha; // excitation pulse SeqDelay delay; // delay objvec+=alpha; // put alpha into the vector objvec+=delay; // put delay into the vector SeqObjLoop loop; loop ( objvec ) [objvec]; // plays out alpha first and then delay \endverbatim * */ class SeqObjVector : public SeqVector, public SeqObjBase, public List { public: /** * Construct an empty vector of sequence objects with the given label */ SeqObjVector(const STD_string& object_label="unnamedSeqObjVector"); /** * Constructs a copy of 'sov' */ SeqObjVector(const SeqObjVector& sov); /** * Assignment operator that makes this sequence container become a copy of 'sov' */ SeqObjVector& operator = (const SeqObjVector& sov); /** * Appends soa to the list of elements in this vector of sequence objects */ SeqObjVector& operator += (const SeqObjBase& soa); /** * Appends sgoa to the list of elements in this vector of sequence objects */ SeqObjVector& operator += (SeqGradObjInterface& sgoa); /** * Appends sgcl to the list of elements in this vector of sequence objects */ SeqObjVector& operator += (SeqGradChanList& sgcl); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; unsigned int event(eventContext& context) const; void query(queryContext& context) const; RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; SeqValList get_freqvallist(freqlistAction action) const; SeqValList get_delayvallist() const; double get_rf_energy() const; // implemented virtual functions from SeqClass void clear_container(); // implemented virtual functions from SeqVector unsigned int get_vectorsize() const {return List::size();} bool needs_unrolling_check() const {return true;} bool is_obj_vector() const {return true;} bool is_acq_vector() const {return true;} // this vector may contain vectors which are relevant for acquisition bool is_qualvector() const {return true;} // timing may change private: constiter get_current() const; }; #endif odin-1.8.5/odinseq/seqgradvec.cpp0000644000175000017500000000714011322062345013671 00000000000000#include "seqgradvec.h" #include "seqgradconst.h" #include "seqloop.h" SeqGradVector::SeqGradVector(const STD_string& object_label,direction gradchannel, float maxgradstrength,const fvector& trimarray, double gradduration) : SeqGradChan(object_label,gradchannel,maxgradstrength,gradduration), SeqVector(object_label) { parent=0; set_trims(trimarray); } SeqGradVector::SeqGradVector(const SeqGradVector& sgv) { parent=0; SeqGradVector::operator = (sgv); } SeqGradVector::SeqGradVector(const STD_string& object_label) : SeqGradChan(object_label), SeqVector(object_label) { parent=0; } SeqGradVector& SeqGradVector::set_trims(const fvector& trims) { trimvals=trims; return *this; } unsigned int SeqGradVector::get_vectorsize() const {return trimvals.size();} svector SeqGradVector::get_vector_commands(const STD_string& iterator) const { return graddriver->get_vector_commands(iterator); } SeqGradVector& SeqGradVector::operator = (const SeqGradVector& sgv) { Log odinlog(this,"SeqGradVector::operator = "); SeqGradChan::operator = (sgv); SeqVector::operator = (sgv); trimvals=sgv.trimvals; return *this; } STD_string SeqGradVector::get_grdpart(float matrixfactor) const { Log odinlog(this,"get_grdpart"); ODINLOG(odinlog,normalDebug) << "matrixfactor=" << matrixfactor << STD_endl; if(parent) { ODINLOG(odinlog,normalDebug) << "has parent " << parent->get_label() << STD_endl; return parent->get_grdpart(matrixfactor); } if(SeqVector::is_handled()) { return graddriver->get_vector_program(get_strength(),matrixfactor,get_current_reord_index()); } return graddriver->get_const_program(get_current_strength(),matrixfactor); // Generate const-gradient entry if vector not handled (for Bruker) } float SeqGradVector::get_current_strength() const { unsigned int count=get_current_index(); if(parent) count=parent->get_current_index(); float trim=1.0; if(count odinlog(this,"prep"); if(!SeqGradChan::prep()) return false; bool result=graddriver->prep_vector(get_strength(),get_grdfactors_norot(),get_gradduration(),trimvals,get_index_matrix(),get_nesting_relation()); return result; } svector SeqGradVector::get_reord_vector_commands(const STD_string& iterator) const { Log odinlog(this,"get_reord_vector_commands"); svector result=SeqVector::get_reord_vector_commands(iterator); unsigned int result_size=result.size(); svector reordvec=graddriver->get_reord_commands(); ODINLOG(odinlog,normalDebug) << "reordvec=" << reordvec.printbody() << STD_endl; if(reordvec.size()) { if(!result_size) return reordvec; svector newresult; newresult.resize(result_size+reordvec.size()); unsigned int i; for(i=0; iset_label(STD_string(get_label())+"_("+ftos(starttime)+"-"+ftos(endtime)+")"); sgv->set_duration(endtime-starttime); sgv->set_temporary(); sgv->parent=this; return *sgv; } bool SeqGradVector::prep_iteration() const { Log odinlog(this,"prep_iteration"); int count=get_current_index(); if(parent) count=parent->get_current_index(); ODINLOG(odinlog,normalDebug) << "count/vectorsize=" << count << "/" << get_vectorsize() << STD_endl; return graddriver->prep_vector_iteration(count); } odin-1.8.5/odinseq/seqacqspiral.cpp0000644000175000017500000001345711322062345014245 00000000000000#include "seqacqspiral.h" void SeqAcqSpiral::common_init() { SeqAcqInterface::set_marshall(&acq); SeqFreqChanInterface::set_marshall(&acq); } SeqAcqSpiral::SeqAcqSpiral(const STD_string& object_label,double sweepwidth, float fov, unsigned int sizeRadial, unsigned int numofSegments, JDXtrajectory& traj, bool inout, bool optimize, const STD_string& nucleus, const dvector& phaselist) : SeqObjList(object_label), par(object_label+"_par"), spirgrad_in(object_label+"_spirgrad_in",traj,secureInv(sweepwidth),secureDivision(fov,sizeRadial),sizeRadial/(1+int(inout)),numofSegments/(1+int(inout)),true,optimize,nucleus), spirgrad_out(object_label+"_spirgrad_out",traj,secureInv(sweepwidth),secureDivision(fov,sizeRadial),sizeRadial/(1+int(inout)),numofSegments/(1+int(inout)),false,optimize,nucleus), preacq(object_label+"_preacq"), acq(object_label+"_acq", int(inout)*spirgrad_in.spiral_size()+spirgrad_out.spiral_size(), sweepwidth, 1.0, nucleus, phaselist), inout_traj(inout) { Log odinlog(this,"SeqAcqSpiral(...)"); common_init(); // set the rotation matrices for the spiral interleaves rotvec.set_label(STD_string(get_label())+"_rotvec"); unsigned int nrot=numofSegments; if(inout) nrot/=2; if(!nrot) nrot=1; rotvec.create_inplane_rotation(nrot); acq.set_rel_center(0.0); if(inout) acq.set_rel_center(0.5); gbalance=SeqGradTrapezParallel(object_label+"_gbalance", -spirgrad_in.get_gradintegral()[readDirection], -spirgrad_in.get_gradintegral()[phaseDirection], 0.0, 0.5*systemInfo->get_max_grad()); build_seq(); } SeqAcqSpiral::SeqAcqSpiral(const SeqAcqSpiral& sas) { common_init(); SeqAcqSpiral::operator = (sas); } SeqAcqSpiral::SeqAcqSpiral(const STD_string& object_label) : SeqObjList(object_label) { common_init(); } SeqAcqSpiral& SeqAcqSpiral::operator = (const SeqAcqSpiral& sas) { SeqObjList::operator = (sas); par=sas.par; spirgrad_in=sas.spirgrad_in; spirgrad_out=sas.spirgrad_out; preacq=sas.preacq; acq=sas.acq; gbalance=sas.gbalance; rotvec=sas.rotvec; inout_traj=sas.inout_traj; build_seq(); return *this; } fvector SeqAcqSpiral::get_ktraj(unsigned int iseg, direction channel) const { Log odinlog(this,"get_ktraj"); const RotMatrix& rotmatrix=rotvec[iseg]; ODINLOG(odinlog,normalDebug) << "rotmatrix=" << rotmatrix.print() << STD_endl; fvector kx_in(spirgrad_in.get_ktraj(readDirection)); fvector ky_in(spirgrad_in.get_ktraj(phaseDirection)); fvector kx_out(spirgrad_out.get_ktraj(readDirection)); fvector ky_out(spirgrad_out.get_ktraj(phaseDirection)); unsigned int size=kx_out.length(); if(inout_traj) size+=kx_in.length(); fvector result(size); dvector kvec(3); dvector kvec_rot(3); kvec=0; unsigned int offset=0; if(inout_traj) offset=kx_in.length(); for(unsigned int i=0; i odinlog(this,"get_denscomp"); fvector denscomp_in(spirgrad_in.get_denscomp()); fvector denscomp_out(spirgrad_out.get_denscomp()); unsigned int size=denscomp_out.length(); if(inout_traj) size+=denscomp_in.length(); fvector result(size); unsigned int offset=0; if(inout_traj) offset=denscomp_in.length(); for(unsigned int i=0; i odinlog(this,"set_sweepwidth"); ODINLOG(odinlog,warningLog) << "Ignoring request to change sweepwidth after construction" << STD_endl; return *this; } bool SeqAcqSpiral::prep() { Log odinlog(this,"prep"); if(!SeqObjList::prep()) return false; unsigned int acqsize= get_ktraj(0,readDirection).length(); unsigned int segsize=rotvec.get_vectorsize(); unsigned int gradsize=3; ODINLOG(odinlog,normalDebug) << "acqsize/segsize=" << acqsize << "/" << segsize << STD_endl; farray ktrajs(segsize,acqsize,gradsize); for(unsigned int iseg=0; iseg odinlog(this,"build_seq"); par.clear(); SeqObjList::clear(); double acqcent=par.get_pulprogduration()+acq.get_acquisition_start(); double shift=systemInfo->get_grad_shift_delay()-acqcent; if(inout_traj) shift += gbalance.get_gradduration()+spirgrad_in.get_ramp_duration(); ODINLOG(odinlog,normalDebug) << "acqcent/shift=" << acqcent << "/" << shift << STD_endl; if(shift>=systemInfo->get_min_duration(delayObj)) { ODINLOG(odinlog,normalDebug) << "acq is played out later, because gradient switching is delayed" << STD_endl; preacq.set_duration(shift); if(inout_traj) par /= (gbalance + spirgrad_in + spirgrad_out); else par /= spirgrad_out; par /= (preacq + acq); } else { ODINLOG(odinlog,normalDebug) << "gradients are played out later, because acq is delayed" << STD_endl; if(inout_traj) { par /= (gbalance + spirgrad_in + spirgrad_out); spirgrad_in.set_predelay_duration(-shift); } else { par /= spirgrad_out; spirgrad_out.set_predelay_duration(-shift); } par /= acq; } (*this)+=par; SeqObjList::set_gradrotmatrixvector(rotvec); } odin-1.8.5/odinseq/seqtree.h0000644000175000017500000002123611455553540012675 00000000000000/*************************************************************************** seqtree.h - description ------------------- begin : Fri Oct 17 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQTREE_H #define SEQTREE_H #include #include #include /** * @addtogroup odinseq_internals * @{ */ /////////////////////////////////////////////////////////////////////////// /** * Callback to display tree-like structures */ class SeqTreeCallbackAbstract { public: virtual void display_node(const SeqClass* thisnode, const SeqClass* parentnode, int treelevel, const svector& columntext) = 0; }; /////////////////////////////////////////////////////////////////////////// class ProgressMeter; // forward declaration /** * This enum is used to specify the behaviour for an event: * - seqRun: trigger the hardware events * - printEvent: Print all events to the console * - countEvents: Returns the number of events without actually executing them */ enum eventAction {seqRun=0, printEvent, countEvents}; /** * Structure that holds the context in which the event of a sequence object is requested */ struct eventContext { eventContext() : action(seqRun), noflush(false), seqcheck(false), elapsed(0.0), event_display(0), event_progmeter(0) {} // the action to be performed eventAction action; // do not flush eventblock bool noflush; // just a test run (e.g. fSEQCheck on Idea) bool seqcheck; // counter for time elapsed since start of the sequence double elapsed; // callback pointers to display events in GUI/console SeqTreeCallbackAbstract* event_display; // pointer for progess meter ProgressMeter* event_progmeter; }; /////////////////////////////////////////////////////////////////////////// /** * This enum is used to specify the behaviour for a call to get_freqvallist: * - calcDeps: Calculates dependencies between consecutive pulse frequency events * - calcList: Creates the gloabal pulse frequency list * - calcAcqList: Creates the gloabal acquisition frequency list * - calcDecList: Creates the gloabal decoupling frequency list */ enum freqlistAction {calcDeps=0,calcList,calcAcqList,calcDecList}; /////////////////////////////////////////////////////////////////////////// /** * This enum is used to specify the behaviour for program printing: * - brukerPpg: create Bruker pulse program * - brukerGpg: create Bruker gradient program * - brukerParx: create Bruker parx interface file (to set ACQP parameters) * - epicCode: Sequence source code for the EPIC framework * - epicPg: Code for the pulsegen section (EPIC) */ enum programMode {brukerPpg=0, brukerGpg, brukerParx, epicCode, epicPg, epicScan, epicPreScan, epicPreScanDummy, numOfProgModes}; /** * Structure that holds the context the sequence program is (recursively) generated with, i.e. type of program or formatting */ struct programContext { programContext() : mode(programMode(0)), formatted(true), nestlevel(0), neststatus(false) {} // the type of program to generate programMode mode; // whether code is nicely formatted (indention, comments), the main // use of this flag is to decide whether to blocks of code are the // same (despite formatting) and whether they can be wrapped in a loop bool formatted; // counter for indention if generating pulse programs int nestlevel; // whether indention is currently enabled bool neststatus; }; /////////////////////////////////////////////////////////////////////////// class SeqTreeObj; //forward declaration /** * This enum is used to specify the behaviour for a call to query: * - count_acqs: Count the number of acquisition objects * - checkoccur: Check the occurence of a particular sequence object in this branch of the tree * - check_acq_iter: Check for an iterator in subtree which is relevant for reco indicies * - tag_toplevel_reploop: Identify and tag outermost repetition loop * - display_tree: Display sequence tree */ enum queryAction {count_acqs, checkoccur, check_acq_iter, tag_toplevel_reploop, display_tree}; /** * Structure that holds the context the sequence tree is (recursively) queried with */ struct queryContext { queryContext() : action(count_acqs), numof_acqs(0), checkoccur_sto(0), checkoccur_result(false), check_acq_iter_result(false), tree_display(0), parentnode(0), treelevel(0), repetitions_prot(0) {} // the action requested queryAction action; // stuff for action 'count_acqs' unsigned int numof_acqs; // stuff for action 'checkoccur' const SeqTreeObj* checkoccur_sto; bool checkoccur_result; bool check_acq_iter_result; // stuff for action 'display_tree' SeqTreeCallbackAbstract* tree_display; const SeqTreeObj* parentnode; int treelevel; // stuff for action 'tag_toplevel_reploop' int repetitions_prot; // the number of reps in the protocol }; /////////////////////////////////////////////////////////////////////////// /** * Instantiation of value list (SeqValList) with double. * It is used in sequence trees to retrieve frequency lists, delay lists, etc. */ struct SeqValList : public ValList { SeqValList(const STD_string& object_label="unnamedSeqValList", unsigned int repetitions=1) : ValList(object_label,repetitions) {} }; /////////////////////////////////////////////////////////////////////////// /** * This is the base class for all objects that can be part of the sequence tree */ class SeqTreeObj : public virtual SeqClass { public: /** * Returns the duration of the sequence object. */ virtual double get_duration() const = 0; /** * Returns the part in the pulse/gradient program of this sequence object. * 'context' holds data about how the program should be generated, e.g. type * of program and formatting. */ virtual STD_string get_program(programContext& context) const {return "";} /** * Returns a string describing the object */ virtual STD_string get_properties() const {return "";} /** * Queries the sequence tree for events, returns the number of events executed */ virtual unsigned int event(eventContext& context) const { // make inline to speed up event execution if(context.action==printEvent) display_event(context); context.elapsed+=get_duration(); return 0; // no real hardware events played out } /** * Appends the k-space coordinates in this branch of the sequence tree to 'coords' * and returns their ordering */ virtual RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const {return RecoValList();} /** * Returns true if 'sto' can be found in the objects branch of the sequence tree */ bool contains(const SeqTreeObj* sto) const; /** * Generates a graphical representation of the sequence tree using 'display' */ void tree(SeqTreeCallbackAbstract* display) const; /** * Returns the list of frequency values in the objects branch of the sequence tree */ virtual SeqValList get_freqvallist(freqlistAction action) const {return SeqValList();} /** * Returns the list of delay values in the objects branch of the sequence tree */ virtual SeqValList get_delayvallist() const {return SeqValList();} /** * Returns the RF power deposition in the objects branch of the sequence tree. * The physical unit is unspecified, it depends on the current platform. */ virtual double get_rf_energy() const {return 0.0;} protected: friend class SeqObjList; friend class SeqObjVector; friend class SeqParallel; SeqTreeObj(); virtual ~SeqTreeObj() {} SeqTreeObj& operator = (const SeqTreeObj& sto) { SeqClass::operator =(sto); return *this; } /** * Query the sequence tree recursively */ virtual void query(queryContext& context) const; static int looplevel; private: void display_event(eventContext& context) const; }; /** @} */ #endif odin-1.8.5/odinseq/odinpulse_trajectories.cpp0000644000175000017500000002340011322062345016322 00000000000000#include "odinpulse.h" #include ///////////////////////////////////////////////////////////////////////// // 1D trajectories: class Const : public JDXfunctionPlugIn { JDXdouble lower; JDXdouble upper; public: Const() : JDXfunctionPlugIn("Const") { lower=0.0; lower.set_minmaxval(0.0,1.0); upper=1.0; upper.set_minmaxval(0.0,1.0); append_member(lower,"lowerBoundary"); append_member(upper,"upperBoundary"); set_description("A trajectory with a linear stepping in k-space (for slice-selective pulses) or in the time domain (for frequency-selective pulses)." "With the parameters lowerBoundary and upperBoundary, a subarea of the pulse can be specified."); } const kspace_coord& calculate_traj(float s) const { double l=lower; double u=upper; if( l <0.0 ) l=0.0; if( l >1.0 ) l=1.0; if( u <0.0 ) u=0.0; if( u >1.0 ) u=1.0; double offset=l; double slew=u-l; coord_retval.traj_s=offset+slew*s; coord_retval.kz = 2.0 * coord_retval.traj_s - 1.0; coord_retval.Gz = 2.0 * slew; coord_retval.denscomp = 1.0; return coord_retval; } const traj_info& get_traj_properties() const { double l=lower; double u=upper; if( l <0.0 ) l=0.0; if( l >1.0 ) l=1.0; if( u <0.0 ) u=0.0; if( u >1.0 ) u=1.0; traj_info_retval.rel_center=secureDivision((0.5-l),(u-l)); if(traj_info_retval.rel_center<0.0) traj_info_retval.rel_center=0.0; if(traj_info_retval.rel_center>1.0) traj_info_retval.rel_center=1.0; return traj_info_retval; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Const;} }; ///////////////////////////////////////////////////////////////////////// class Sinus : public JDXfunctionPlugIn { JDXint cycles; JDXfilter spectfilter; public: Sinus() : JDXfunctionPlugIn("Sinus"), spectfilter("spectfilter") { cycles=8; cycles.set_minmaxval(1,20); append_member(cycles,"NumPulses"); spectfilter.set_function(0); append_member(spectfilter,"SpectralFilter"); set_description("This is a trajectory with a sinus-shaped gradient waveform. The NumPulses\n" "parameter specifies the number of times the trajectory passes the k-space origin. This trajectory may be used for spectral-spatial\n" "selective pulses."); } const kspace_coord& calculate_traj(float s) const { coord_retval.traj_s=s; float phi = PII * float(cycles) * (s - 1.0); coord_retval.kz = -cos (phi); coord_retval.Gz = PII * cycles * sin (phi); coord_retval.denscomp = fabs(coord_retval.Gz) * spectfilter.calculate (fabs(s-0.5)*2.0); // Quick hack: Apply filter in spectral dimension via denscomp return coord_retval; } const traj_info& get_traj_properties() const { traj_info_retval.rel_center=1.0-1.0/(float(cycles)*2.0); return traj_info_retval; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Sinus;} }; ///////////////////////////////////////////////////////////////////////// // 2D trajectories: // Base class for all Archimedian spirals, c.f. Block and Frahm, JMRI 21:657-668(2005) class ArchimedianSpiral : public JDXfunctionPlugIn { JDXint cycles; virtual void calc_theta(float& theta, float& dtheta, float s) const = 0; public: ArchimedianSpiral(const STD_string& label) : JDXfunctionPlugIn(label) { cycles=16; cycles.set_minmaxval(1,64); append_member(cycles,"NumCycles"); } const kspace_coord& calculate_traj(float s) const { coord_retval.traj_s=s; float theta, dtheta; calc_theta(theta, dtheta, s); float phi = -2.0 * PII * (float)cycles * theta; float dphi = -2.0 * PII * (float)cycles * dtheta; coord_retval.kx = theta * cos (phi); coord_retval.ky = theta * sin (phi); coord_retval.Gx = dtheta * cos (phi) - theta * sin (phi) * dphi; coord_retval.Gy = dtheta * sin (phi) + theta * cos (phi) * dphi; coord_retval.denscomp = fabs(phi*dphi); //radius / sqrt (phi * phi + 1.0); return coord_retval; } const traj_info& get_traj_properties() const { traj_info_retval.rel_center=1.0; traj_info_retval.max_kspace_step=secureInv(2.0*cycles); return traj_info_retval; } }; /////////////////////////////////////////////////////////////////////////// class ConstSpiral : public ArchimedianSpiral { public: ConstSpiral() : ArchimedianSpiral("ConstSpiral") { set_description("An Archimedian spiral where the radius increases linearly with time."); } // implementing virtual function of ArchimedianSpiral void calc_theta(float& theta, float& dtheta, float s) const { // Spiral is out->in theta=1.0-s; dtheta=-1.0; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new ConstSpiral;} }; ///////////////////////////////////////////////////////////////////////// class WrapSpiral : public ArchimedianSpiral { JDXfloat switchpoint; public: WrapSpiral() : ArchimedianSpiral("WrapSpiral") { switchpoint=0.5; switchpoint.set_minmaxval(0.0,1.0); append_member(switchpoint,_TRAJ_OPTIMIZE_PARLABEL_); set_description("An Archimedian spiral.\n" "In the inner part of k-space the radius increases linerly with time,\n" "while in the outer part the distance between adjacent sampling points along the\n" "trajectory in k-space is kept constant.\n" "The "_TRAJ_OPTIMIZE_PARLABEL_" parameter determines the relative point in time (between\n" "0.0 and 1.0) where the switching between these two modes occurs."); } // implementing virtual function of ArchimedianSpiral void calc_theta(float& theta, float& dtheta, float s) const { if (s < switchpoint) { // const sampling density theta = sqrt (1.0 - 2.0 * s / (switchpoint + 1.0)); dtheta = -1.0 / ((switchpoint + 1.0) * theta); } else { // const spiral if(switchpoint>=1.0) { // take radius/dradius of const spiral theta = 1.0-s; dtheta = -1.0; } else { float denominator=sqrt (1.0 - switchpoint*switchpoint); theta = secureDivision(1.0-s, denominator); dtheta = secureDivision(-1.0, denominator); } } } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new WrapSpiral;} }; ///////////////////////////////////////////////////////////////////////// class BoernertSpiral : public ArchimedianSpiral { JDXfloat alpha; public: BoernertSpiral() : ArchimedianSpiral("BoernertSpiral") { alpha=0.5; alpha.set_minmaxval(0.0,1.0); append_member(alpha,_TRAJ_OPTIMIZE_PARLABEL_); set_description("An Archimedian spiral as described in Boernert et al, MAGMA 9:29-41(1999)."); } // implementing virtual function of ArchimedianSpiral void calc_theta(float& theta, float& dtheta, float s) const { float f=1.0-s; float df=-1.0; float g=sqrt(alpha+(1.0-alpha)*(1.0-s)); float dg=secureDivision(alpha-1.0, 2.0*g); theta=secureDivision(f,g); dtheta=secureDivision(df*g-f*dg,g*g); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new BoernertSpiral;} }; ///////////////////////////////////////////////////////////////////////// class SegmentedRotation : public JDXfunctionPlugIn { JDXtrajectory Trajectory; JDXint Segment; JDXint Nsegments; mutable kspace_coord tds; // mutable -> member function calculate_traj defined as const mutable traj_info ti; RotMatrix rot_matrix; float deltaphi; mutable dvector vec; mutable dvector rot_vec; public: SegmentedRotation() : JDXfunctionPlugIn("SegmentedRotation") { Nsegments=8; Nsegments.set_minmaxval(1,30); Segment=1; Segment.set_minmaxval(1,30); vec.resize(3); rot_vec.resize(3); append_member(Trajectory,"Trajectory"); append_member(Nsegments,"NumSegments"); append_member(Segment,"CurrSegment"); set_description("This is a segmented trajectory, which can be used to rotate the other 2D-trajectories."); Trajectory.set_function_mode(twoDeeMode); } void init_trajectory(OdinPulse* pls=0) { if (Nsegments < 1) Nsegments = 1; if (Segment >= Nsegments) Segment = int (Nsegments); if (Segment < 1) Segment = 1; Trajectory.init_trajectory(pls); float phi= float(Segment-1) * 2.0 * PII / float(Nsegments); rot_matrix.set_inplane_rotation(phi); } const kspace_coord& calculate_traj(float s) const { tds=Trajectory.calculate(s); vec[0]=tds.kx; vec[1]=tds.ky; vec[2]=0.0; rot_vec=rot_matrix*vec; tds.kx=rot_vec[0]; tds.ky=rot_vec[1]; tds.kz=0.0; // calculate gradient vector vec[0]=tds.Gx; vec[1]=tds.Gy; vec[2]=0.0; rot_vec=rot_matrix*vec; tds.Gx=rot_vec[0]; tds.Gy=rot_vec[1]; tds.Gz=0.0; return tds; } const traj_info& get_traj_properties() const { ti=Trajectory.get_traj_info(); ti.max_kspace_step/=float(Nsegments); return ti; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new SegmentedRotation;} }; ///////////////////////////////////////////////////////////////////////// // allocating plugins void JDXtrajectory::init_static() { (new Const)->register_function(trajFunc,zeroDeeMode).register_function(trajFunc,oneDeeMode); (new Sinus)->register_function(trajFunc,oneDeeMode); (new ConstSpiral)->register_function(trajFunc,twoDeeMode); (new WrapSpiral)->register_function(trajFunc,twoDeeMode); (new BoernertSpiral)->register_function(trajFunc,twoDeeMode); (new SegmentedRotation)->register_function(trajFunc,twoDeeMode); } void JDXtrajectory::destroy_static() { // pulgins will be deleted by JDXfunction } EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/odinseq/seqveciter.h0000644000175000017500000000473111455553540013400 00000000000000/*************************************************************************** seqveciter.h - description ------------------- begin : Fri Jan 19 2007 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQVECITER_H #define SEQVECITER_H #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Iterator for vectors * * Iterator to step manually through vectors. * Each occurence of this iterator in the sequence tree will * increment actual value of the vector by one. If the end of * the vector is reached, iteration starts again at the beginning, * i.e. the iteration is cyclical. * Use add_vector() to append vectors which should be controlled * by this iterator. */ class SeqVecIter : public SeqCounter, public SeqObjBase { public: /** * Construct an empty iterator with the given label. * Iteration will start at index 'start'. */ SeqVecIter(const STD_string& object_label = "unnamedSeqVecIter", unsigned int start=0); /** * Copy constructor */ SeqVecIter(const SeqVecIter& svi); /** * Assignment operator */ SeqVecIter& operator = (const SeqVecIter& svi); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; unsigned int event(eventContext& context) const; STD_string get_properties() const; void query(queryContext& context) const; RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; private: bool is_acq_iterator() const; // overwriting virtual functions from SeqClass bool prep(); unsigned int startindex; }; /** @} */ #endif odin-1.8.5/odinseq/seqgradecho.cpp0000644000175000017500000002245111455553540014045 00000000000000#include "seqgradecho.h" void SeqGradEcho::common_init(const STD_string& objlabel) { SeqAcqInterface::set_marshall(&acqread); SeqFreqChanInterface::set_marshall(&acqread); postexcpart.set_label(objlabel+"_postexcpart"); postacqpart.set_label(objlabel+"_postacqpart"); phasesim.set_label(objlabel+"_phasesim"); phasesim3d.set_label(objlabel+"_phasesim3d"); phasereordsim.set_label(objlabel+"_phasereordsim"); midpart.set_label(objlabel+"_midpart"); mode=slicepack; balanced_grads=false; } SeqGradEcho::SeqGradEcho(const STD_string& object_label, SeqPulsar& exc, double sweepwidth, unsigned int readnpts, float FOVread, unsigned int phasenpts, float FOVphase, encodingScheme scheme, reorderScheme reorder, unsigned int nsegments, unsigned int reduction, unsigned int acl_bands, bool balanced, float partial_fourier_phase, float partial_fourier_read, bool partial_fourier_read_at_end, float os_factor, const STD_string& nucleus) : SeqObjList(object_label), pls_reph(object_label+"_exc_reph",exc), acqread(object_label+"_acqread", sweepwidth, readnpts, FOVread, readDirection, os_factor, partial_fourier_read, partial_fourier_read_at_end, nucleus) { Log odinlog(this,"SeqGradEcho"); common_init(object_label); mode=slicepack; balanced_grads=balanced; pulsptr.set_handled(&exc); // use duration of on-ramp and constant part of pls_reph as duration of constant part of the other trapezoids double constdur=pls_reph.get_constgrad_duration()+pls_reph.get_onramp_duration(); // use SeqGradPhaseEnc to initialize phase encoding SeqGradPhaseEnc pedummy(object_label+"_phase", phasenpts, FOVphase, constdur, phaseDirection, scheme, reorder, nsegments, reduction, acl_bands, partial_fourier_phase, nucleus); phase=pedummy.vectorgrad; if(balanced_grads) { phase_rew=phase; phase_rew.set_label("phase_rew"); phase_rew.invert_strength(); } // the same for read-dephase float readdeph_strengh=secureDivision(acqread.readdephgrad.get_integral(),constdur); readdeph=SeqGradConst(object_label+"_readdeph",acqread.read.get_channel(),readdeph_strengh,constdur); build_seq(); } SeqGradEcho::SeqGradEcho(const STD_string& object_label, unsigned int readnpts, float FOVread, unsigned int phasenpts, float FOVphase, unsigned int slicenpts, float FOVslice, SeqPulsar& exc, double sweepwidth, unsigned int reduction, unsigned int acl_bands, bool balanced, float partial_fourier_phase, float partial_fourier_read, bool partial_fourier_read_at_end, float os_factor, const STD_string& nucleus) : SeqObjList(object_label), pls_reph(object_label+"_exc_reph",exc), acqread(object_label+"_acqread", sweepwidth, readnpts, FOVread, readDirection, os_factor, partial_fourier_read, partial_fourier_read_at_end, nucleus) { Log odinlog(this,"SeqGradEcho"); common_init(object_label); mode=voxel_3d; balanced_grads=balanced; pulsptr.set_handled(&exc); // use duration of on-ramp and constant part of pls_reph as duration of constant part of the other trapezoids double constdur=pls_reph.get_constgrad_duration()+pls_reph.get_onramp_duration(); // use SeqGradPhaseEnc to initialize phase encoding SeqGradPhaseEnc pedummy(object_label+"_phase", phasenpts, FOVphase, constdur, phaseDirection, linearEncoding, noReorder, 1, reduction, acl_bands, partial_fourier_phase, nucleus); phase=pedummy.vectorgrad; // use SeqGradPhaseEnc to initialize phase encoding SeqGradPhaseEnc pedummy3d(object_label+"_phase3d", slicenpts, FOVslice, constdur, sliceDirection, linearEncoding, noReorder, 1, reduction, acl_bands, 0.0, nucleus); phase3d=pedummy3d.vectorgrad; // Merge slice rephaser and 2nd phase encoding float integral_phase3d=phase3d.get_strength()*phase3d.get_gradduration(); float integral_reph=pls_reph.get_gradintegral()[sliceDirection]; fvector integrals_slice = phase3d.get_trims()*integral_phase3d + integral_reph; ODINLOG(odinlog,normalDebug) << "integrals_slice=" << integrals_slice << STD_endl; float maxabsintegral_slice=integrals_slice.maxabs(); float strength_slice=secureDivision(maxabsintegral_slice, constdur); fvector trims_slice(integrals_slice/maxabsintegral_slice); phase3d=SeqGradVector("phase3d", sliceDirection, strength_slice, trims_slice, constdur); if(balanced_grads) { phase_rew=phase; phase_rew.set_label("phase_rew"); phase_rew.invert_strength(); phase3d_rew=phase3d; phase3d_rew.set_label("phase3d_rew"); phase3d_rew.invert_strength(); } // the same for read-dephase float readdeph_strengh=secureDivision(acqread.readdephgrad.get_integral(),constdur); readdeph=SeqGradConst(object_label+"_readdeph",acqread.read.get_channel(),readdeph_strengh,constdur); build_seq(); } SeqGradEcho::SeqGradEcho(const STD_string& object_label) : SeqObjList(object_label) { common_init(object_label); } SeqGradEcho::SeqGradEcho(const SeqGradEcho& sge) { SeqGradEcho::operator = (sge); common_init(sge.get_label()); } SeqGradEcho& SeqGradEcho::operator = (const SeqGradEcho& sge) { SeqObjList::operator = (sge); pulsptr=sge.pulsptr; pls_reph=sge.pls_reph; phase=sge.phase; phase3d=sge.phase3d; phase_rew=sge.phase_rew; phase3d_rew=sge.phase3d_rew; acqread=sge.acqread; readdeph=sge.readdeph; midpart=sge.midpart; mode=sge.mode; balanced_grads=sge.balanced_grads; build_seq(); return *this; } SeqGradEcho& SeqGradEcho::set_pe_reorder_scheme(reorderScheme scheme,unsigned int nsegments) { phase.set_reorder_scheme(scheme,nsegments); if(balanced_grads) phase_rew.set_reorder_scheme(scheme,nsegments); return *this; } SeqVector& SeqGradEcho::get_pe_vector() { if(balanced_grads) return phasesim; return phase; } SeqVector& SeqGradEcho::get_pe3d_vector() { if(balanced_grads) return phasesim3d; return phase3d; } const SeqVector& SeqGradEcho::get_pe_reorder_vector() const { if(balanced_grads) return phasereordsim; return phase.get_reorder_vector(); } double SeqGradEcho::get_echo_time() const { Log odinlog(this,"get_echo_time"); double result=0.0; if(pulsptr.get_handled()) { double magcenter=(pulsptr.get_handled()->get_duration()) - (pulsptr.get_handled()->get_magnetic_center()); ODINLOG(odinlog,normalDebug) << "magcenter=" << magcenter << STD_endl; result+=magcenter; } double middur=midpart.get_duration(); double postexcdur=postexcpart.get_duration(); double acqcenter=acqread.get_acquisition_center(); ODINLOG(odinlog,normalDebug) << "middur/postexcdur/acqcenter=" << middur << "/" << postexcdur << "/" << acqcenter << STD_endl; result += middur + postexcdur + acqcenter; return result; } SeqGradEcho& SeqGradEcho::set_midpart(const SeqObjBase& soa) { midpart=soa; build_seq(); // Has to be re-built so that objects of midpart are copied to this return *this; } SeqAcqInterface& SeqGradEcho::set_template_type(templateType type) { acqread.set_template_type(type); if(type==phasecorr_template) phase.set_strength(0.0); return *this; } double SeqGradEcho::get_preacq() const { double result=0.0; if(pulsptr.get_handled()) result+=pulsptr.get_handled()->get_duration(); result+=midpart.get_duration(); result+=postexcpart.get_duration(); return result; } SeqGradInterface& SeqGradEcho::set_gradrotmatrix(const RotMatrix& matrix) { if(pulsptr.get_handled()) pulsptr.get_handled()->set_gradrotmatrix(matrix); postexcpart.set_gradrotmatrix(matrix); acqread.set_gradrotmatrix(matrix); postacqpart.set_gradrotmatrix(matrix); return *this; } SeqGradInterface& SeqGradEcho::invert_strength() { if(pulsptr.get_handled()) pulsptr.get_handled()->invert_strength(); postexcpart.invert_strength(); acqread.invert_strength(); postacqpart.invert_strength(); return *this; } fvector SeqGradEcho::get_gradintegral() const { fvector result(3); result=0.0; if(pulsptr.get_handled()) result+=pulsptr.get_handled()->get_gradintegral(); result+=postexcpart.get_gradintegral(); result+=acqread.get_gradintegral(); result+=postacqpart.get_gradintegral(); return result; } void SeqGradEcho::build_seq() { Log odinlog(this,"build_seq"); clear(); postexcpart.clear(); postacqpart.clear(); phasesim.clear(); phasesim3d.clear(); phasereordsim.clear(); if(balanced_grads) { phasesim+=phase; phasesim+=phase_rew; phasereordsim+=phase.get_reorder_vector(); phasereordsim+=phase_rew.get_reorder_vector(); if(mode==voxel_3d) { phasesim3d+=phase3d; phasesim3d+=phase3d_rew; } } if(mode==voxel_3d) { postexcpart /= phase3d / phase / readdeph ; if(balanced_grads) postacqpart /= phase3d_rew / phase_rew / readdeph ; } else { postexcpart /= pls_reph / phase / readdeph ; if(balanced_grads) postacqpart /= pls_reph / phase_rew / readdeph ; } if(pulsptr.get_handled()) { (*this)+=(*pulsptr.get_handled()) + midpart + postexcpart + acqread; if(balanced_grads) (*this) += postacqpart; } else { ODINLOG(odinlog,warningLog) << "No pulse specified for gradient echo module" << STD_endl; } // reco stuff acqread.set_reco_vector(line,phase); if(mode==voxel_3d) acqread.set_reco_vector(line3d,phase3d); if(pulsptr.get_handled()) acqread.set_reco_vector(slice,*pulsptr.get_handled()); } odin-1.8.5/odinseq/seqdelayvec.cpp0000644000175000017500000000352711322062345014057 00000000000000#include "seqdelayvec.h" SeqDelayVector::SeqDelayVector(const STD_string& object_label,const dvector& delaylist) : SeqObjBase(object_label), SeqVector(object_label), delayvecdriver(object_label), delayvec(delaylist) { } SeqDelayVector::SeqDelayVector(const STD_string& object_label) : SeqObjBase(object_label), SeqVector(object_label), delayvecdriver(object_label) { } SeqDelayVector::SeqDelayVector(const SeqDelayVector& sdv) { SeqDelayVector::operator = (sdv); } SeqDelayVector& SeqDelayVector::operator = (const SeqDelayVector& sdv) { SeqObjBase::operator = (sdv); SeqVector::operator = (sdv); delayvecdriver=sdv.delayvecdriver; delayvec=sdv.delayvec; return *this; } SeqDelayVector& SeqDelayVector::set_delayvector(const dvector& delays) { delayvec=delays; return *this; } dvector SeqDelayVector::get_delayvector() const {return delayvec;} double SeqDelayVector::get_duration() const { double result=systemInfo->get_min_duration(delayObj); double value=0.0; if(get_vectorsize()) { value=delayvec[get_current_index()]; } if(value>result) result=value; return result; } STD_string SeqDelayVector::get_program(programContext& context) const { Log odinlog(this,"get_program"); double delaydur=0.0; if(get_vectorsize()) { delaydur=delayvec[get_current_index()]; } ODINLOG(odinlog,normalDebug) << "context.mode/delaydur=" << context.mode << "/" << delaydur << STD_endl; return delayvecdriver->get_program(context,delaydur); } SeqValList SeqDelayVector::get_delayvallist() const { Log odinlog(this,"get_delayvallist"); SeqValList result(get_label()); result.set_value(get_duration()); return result; } unsigned int SeqDelayVector::get_vectorsize() const {return delayvec.size();} bool SeqDelayVector::prep() { if(!SeqObjBase::prep()) return false; return delayvecdriver->prep_driver(); } odin-1.8.5/odinseq/00seqtest.cpp0000644000175000017500000000432111322062345013373 00000000000000#include "seqall.h" #ifdef ODIN_DEBUG int seqtestfunc() { SeqGradConst constgrad; SeqGradConstPulse constgradpulse; SeqPulsar pulsar; SeqObjList list; SeqDelay delay; SeqObjLoop loop; SeqDecoupling dec; SeqGradEcho grech; SeqAcqEPI epi; SeqAcqSpiral spiral; SeqDiffWeight dw; SeqSat sat; SeqFieldMap fmap; // Testing + operator constgrad + constgrad; constgrad + constgradpulse; constgrad + pulsar; constgrad + list; constgrad + delay; constgrad + loop; constgrad + dec; constgradpulse + constgrad; constgradpulse + constgradpulse; constgradpulse + pulsar; constgradpulse + list; constgradpulse + delay; constgradpulse + loop; constgradpulse + dec; pulsar + constgrad; pulsar + constgradpulse; pulsar + pulsar; pulsar + list; pulsar + delay; pulsar + loop; pulsar + dec; list + constgrad; list + constgradpulse; list + pulsar; list + list; list + delay; list + loop; list + dec; delay + constgrad; delay + constgradpulse; delay + pulsar; delay + list; delay + delay; delay + loop; delay + dec; loop + constgrad; loop + constgradpulse; loop + pulsar; loop + list; loop + delay; loop + loop; loop + dec; dec + constgrad; dec + constgradpulse; dec + pulsar; dec + list; dec + delay; dec + loop; dec + dec; // Testing / operator constgrad / constgrad; constgrad / constgradpulse; constgrad / list; constgrad / delay; constgrad / loop; constgrad / dec; constgradpulse / constgrad; constgradpulse / constgradpulse; constgradpulse / list; constgradpulse / delay; constgradpulse / loop; constgradpulse / dec; list / constgrad; list / constgradpulse; delay / constgrad; delay / constgradpulse; loop / constgrad; loop / constgradpulse; dec / constgrad; dec / constgradpulse; // Testing += operator list += constgrad; list += constgradpulse; list += pulsar; list += list; list += delay; list += loop; list += dec; constgradpulse += constgrad; constgradpulse += constgradpulse; // Testing = operator list = constgrad; list = constgradpulse; list = pulsar; list = list; list = delay; list = loop; list = dec; return 0; } #endif odin-1.8.5/odinseq/seqrotmatrixvector.h0000644000175000017500000000670311322062345015203 00000000000000/*************************************************************************** seqrotmatrixvector.h - description ------------------- begin : Wed Jul 30 2003 copyright : (C) 2003 by Thies H. Jochimsen and Michael v. Mengershausen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQROTMATRIXVECTOR_H #define SEQROTMATRIXVECTOR_H #include class SeqGradChanList; // forward declaration /** * @ingroup odinseq * * \brief Vector of SeqRotMatrix's * * This class keeps an arry of rotation matrices. * It can be used consecutively by a gradient object within a loop * via the function SeqObjList::set_gradrotmatrixvector(). */ class SeqRotMatrixVector : public SeqVector, public Handled { public: /** * default constructor */ SeqRotMatrixVector(const STD_string& object_label = "unnamedSeqRotMatrixVector"); /** * constructs a rot-matrix vector from an existing rot-matrix vector */ SeqRotMatrixVector(const SeqRotMatrixVector& srmv); /** * Destructor */ ~SeqRotMatrixVector(); /** * assignment operator */ SeqRotMatrixVector& operator = (const SeqRotMatrixVector& srmv); /** * returns the index'th matrix */ const RotMatrix& operator [] (unsigned long index) const; /** * returns the currently active matrix when used inside a loop */ const RotMatrix& get_current_matrix () const; /** * Makes this a vector of 'nsegments' matrices that * rotate the first and second dimension (read, phase) with * a constant angle increment of 2*PI/nsegments. */ SeqRotMatrixVector& create_inplane_rotation(unsigned int nsegments); /** * clears the list of rotation matrices */ SeqRotMatrixVector& clear() { rotMatrixList.clear(); return *this; }; /** * adds a new rotation matrix at the end of the vector */ SeqRotMatrixVector& append(const RotMatrix& srm) { // srm.check_and_correct(); rotMatrixList.push_back(srm); return *this; }; /** * returns values with max. absolute values for each element of the matrix vector */ RotMatrix get_maxMatrix () const; // implemented virtual from SeqVector unsigned int get_vectorsize() const {return rotMatrixList.size();}; bool needs_unrolling_check() const {return get_vectorsize()>1;} bool is_qualvector() const {return false;} bool prep_iteration() const; svector get_vector_commands(const STD_string& iterator) const {iterator_cache=iterator; return svector();} // return stored iterator, quick hack for EPIC rotmats const STD_string& get_iterator() const {return iterator_cache;} private: friend class SeqGradChan; mutable STD_string iterator_cache; STD_list rotMatrixList; RotMatrix dummyrotmat; }; #endif odin-1.8.5/odinseq/seqrotmatrixvector.cpp0000644000175000017500000000442411322062345015534 00000000000000#include "seqrotmatrixvector.h" #include "seqloop.h" #include "seqgradchan.h" #include SeqRotMatrixVector::SeqRotMatrixVector(const STD_string& object_label): SeqVector(object_label){ Log odinlog(this,"SeqRotMatrixVector(const STD_string&)"); set_label(object_label); } SeqRotMatrixVector::SeqRotMatrixVector(const SeqRotMatrixVector& srmv) { Log odinlog(this,"SeqRotMatrixVector(SeqRotMatrixVector)"); SeqRotMatrixVector::operator = (srmv); } SeqRotMatrixVector& SeqRotMatrixVector::operator = (const SeqRotMatrixVector& srmv){ Log odinlog(this,"operator ="); SeqVector::operator = (srmv); rotMatrixList=srmv.rotMatrixList; return *this; }; SeqRotMatrixVector::~SeqRotMatrixVector() { Log odinlog(this,"~SeqRotMatrixVector"); } const RotMatrix& SeqRotMatrixVector::operator [] (unsigned long index) const{ unsigned long i=0; STD_list::const_iterator it; for ( it=rotMatrixList.begin(); it !=rotMatrixList.end();++it){ if(i==index) return *it; i++; } return dummyrotmat; }; const RotMatrix& SeqRotMatrixVector::get_current_matrix () const{ if(get_vectorsize()) return (*this)[get_current_index()]; return dummyrotmat; } SeqRotMatrixVector& SeqRotMatrixVector::create_inplane_rotation(unsigned int nsegments) { Log odinlog(this,"create_inplane_rotation"); clear(); for(unsigned int i=0; i; odin-1.8.5/odinseq/seqphase.h0000644000175000017500000000641511322062345013027 00000000000000/*************************************************************************** seqphase.h - description ------------------- begin : Sun Apr 4 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPHASE_H #define SEQPHASE_H #include #include #include /////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of phase lists */ class SeqPhaseDriver : public SeqDriverBase { public: SeqPhaseDriver() {} virtual ~SeqPhaseDriver() {} virtual void prep_driver(const dvector& phaselist) = 0; virtual unsigned int get_phaselistindex(const dvector& phaselist) const = 0; virtual STD_string get_loopcommand(const dvector& phaselist) const = 0; virtual svector get_phasevec_commands(const STD_string& iterator, const STD_string& instr) const = 0; virtual SeqPhaseDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////////// class SeqFreqChan; // forward declaration /** * @ingroup odinseq_internals * A vector class for managing phase lists */ class SeqPhaseListVector : public SeqVector, public virtual SeqClass { private: //make everything private so that only SeqFreqChan can use it SeqPhaseListVector(const STD_string& object_label = "unnamedSeqPhaseListVector", const dvector& phase_list=0 ); SeqPhaseListVector(const SeqPhaseListVector& spl); SeqPhaseListVector& operator = (const SeqPhaseListVector& spl); /** * Specifies the phaselist */ SeqPhaseListVector& set_phaselist(const dvector& pl); /** * Returns the phaselist */ dvector get_phaselist() const {return phaselist;} /** * Return the index for the phaselist */ unsigned int get_phaselistindex() const; /** * Returns the current phase in deg */ double get_phase() const; // overloaded functions of SeqVector unsigned int get_vectorsize() const {return phaselist.size();} STD_string get_loopcommand() const; svector get_vector_commands(const STD_string& iterator) const; bool prep_iteration() const; bool is_qualvector() const {return false;} private: friend class SeqFreqChan; // overwriting virtual functions from SeqClass bool prep(); // the hardware driver mutable SeqDriverInterface phasedriver; dvector phaselist; // in deg // the frequency object in which this object is embedded SeqFreqChan* user; }; #endif odin-1.8.5/odinseq/seqsimvec.cpp0000644000175000017500000001276611322062345013556 00000000000000#include "seqsimvec.h" SeqSimultanVector::SeqSimultanVector(const SeqSimultanVector& ssv) { SeqSimultanVector::operator = (ssv); } SeqSimultanVector& SeqSimultanVector::operator = (const SeqSimultanVector& ssv) { SeqVector::operator = (ssv); SeqClass::operator = (ssv); List::operator = (ssv); return *this; } SeqSimultanVector& SeqSimultanVector::operator += (const SeqVector& sv) { Log odinlog(this,"+="); if(&sv==this) ODINLOG(odinlog,errorLog) << "refusing to manage myself" << STD_endl; else { append(sv); sv.simhandler.set_handled(this); } return *this; } svector SeqSimultanVector::get_vector_commands(const STD_string& iterator) const { Log odinlog(this,"get_vector_commands"); STD_list labels; STD_list::const_iterator veciter; // using local iterator because member functions may be nested for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { svector veclabels=(*veciter)->get_vector_commands(iterator); for(unsigned int i=0; i::const_iterator it=labels.begin(); it!=labels.end(); ++it) { result[index]=*it; index++; } return result; } unsigned int SeqSimultanVector::get_vectorsize() const { Log odinlog(this,"get_vectorsize"); unsigned int result=0; STD_list::const_iterator veciter; // using local iterator because member functions may be nested if(size()) { result=(*get_const_begin())->get_vectorsize(); for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->get_vectorsize()!=result) ODINLOG(odinlog,errorLog) << "vector size mismatch" << STD_endl; } } return result; } unsigned int SeqSimultanVector::get_numof_iterations() const { Log odinlog(this,"get_numof_iterations"); unsigned int result=0; STD_list::const_iterator veciter; // using local iterator because member functions may be nested if(size()) { result=(*get_const_begin())->get_numof_iterations(); for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->get_numof_iterations()!=result) ODINLOG(odinlog,errorLog) << "numof_iterations mismatch" << STD_endl; } } return result; } STD_string SeqSimultanVector::get_loopcommand() const { Log odinlog(this,"get_loopcommand"); STD_string result; STD_list::const_iterator veciter; // using local iterator because member functions may be nested if(size()) { result=(*get_const_begin())->get_loopcommand(); for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->get_loopcommand()!=result) ODINLOG(odinlog,errorLog) << "loopcommand mismatch" << STD_endl; } } return result; } nestingRelation SeqSimultanVector::get_nesting_relation() const { Log odinlog(this,"get_nesting_relation"); nestingRelation result=noRelation; STD_list::const_iterator veciter; // using local iterator because member functions may be nested if(size()) { result=(*get_const_begin())->get_nesting_relation(); for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->get_nesting_relation()!=result) ODINLOG(odinlog,errorLog) << "nesting_relation mismatch" << STD_endl; } } return result; } bool SeqSimultanVector::needs_unrolling_check() const { Log odinlog(this,"needs_unrolling_check"); bool result=false; STD_list::const_iterator veciter; // using local iterator because member functions may be nested for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->needs_unrolling_check()) result=true; } return result; } bool SeqSimultanVector::prep_iteration() const { Log odinlog(this,"prep_iteration"); bool result=true; ODINLOG(odinlog,normalDebug) << "managing " << size() << " vectors" << STD_endl; STD_list::const_iterator veciter; // using local iterator because member functions may be nested for(veciter=get_const_begin(); veciter!=get_const_end(); ++veciter) { ODINLOG(odinlog,normalDebug) << "prep_iteration of " << (*veciter)->get_label() << STD_endl; if(!(*veciter)->prep_iteration()) { ODINLOG(odinlog,errorLog) << (*veciter)->get_label() << ".prep_iteration() failed" << STD_endl; return false; } } return result; } /* bool SeqSimultanVector::is_acq_vector() const { Log odinlog(this,"SeqSimultanVector::is_acq_vector"); return SeqVector::is_acq_vector(); } */ const SeqVector& SeqSimultanVector::set_vechandler(const SeqCounter* sc) const { Log odinlog(this,"set_vechandler"); SeqVector::set_vechandler(sc); STD_list::const_iterator veciter; // using local iterator because member functions may be nested for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { (*veciter)->set_vechandler(sc); } return *this; } bool SeqSimultanVector::is_qualvector() const { Log odinlog(this,"is_qualvector"); STD_list::const_iterator veciter; // using local iterator because member functions may be nested for(veciter=get_const_begin();veciter!=get_const_end();++veciter) { if((*veciter)->is_qualvector()) return true; } return false; } void SeqSimultanVector::clear_container() { List::clear(); } odin-1.8.5/odinseq/seqcmdline.h0000644000175000017500000000423611322062345013341 00000000000000/*************************************************************************** seqcmdline.h - description ------------------- begin : Tue Jan 18 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQCMDLINE_H #define SEQCMDLINE_H #include #define USAGE_INDENTION_FACTOR 2 ///////////////////////////////////////////////////////// #ifdef NO_CMDLINE struct SeqCmdlineActionList {}; // dummy class #else struct SeqCmdlineAction { SeqCmdlineAction(const STD_string& act, const STD_string& descr) : action(act), description(descr) {} void add_req_arg(const STD_string& opt, const STD_string& descr) {req_args[opt]=descr;} void add_opt_arg(const STD_string& opt, const STD_string& descr) {opt_args[opt]=descr;} STD_string action; STD_string description; STD_map req_args; STD_map opt_args; }; typedef STD_list SeqCmdlineActionList; #endif ///////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Helper class to deal with command line arguments */ class SeqCmdLine : public SeqClass { public: static int process(int argc, char *argv[]); static STD_string format_actions(const SeqCmdlineActionList& actions); private: static STD_string usage(const STD_string& meth, const STD_string& description); }; #endif odin-1.8.5/odinseq/seqdriver.cpp0000644000175000017500000000442111322062345013550 00000000000000#include "seqdriver.h" #include "seqplatform.h" #ifdef PARAVISION_PLUGIN #include "../platforms/Paravision/odinseq_paravision/seqparavision.h" #endif #ifdef IDEA_PLUGIN #include "../platforms/IDEA_n4/odinseq_idea/seqidea.h" #endif #ifdef STANDALONE_PLUGIN #include "../platforms/StandAlone/odinseq_standalone/seqstandalone.h" #endif #ifdef EPIC_PLUGIN #include "../platforms/EPIC/odinseq_epic/seqepic.h" #endif ///////////////////////////////////////////////////////////////////// SeqPlatformInstances::SeqPlatformInstances() { Log odinlog("SeqPlatformInstances","SeqPlatformInstances"); PlatformRegistration da; int i; for(i=0; i #include "seqdiffweight.h" #include "seqgradchanparallel.h" float* get_dti_dirarr(unsigned int ndir); // forward declaration void calc_dw_grads(fvector& gradtrims, double& delta, const fvector& bvals, float maxgradstrength, float middur, float gamma) { Log odinlog("SeqDiffWeight","calc_grads"); float maxbval=bvals.maxabs(); // solve cubic equation for delta double a=3.0/2.0*middur; double c=-3.0/2.0*secureDivision(maxbval,gamma*gamma*maxgradstrength*maxgradstrength); ODINLOG(odinlog,normalDebug) << "a/c=" << a << "/" << c << STD_endl; double x0=0.0; double x1=0.0; double x2=0.0; int nroots=solve_cubic (a,0.0,c,&x0,&x1,&x2); ODINLOG(odinlog,normalDebug) << "nroots/x0/x1/x2=" << nroots << "/" << x0 << "/" << x1 << "/" << x2 << STD_endl; delta=maxof3(x0,x1,x2); ODINLOG(odinlog,normalDebug) << "delta=" << delta << STD_endl; unsigned int ntrims=bvals.length(); gradtrims.resize(ntrims); for(unsigned int i=0; i odinlog(this,"SeqDiffWeight(...)"); middle_part=midpart; fvector gradtrims1; double delta; calc_dw_grads(gradtrims1, delta, bvals, maxgradstrength, middle_part.get_duration(), systemInfo->get_gamma(nucleus)); fvector gradtrims2(gradtrims1); if(!stejskalTanner) gradtrims2=-gradtrims1; // reset for(int idim=0; idim odinlog(this,"SeqDiffWeight(...)"); float* arr=get_dti_dirarr(ndir); if(!arr) { ODINLOG(odinlog,errorLog) << "array not available for ndir=" << ndir << STD_endl; return; } middle_part=midpart; STD_list blist[n_directions]; unsigned int idim; // single declaration for MSVC6 for(idim=0; idim=baseline_rep && idir<(ndir-1)) { repcounter=0; for(idim=0; idimget_gamma(nucleus)); fvector gradtrims2(gradtrims1); if(!stejskalTanner) gradtrims2=-gradtrims1; ODINLOG(odinlog,normalDebug) << "gradtrims1[" << idim << "]=" << gradtrims1 << STD_endl; ODINLOG(odinlog,normalDebug) << "gradtrims2[" << idim << "]=" << gradtrims2 << STD_endl; pfg1[idim]=SeqGradVectorPulse(object_label+"_pfg1_"+directionLabel[idim],direction(idim),maxgradstrength,gradtrims1,delta); pfg2[idim]=SeqGradVectorPulse(object_label+"_pfg2_"+directionLabel[idim],direction(idim),maxgradstrength,gradtrims2,delta); } build_seq(); } SeqDiffWeight::SeqDiffWeight(const STD_string& object_label ) : SeqObjList(object_label), SeqSimultanVector(object_label) { } SeqDiffWeight& SeqDiffWeight::operator = (const SeqDiffWeight& sgdw) { SeqSimultanVector::operator = (sgdw); SeqObjList::operator = (sgdw); for(int idim=0; idimset_temporary(); SeqGradChanParallel* sgcp2=new SeqGradChanParallel(get_label()+"_sgcp2"); sgcp2->set_temporary(); SeqSimultanVector::clear(); for(int idim=0; idim odinlog(this,"SeqDiffWeightFlowComp()"); fvector gradtrims; double delta; calc_dw_grads(gradtrims, delta, 0.5*bvals, maxgradstrength, 0.0, systemInfo->get_gamma(nucleus)); pfg1=SeqGradVectorPulse(object_label+"_pfg1",chan,maxgradstrength, gradtrims,delta); pfg2=SeqGradVectorPulse(object_label+"_pfg2",chan,-maxgradstrength,gradtrims,2.0*delta); pfg3=SeqGradVectorPulse(object_label+"_pfg3",chan,maxgradstrength, gradtrims,delta); build_seq(); } SeqDiffWeightFlowComp::SeqDiffWeightFlowComp(const STD_string& object_label) : SeqGradChanList(object_label), SeqSimultanVector(object_label) {} SeqDiffWeightFlowComp& SeqDiffWeightFlowComp::operator = (const SeqDiffWeightFlowComp& sgdwfc) { SeqSimultanVector::operator = (sgdwfc); SeqGradChanList::operator = (sgdwfc); pfg1=sgdwfc.pfg1; pfg2=sgdwfc.pfg2; pfg3=sgdwfc.pfg3; delay=sgdwfc.delay; build_seq(); return *this; } void SeqDiffWeightFlowComp::build_seq() { SeqSimultanVector::clear(); SeqSimultanVector::operator += (pfg1); SeqSimultanVector::operator += (pfg2); SeqSimultanVector::operator += (pfg3); SeqGradChanList::clear(); SeqGradChanList::operator += (pfg1); SeqGradChanList::operator += (delay); SeqGradChanList::operator += (pfg2); SeqGradChanList::operator += (delay); SeqGradChanList::operator += (pfg3); } ////////////////////////////////////////////////////////////////////////////////////////// static float ps3 [9] = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; //static float ps3 [9] = { -0.100796, 0.994902, 0.003109, -0.994900, -0.100783, -0.004049, -0.003715, -0.003501, 0.999987}; static float ps4 [12] = { -0.021560, -0.304929, 0.952131, -0.949220, -0.064610, 0.307906, 0.491865, 0.656790, 0.571572, 0.435796, -0.897109, 0.072653}; static float ps5 [15] = { -0.810867, -0.496465, 0.309866, 0.307318, -0.931254, 0.195761, -0.171601, -0.145829, 0.974314, -0.894745, 0.169209, -0.413280, 0.139610, 0.736549, 0.661819}; static float ps6 [18] = { -0.006226, -0.064447, 0.997902, 0.636679, -0.653135, 0.409945, -0.399917, -0.828419, 0.392157, 0.789559, 0.384929, 0.477940, -0.887689, 0.101313, 0.449159, 0.152552, -0.851204, -0.502175}; static float ps7 [21] = { 0.055396, -0.824375, 0.563326, 0.811301, -0.575497, 0.102927, -0.229063, 0.783589, 0.577511, -0.881413, -0.159849, 0.444477, 0.564952, 0.817041, 0.115211, 0.707747, 0.119062, 0.696361, -0.150399, -0.035322, 0.987994}; static float ps8 [24] = { -0.590425, -0.804665, -0.062549, 0.027408, -0.732319, -0.680410, 0.756064, -0.645224, 0.109787, 0.952343, 0.144115, 0.268837, 0.391908, -0.032990, 0.919413, 0.101437, -0.919831, 0.378974, -0.389232, -0.418658, 0.820502, -0.751151, 0.241893, 0.614215}; static float ps9 [27] = { 0.393918, -0.259108, 0.881868, 0.625857, 0.591521, 0.508337, 0.517317, -0.817156, 0.254244, -0.758341, 0.441699, 0.479396, -0.234181, 0.114957, 0.965373, 0.958459, -0.080740, 0.273564, -0.041437, 0.894887, 0.444364, -0.237557, -0.849808, 0.470524, 0.818447, 0.402205, -0.410335}; static float ps10 [30] = { 0.557836, 0.789965, 0.254507, 0.569859, -0.258762, -0.779937, -0.195499, -0.880727, 0.431393, 0.932196, -0.349524, -0.094038, 0.549517, -0.660507, 0.511627, -0.015038, -0.296982, 0.954765, 0.818590, 0.095700, 0.566350, -0.833628, -0.392682, 0.388415, 0.175157, 0.478983, 0.860172, -0.299722, 0.912303, 0.279053}; static float ps11 [33] = { 0.511351, 0.804163, 0.303054, -0.794769, -0.503466, 0.338916, 0.174571, 0.221229, 0.959470, -0.234636, -0.431883, 0.870875, 0.815945, 0.188147, 0.546657, -0.981514, 0.181966, 0.059311, -0.599540, 0.800343, 0.001858, -0.081149, -0.946839, 0.311306, -0.636726, 0.218439, 0.739503, 0.517936, -0.498952, 0.694830, -0.161200, 0.795247, 0.584462}; static float ps12 [36] = { 0.425180, 0.315653, 0.848284, 0.185196, -0.382898, 0.905037, -0.480267, -0.117082, 0.869273, -0.477164, -0.715637, 0.510077, -0.702985, 0.558424, -0.440426, -0.707505, -0.690260, -0.151584, 0.944077, 0.041899, -0.327051, -0.264785, 0.510148, 0.818314, 0.918467, 0.068806, 0.389467, 0.085525, 0.922253, 0.377009, -0.144817, 0.947629, -0.284652, -0.704094, 0.656651, 0.270298}; static float ps13 [39] = { 0.608489, 0.354732, 0.709863, 0.840005, 0.542193, 0.020474, -0.380743, -0.814648, 0.437474, 0.207531, -0.233095, 0.950051, -0.789643, 0.613015, -0.025996, -0.937460, -0.021576, 0.347425, 0.304986, -0.753712, 0.582152, 0.873326, -0.161334, 0.459645, 0.321048, 0.871575, 0.370521, -0.486692, -0.248656, 0.837437, -0.041337, 0.427363, 0.903135, -0.582926, 0.527413, 0.618088, -0.220542, 0.971625, 0.085473}; static float ps14 [42] = { -0.529230, -0.838809, 0.127733, -0.502637, 0.855008, -0.127741, -0.313344, 0.635274, 0.705864, -0.000007, 0.000003, 1.000000, 0.601859, 0.028092, -0.798108, -0.333120, -0.625125, -0.705868, 0.923984, 0.258254, -0.282062, 0.301096, -0.657339, 0.690830, 0.821113, -0.458657, -0.339715, 0.835101, 0.432657, 0.339727, -0.015439, -0.983550, -0.179977, 0.915418, -0.287130, 0.282075, 0.321591, 0.647564, -0.690826, 0.600669, -0.046970, 0.798117}; static float ps15 [45] = { 0.957387, -0.187071, 0.220034, 0.190618, 0.585245, 0.788133, 0.325492, -0.844583, -0.425129, 0.022796, -0.678409, 0.734331, -0.596977, -0.258722, 0.759395, -0.416250, 0.343103, 0.842031, 0.734448, 0.292307, 0.612489, 0.581881, -0.362502, 0.728016, 0.928822, 0.354407, -0.108098, -0.861661, 0.322776, 0.391608, 0.525770, 0.761172, -0.379714, -0.034273, 0.991162, -0.128153, 0.084508, -0.056169, 0.994838, 0.630413, -0.756662, 0.173326, 0.491239, 0.826626, 0.274542}; static float ps16 [48] = { 0.554077, 0.486008, 0.675866, -0.495011, 0.455826, 0.739721, 0.944451, 0.224351, 0.240166, -0.818498, -0.461979, 0.341521, 0.629291, -0.144331, 0.763650, -0.302298, -0.787745, 0.536725, 0.011914, 0.814134, 0.580555, 0.030663, -0.999031, 0.031565, 0.589202, -0.783569, -0.197131, 0.562891, 0.816715, 0.127007, 0.052951, 0.220175, 0.974022, 0.067168, -0.416946, 0.906446, 0.878961, -0.413143, 0.238202, -0.522802, -0.177477, 0.833775, 0.409735, -0.767260, 0.493386, -0.919674, 0.170720, 0.353630}; static float ps17 [51] = { -0.084677, -0.798978, 0.595368, -0.285378, 0.382557, 0.878755, 0.239575, -0.008537, 0.970840, -0.826274, 0.479411, -0.295697, -0.933600, 0.272403, 0.232780, -0.585702, 0.695361, 0.416445, 0.348167, 0.536125, 0.768993, 0.687326, 0.597291, -0.413312, -0.788627, -0.069187, -0.610967, 0.672858, 0.682522, 0.285353, -0.729422, -0.025495, 0.683588, -0.028902, 0.887279, 0.460327, 0.432026, -0.525413, 0.733004, -0.386679, 0.910660, -0.145523, -0.269733, -0.320655, 0.907978, -0.266447, -0.962145, 0.057290, -0.969994, -0.241445, -0.028553}; static float ps18 [54] = { -0.358616, 0.232844, 0.903979, 0.990653, -0.112342, 0.077367, -0.282930, 0.716688, 0.637423, -0.891249, -0.417614, 0.176844, -0.733882, -0.178601, 0.655377, 0.579701, -0.807043, -0.112374, 0.000650, 0.985575, 0.169239, 0.319924, -0.498679, 0.805586, -0.822530, 0.367692, 0.433874, -0.412439, -0.753502, 0.511984, 0.153276, -0.903274, 0.400754, 0.228998, 0.150756, 0.961682, 0.720077, -0.052737, 0.691887, 0.530172, 0.845386, 0.065124, 0.737068, -0.568030, 0.366160, 0.309857, 0.667672, 0.676907, -0.209598, -0.358489, 0.909700, 0.795763, 0.431108, 0.425331}; static float ps19 [57] = { -0.506190, -0.182434, 0.842905, -0.353038, -0.682139, 0.640352, 0.416262, 0.804302, 0.424057, -0.364266, -0.916701, 0.164226, 0.265893, -0.875818, 0.402794, -0.788937, -0.296829, -0.538025, -0.635112, 0.742750, 0.212027, -0.853341, -0.307549, 0.420979, 0.000000, 0.000000, 1.000000, -0.170383, 0.527122, -0.832533, 0.617996, -0.195486, 0.761490, -0.126832, 0.982490, 0.136478, 0.755313, -0.565523, 0.331189, -0.890859, 0.267459, 0.367200, 0.987215, -0.062418, 0.146668, 0.317816, 0.401218, 0.859079, -0.500303, 0.374591, 0.780627, 0.131853, -0.737897, -0.661909, -0.813935, -0.580022, -0.032945}; static float ps20 [60] = { -0.947965, 0.033315, 0.316625, -0.399719, -0.680997, 0.613570, -0.224707, 0.635190, 0.738945, -0.625805, -0.223904, 0.747152, 0.664622, 0.112881, 0.738604, -0.855031, -0.480158, 0.195886, -0.256130, 0.083729, 0.963009, -0.198427, 0.183236, -0.962835, 0.168344, 0.896561, 0.409682, -0.505636, -0.860974, 0.055276, 0.690315, -0.403910, 0.600269, -0.002786, -0.980688, 0.195559, -0.966326, -0.047679, -0.252866, -0.428878, 0.867093, 0.253402, 0.490998, -0.811800, 0.316073, 0.109684, -0.655863, 0.746869, 0.701264, 0.583572, 0.409477, -0.862283, 0.506426, 0.000331, -0.688646, 0.405965, 0.600798, 0.266429, 0.453089, 0.850721}; static float ps21 [63] = { 0.281102, 0.664650, 0.692259, 0.912517, 0.330300, -0.241279, -0.523441, -0.498410, 0.691084, 0.959417, -0.211461, -0.186559, -0.737697, -0.614913, -0.278721, -0.671940, 0.628624, 0.391572, -0.593050, -0.773400, 0.223929, 0.214257, 0.116502, 0.969805, 0.409038, -0.735521, 0.540090, 0.953042, 0.036026, 0.300687, -0.738786, 0.080476, 0.669118, 0.629538, -0.272009, 0.727800, -0.348436, 0.936659, -0.035541, -0.297481, -0.074546, 0.951813, -0.282864, 0.460513, 0.841377, 0.065572, -0.476145, 0.876918, 0.240577, 0.958924, 0.150293, -0.804358, 0.556622, -0.207800, 0.661996, 0.272751, 0.698118, -0.108159, -0.886921, 0.449079, -0.183756, 0.858018, 0.479623}; static float ps22 [66] = { -0.882341, 0.332209, -0.333333, -0.352361, -0.935864, 0.000000, 0.986663, 0.162779, 0.000000, 0.341948, 0.773385, 0.533805, -0.498797, 0.682828, -0.533805, 0.728872, 0.598025, -0.333333, -0.000000, -0.000000, 1.000000, 0.634302, -0.773086, 0.000000, 0.158690, -0.961879, 0.222724, 0.087078, -0.527812, 0.844886, 0.413560, 0.339318, 0.844886, -0.840745, -0.090557, 0.533805, 0.446341, 0.366214, -0.816497, -0.540321, 0.203436, -0.816497, -0.825279, -0.184302, -0.533805, 0.912357, -0.343510, -0.222724, -0.753667, -0.618369, -0.222724, 0.253029, 0.806863, -0.533805, -0.572250, 0.622562, 0.533805, -0.153469, 0.930234, 0.333333, -0.093980, 0.569650, 0.816497, 0.500637, -0.188494, -0.844886}; static float ps23 [69] = { 0.461401, -0.470194, 0.752347, -0.001035, -0.702076, 0.712101, 0.335322, 0.027683, 0.941697, -0.165846, 0.814522, 0.555922, 0.663968, 0.730147, -0.161344, 0.801328, -0.534568, 0.268534, 0.604447, -0.778192, -0.170471, 0.411647, 0.852388, 0.322461, -0.640902, -0.026697, 0.767158, 0.788165, -0.084222, 0.609674, -0.080094, 0.992163, 0.095902, 0.223489, 0.927836, -0.298619, 0.991384, -0.050116, 0.121023, 0.903221, 0.247278, -0.350777, -0.871316, -0.449293, -0.197343, 0.896749, -0.315784, -0.310034, -0.525387, -0.541060, 0.656675, -0.188149, 0.259579, 0.947216, 0.200720, 0.574644, 0.793408, -0.128638, -0.262416, 0.956342, 0.378311, -0.859291, 0.344239, 0.644524, 0.418362, 0.639971, -0.564167, 0.497659, 0.658826}; static float ps24 [72] = { 0.132723, 0.739879, -0.659517, -0.918278, -0.379929, 0.111440, -0.965426, 0.153303, 0.210835, 0.608607, -0.784469, 0.119187, 0.639150, 0.437609, 0.632444, 0.789542, 0.209334, -0.576891, 0.135008, -0.362540, 0.922138, 0.344276, 0.093474, 0.934204, 0.682349, 0.706470, 0.187884, 0.141671, 0.550473, 0.822745, 0.699577, -0.167742, 0.694590, -0.591356, -0.690452, 0.416621, 0.935168, 0.136207, 0.326968, 0.644819, -0.248547, -0.722795, -0.727042, 0.600675, 0.332565, -0.156172, 0.940576, -0.301540, -0.196180, 0.149388, 0.969121, 0.293367, 0.952754, -0.078708, 0.467415, -0.628758, 0.621439, 0.242627, 0.862959, 0.443209, -0.321942, 0.668161, 0.670756, 0.229728, -0.943726, -0.237921, -0.391999, -0.321717, 0.861879, 0.887686, -0.387799, 0.248245}; static float ps25 [75] = { -0.390766, 0.445739, 0.805368, -0.207574, -0.064662, 0.976080, -0.695120, -0.716447, 0.059252, 0.603415, -0.536675, 0.589806, 0.869788, -0.131387, 0.475612, 0.348154, 0.902751, 0.252644, -0.841901, -0.429795, -0.326312, 0.026932, 0.992875, -0.116078, 0.199282, -0.822464, 0.532766, -0.866657, -0.349331, 0.356193, 0.328448, -0.243190, 0.912678, -0.536597, -0.448887, 0.714537, -0.639476, 0.653882, 0.404362, 0.137832, 0.291341, 0.946638, 0.900413, -0.230926, -0.368687, -0.372910, -0.822287, 0.429862, -0.668219, 0.036606, 0.743064, -0.229908, 0.922003, 0.311534, 0.002286, 0.727683, 0.685910, 0.487929, 0.607072, 0.627207, -0.868181, 0.488192, -0.089047, -0.997594, -0.063085, -0.028748, -0.057425, -0.548469, 0.834196, 0.613080, 0.142607, 0.777043, -0.522776, 0.844196, -0.118489}; static float ps26 [78] = { -0.170472, -0.438955, 0.882189, 0.554683, -0.770371, 0.314414, 0.345112, -0.727674, -0.592780, -0.416733, 0.254294, 0.872736, -0.763875, 0.349438, 0.542576, 0.747465, -0.374683, 0.548551, 0.284346, -0.587046, 0.757974, 0.636315, -0.740927, -0.214778, -0.000000, 0.000000, 1.000000, 0.432938, 0.379714, 0.817546, 0.006321, 0.520762, 0.853679, 0.451156, -0.136178, 0.881994, -0.150889, -0.863141, -0.481893, 0.599057, 0.676130, 0.428928, 0.226535, 0.973861, -0.016605, -0.946988, -0.026404, 0.320181, -0.625272, -0.775587, 0.086600, -0.765174, -0.460884, 0.449549, -0.363201, -0.745474, 0.558887, 0.895953, -0.443971, 0.012599, -0.592938, -0.176069, 0.785763, 0.079483, -0.899040, 0.430592, -0.903853, -0.419147, -0.085820, 0.978816, -0.037941, 0.201195, 0.791067, 0.176959, 0.585575, -0.233199, 0.968071, 0.091965}; static float ps27 [81] = { 0.463021, -0.849503, 0.252896, 0.091872, -0.435100, 0.895683, 0.113035, 0.782286, 0.612578, -0.782141, -0.478793, 0.398763, 0.618257, -0.507255, 0.600376, 0.383776, 0.378376, 0.842347, -0.202217, 0.957680, 0.204833, 0.605451, 0.671866, 0.426645, 0.905808, 0.410461, 0.105043, 0.994425, -0.009222, -0.105043, 0.506335, -0.118428, 0.854166, 0.908941, -0.121717, 0.398763, 0.867348, -0.482561, 0.121824, 0.636480, -0.747878, -0.188604, -0.598218, -0.792019, 0.121824, -0.415234, -0.313019, 0.854166, -0.503985, 0.190923, 0.842346, -0.000000, -0.000000, 1.000000, -0.094212, 0.446180, 0.889970, 0.162534, -0.769747, 0.617310, 0.769074, 0.251434, 0.587627, 0.825389, -0.369741, -0.426645, -0.080058, -0.964176, 0.252896, -0.805072, -0.080951, 0.587627, -0.279795, -0.941352, -0.188604, -0.419649, 0.669808, 0.612578, -0.360407, -0.713902, 0.600376}; static float ps28 [84] = { -0.200535, 0.176758, 0.963609, -0.789706, 0.093773, -0.606277, -0.634769, 0.434030, 0.639286, 0.371816, -0.791058, 0.485778, 0.295843, 0.516228, 0.803732, 0.558554, 0.721872, 0.408556, 0.757931, 0.348475, 0.551458, -0.769718, 0.520916, -0.369026, -0.072981, -0.922968, 0.377894, -0.814183, -0.367904, 0.449169, 0.836984, -0.511974, -0.193235, -0.567532, 0.822113, -0.045132, -0.936615, 0.064113, 0.344444, -0.951494, -0.292660, -0.094916, 0.097786, 0.871555, 0.480448, 0.744405, 0.665315, -0.056724, 0.414048, 0.099130, 0.904841, -0.010740, -0.636290, 0.771375, 0.459723, -0.405579, 0.790038, 0.048340, -0.194793, 0.979652, -0.418882, 0.803886, 0.422262, -0.173571, 0.588245, 0.789836, -0.487511, -0.721184, 0.492166, -0.406398, -0.371802, 0.834628, 0.357460, 0.933785, 0.016391, -0.132835, 0.989660, 0.054113, -0.977329, 0.156583, -0.142513, -0.641476, 0.004168, 0.767132}; static float ps29 [87] = { -0.005354, 0.838993, 0.544116, -0.813080, 0.581660, 0.023934, -0.704906, -0.614780, 0.353769, -0.075777, 0.995211, 0.061751, 0.481696, -0.869085, 0.112513, 0.861387, 0.263749, 0.434106, -0.139595, -0.323021, 0.936040, -0.137055, 0.154882, 0.978380, 0.736312, 0.666344, 0.117604, 0.148443, -0.885577, 0.440135, 0.274554, -0.090726, 0.957282, -0.517675, -0.645708, -0.561314, 0.556108, 0.381572, -0.738341, -0.347114, 0.549350, 0.760083, 0.555705, 0.242041, 0.795367, -0.974030, 0.168711, 0.151007, 0.338337, 0.907573, -0.248675, 0.150825, 0.499473, 0.853100, -0.225735, -0.715029, 0.661647, 0.928918, -0.196774, 0.313674, 0.958288, 0.284151, -0.030686, 0.674417, -0.210137, 0.707817, -0.349431, -0.911036, -0.218888, 0.274834, -0.561372, 0.780594, -0.469528, 0.803671, 0.365589, -0.861943, -0.128115, 0.490552, 0.642962, -0.608202, 0.465499, -0.569978, 0.095177, 0.816129, -0.754108, 0.419020, 0.505711}; static float ps30 [90] = { -0.546405, 0.619202, 0.563943, -0.398931, -0.600006, 0.693432, 0.587973, 0.521686, 0.618168, 0.055894, -0.991971, -0.113444, -0.666933, -0.677984, 0.309094, 0.163684, 0.533013, 0.830123, 0.542826, 0.133898, 0.829102, -0.074751, -0.350412, 0.933608, 0.845751, -0.478624, -0.235847, 0.767148, -0.610673, 0.196372, -0.283810, 0.381633, 0.879663, 0.537228, -0.616249, 0.575868, -0.711387, 0.197778, 0.674398, 0.886511, 0.219025, 0.407586, 0.296061, 0.842985, 0.449136, -0.937540, -0.340990, 0.068877, 0.398833, 0.917023, 0.000835, 0.097278, -0.711949, 0.695460, -0.311534, 0.908623, -0.278121, -0.432043, -0.089758, 0.897375, -0.949980, 0.030810, 0.310788, 0.146722, -0.811981, -0.564942, -0.172201, -0.908573, 0.380580, 0.507209, -0.848578, -0.150513, -0.730808, -0.654136, -0.194999, 0.077744, 0.094961, 0.992441, 0.383976, -0.293959, 0.875300, 0.788208, -0.213656, 0.577130, -0.752333, -0.301447, 0.585769, -0.975732, 0.165497, -0.143382}; static float ps31 [93] = { 0.204365, 0.723592, 0.659280, 0.156581, 0.952862, 0.259878, 0.502093, 0.845243, -0.182942, -0.462199, 0.146202, 0.874641, -0.828951, -0.557577, 0.044144, 0.759598, -0.365808, 0.537769, -0.461678, -0.305697, 0.832708, 0.293945, 0.300853, 0.907239, -0.744891, -0.458029, 0.485125, -0.053573, -0.007571, 0.998535, -0.801661, 0.004602, 0.597761, 0.906689, -0.326546, -0.266990, -0.634552, 0.733992, 0.242072, 0.898661, 0.303062, 0.317116, 0.386692, -0.157930, 0.908585, -0.147760, 0.482285, 0.863463, -0.282948, 0.955956, 0.078033, 0.077351, 0.977208, -0.197689, 0.415644, -0.565839, 0.712086, -0.367403, -0.708805, 0.602171, 0.809329, -0.571428, 0.135854, -0.024719, -0.459890, 0.887632, 0.971604, -0.128709, 0.198542, 0.605429, 0.490255, 0.626981, -0.247787, 0.807881, 0.534723, 0.072291, -0.816662, 0.572570, 0.474533, -0.823107, 0.311951, 0.728476, 0.053702, 0.682963, -0.610171, 0.488179, 0.623997, 0.973963, 0.137190, -0.180485, 0.571718, 0.771067, 0.280348}; static float ps32 [96] = { 0.519013, 0.854199, 0.031151, 0.801211, -0.063809, 0.594970, 0.514837, 0.726299, 0.455448, 0.117967, 0.965760, 0.231065, -0.467151, -0.549242, 0.692895, 0.716315, 0.197382, -0.669278, 0.599777, -0.492419, 0.630707, -0.800020, 0.223072, 0.556963, 0.029535, 0.733272, -0.679294, 0.379870, 0.402820, 0.832727, -0.951171, -0.161172, 0.263244, -0.102942, 0.448113, 0.888030, -0.760744, -0.566441, 0.316879, -0.697256, 0.653755, 0.294005, -0.944892, 0.293928, 0.144174, -0.353468, 0.934011, 0.051810, -0.680714, 0.715159, -0.158670, 0.747590, 0.362889, 0.556256, 0.890215, -0.360105, 0.279001, -0.378146, -0.845537, 0.376926, -0.281684, 0.832306, 0.477411, 0.841861, 0.525064, 0.124811, 0.478308, -0.041353, 0.877218, 0.231306, -0.428135, 0.873612, -0.206770, -0.303548, 0.930110, 0.978177, 0.099085, 0.182624, 0.118710, 0.750307, 0.650344, 0.004364, 0.977355, -0.211562, -0.348364, 0.817823, -0.458049, -0.435353, 0.090815, 0.895667, -0.498520, 0.514078, 0.697998, 0.058008, 0.049572, 0.997085}; static float ps33 [99] = { 0.089846, -0.796132, 0.598416, -0.889197, -0.439400, 0.127498, 0.878732, 0.057482, -0.473842, 0.298808, 0.383830, 0.873721, -0.667462, 0.734674, 0.121444, 0.902709, -0.168444, 0.395908, -0.466351, 0.711849, 0.525154, -0.012642, 0.898708, 0.438366, -0.796352, 0.378713, 0.471593, 0.998344, 0.021989, -0.053149, 0.921461, -0.385101, -0.051050, 0.287662, -0.049396, 0.956457, 0.511047, -0.533415, 0.674017, -0.317868, -0.543955, 0.776578, 0.671652, 0.316978, 0.669633, -0.194675, -0.169063, 0.966188, 0.655941, -0.120039, 0.745206, -0.412577, 0.858600, -0.304281, -0.117792, 0.238027, 0.964089, 0.139886, -0.457650, 0.878060, -0.697865, -0.651979, -0.296492, -0.512479, 0.326764, 0.794098, 0.288795, -0.949244, -0.124633, -0.096132, 0.630120, 0.770524, 0.752046, -0.576139, 0.320141, -0.910968, -0.265341, -0.315802, -0.338708, -0.827785, 0.447268, 0.375133, 0.714447, 0.590627, -0.692855, -0.487474, 0.531338, 0.325491, 0.932049, 0.159189, -0.594859, -0.109432, 0.796347, -0.614860, -0.777249, 0.133535, -0.036549, -0.984926, 0.169073}; static float ps34 [102] = { -0.227292, 0.546703, 0.805887, 0.441153, 0.200379, 0.874776, -0.384424, 0.088677, 0.918888, -0.067113, 0.675224, -0.734553, 0.289281, 0.820849, 0.492466, 0.215005, -0.899033, 0.381460, 0.057075, -0.994756, -0.084875, -0.102712, -0.320427, 0.941688, 0.626386, 0.750060, -0.212252, 0.960624, 0.097251, -0.260276, 0.910037, 0.414253, 0.015075, 0.018249, 0.157257, 0.987389, -0.565995, 0.716767, 0.407302, -0.879234, 0.337122, 0.336596, 0.896546, 0.191369, 0.399480, 0.688778, 0.678433, 0.255565, -0.152798, 0.855448, 0.494835, 0.192637, 0.562150, 0.804287, -0.816991, 0.576633, 0.004479, -0.766316, -0.448832, 0.459684, 0.709943, -0.075851, 0.700162, -0.501383, -0.327837, 0.800711, 0.360787, 0.928343, 0.089511, -0.364122, -0.688358, 0.627358, -0.606184, 0.401621, 0.686471, 0.304947, -0.219571, 0.926712, -0.457250, 0.888461, 0.039500, -0.597904, 0.722092, -0.347985, 0.482321, -0.522788, 0.702893, 0.837085, -0.353846, 0.417230, 0.763822, 0.008667, -0.645369, 0.630903, 0.474301, 0.614003, 0.196633, 0.925540, -0.323591, 0.987330, -0.123742, 0.099330}; static float ps35 [105] = { 0.322845, 0.739190, 0.591075, 0.952764, -0.275224, 0.128425, -0.435735, 0.871470, -0.225112, 0.822539, -0.152951, 0.547755, -0.163205, 0.785170, 0.597387, 0.552607, -0.029060, 0.832935, 0.220823, -0.329362, 0.918019, 0.265105, 0.866584, -0.422791, 0.659292, 0.675265, 0.330685, -0.203207, -0.263415, 0.943037, -0.011602, 0.507891, 0.861343, -0.491542, 0.444266, 0.749009, 0.829314, 0.329633, -0.451199, -0.589689, -0.148796, 0.793805, -0.786395, 0.142270, 0.601118, 0.443586, 0.895704, 0.030746, 0.752972, 0.329843, 0.569418, 0.655995, 0.703730, -0.272826, 0.955898, 0.155214, 0.249334, 0.506293, -0.505363, 0.698767, -0.004827, 0.990475, -0.137610, 0.141870, 0.096952, 0.985126, 0.421916, 0.400296, 0.813480, -0.313556, 0.929918, 0.192185, -0.579323, 0.685339, 0.441243, 0.980918, 0.052353, -0.187243, 0.122013, 0.948813, 0.291320, -0.290694, 0.157443, 0.943774, -0.078173, -0.635601, 0.768050, -0.211441, 0.807358, -0.550877, -0.497337, -0.557741, 0.664515, 0.734731, -0.565231, 0.375080, -0.878318, 0.379100, 0.291275, 0.873713, 0.486357, 0.009089, -0.723907, 0.688934, 0.036449}; static float ps36 [108] = { -0.442021, 0.233720, 0.866021, 0.265297, 0.963214, -0.042849, 0.014198, 0.835225, 0.549726, -0.918570, -0.395226, -0.005005, -0.579713, 0.813187, -0.051581, 0.892537, 0.236984, 0.383687, 0.843422, -0.180847, 0.505899, -0.745608, 0.303434, 0.593293, 0.133929, -0.265066, 0.954884, -0.309793, 0.894950, 0.321082, 0.327869, 0.180018, 0.927414, 0.643428, -0.565080, 0.516415, 0.345805, 0.874587, 0.339876, 0.057298, 0.888801, -0.454697, -0.316097, -0.214039, 0.924267, 0.344138, -0.857246, 0.383013, 0.663879, 0.219903, 0.714778, -0.937860, -0.079616, 0.337756, 0.682960, 0.605834, 0.408082, -0.019210, 0.522484, 0.852433, 0.993716, -0.058561, 0.095385, 0.661588, 0.749862, 0.002750, -0.397201, 0.624181, 0.672778, -0.513865, -0.506286, 0.692544, 0.290595, -0.606963, 0.739696, 0.917284, -0.336405, -0.213123, -0.122197, -0.615176, 0.778862, -0.126908, 0.991809, -0.014502, -0.065870, 0.123218, 0.990191, -0.673790, 0.661289, 0.329703, -0.788497, -0.485536, 0.377527, 0.540353, -0.214506, 0.813638, 0.382021, 0.587004, 0.713783, 0.850692, -0.499691, 0.163194, -0.462873, -0.796214, 0.389606, -0.703715, -0.115243, 0.701074}; static float ps37 [111] = { -0.954059, -0.257965, 0.152396, 0.385177, 0.401219, 0.831061, -0.044825, 0.566975, 0.822514, -0.671872, 0.605565, -0.426473, 0.175678, 0.946160, 0.271878, -0.980206, 0.191084, 0.051793, -0.802935, 0.485758, 0.345448, 0.299326, 0.945908, -0.125147, 0.603043, -0.331384, 0.725619, -0.685088, -0.701521, 0.196273, 0.758506, 0.089442, 0.645499, -0.894808, 0.023151, 0.445850, 0.801753, -0.596312, 0.040054, -0.607684, -0.102556, 0.787529, 0.843509, 0.515612, 0.150454, 0.190019, -0.349851, 0.917331, -0.675261, 0.288604, 0.678771, 0.041084, -0.916783, 0.397267, -0.195784, -0.189168, 0.962229, 0.058929, 0.149113, 0.987063, -0.952760, -0.136443, -0.271352, 0.682823, 0.489769, 0.542106, -0.557306, -0.797681, -0.230468, 0.153620, -0.987511, -0.034965, -0.389228, -0.780049, 0.489923, -0.326981, 0.694221, -0.641202, -0.438140, -0.474772, 0.763299, -0.762006, -0.416709, 0.495682, -0.155024, 0.856206, 0.492828, -0.449239, 0.868714, -0.208615, -0.064280, -0.649466, 0.757669, -0.331738, 0.249426, 0.909800, 0.297073, 0.735335, 0.609122, 0.433035, -0.002622, 0.901373, 0.522125, -0.820246, -0.233628, -0.892303, 0.257373, -0.370883, -0.451826, 0.626854, 0.634749}; static float ps38 [114] = { -0.676206, 0.728972, -0.106518, 0.072231, -0.908443, 0.411720, -0.389288, -0.080230, 0.917615, -0.676402, 0.167071, 0.717334, -0.460690, -0.867151, 0.189245, 0.448263, 0.400819, 0.799003, -0.246186, -0.764755, -0.595435, 0.068469, 0.500765, 0.862871, -0.823912, 0.499391, 0.267915, 0.062498, -0.653811, 0.754073, -0.290923, -0.781577, 0.551817, -0.015735, 0.115881, 0.993138, 0.441939, -0.752626, 0.488102, 0.920465, -0.071320, 0.384262, -0.909908, 0.106315, 0.400955, 0.736330, -0.473462, 0.483377, 0.013905, -0.296972, 0.954785, 0.640695, 0.626934, 0.443242, 0.908488, 0.332755, -0.252833, -0.210124, 0.738705, 0.640440, 0.759884, 0.259220, 0.596138, 0.061906, -0.944189, -0.323535, -0.334017, 0.366930, 0.868214, -0.751032, -0.660191, -0.009921, -0.399527, -0.886702, -0.232673, -0.662679, -0.597622, 0.451337, -0.491780, 0.821935, 0.287360, 0.915422, -0.389028, 0.103243, 0.097537, 0.994018, -0.049148, -0.362266, -0.007743, -0.932042, 0.325649, -0.942891, 0.070062, 0.675680, -0.125663, 0.726405, 0.408413, -0.434792, 0.802592, -0.370998, -0.468629, 0.801715, -0.592198, 0.551955, 0.587066, 0.915494, 0.345473, 0.206201, -0.724062, -0.239792, 0.646710, 0.999626, -0.004145, -0.027025}; static float ps39 [117] = { 0.347153, 0.508688, 0.787859, -0.078282, 0.947920, 0.308739, 0.631909, 0.764615, 0.126708, 0.988533, 0.143494, -0.047031, 0.192917, -0.976621, 0.094843, 0.291491, 0.834533, 0.467534, 0.498874, -0.585235, 0.639237, 0.801485, -0.597122, -0.032657, -0.144644, -0.937323, 0.317023, 0.012081, -0.114745, 0.993322, -0.625179, -0.176163, 0.760340, 0.702102, -0.175371, 0.690144, 0.800827, -0.453784, 0.390839, -0.014742, 0.694437, 0.719403, -0.878699, -0.177390, 0.443193, 0.192259, -0.833283, 0.518339, -0.921493, 0.222000, 0.318694, -0.366381, 0.765325, 0.529190, 0.385601, 0.118180, 0.915066, 0.549586, -0.791079, 0.268604, 0.920391, 0.018063, 0.390582, -0.349828, 0.074056, 0.933882, 0.364182, -0.286254, 0.886245, -0.632981, -0.531079, 0.563285, -0.001472, 0.320596, 0.947215, 0.877627, 0.410926, 0.246800, 0.076526, -0.565476, 0.821207, -0.530028, -0.803470, 0.271120, 0.500102, -0.852700, -0.150998, -0.835436, -0.520972, 0.175031, -0.388262, 0.461512, 0.797658, 0.703022, 0.242172, 0.668665, -0.264781, -0.961753, -0.070160, -0.293581, -0.379303, 0.877462, 0.623223, 0.602331, 0.498789, -0.705112, 0.213058, 0.676330, -0.703858, 0.557815, 0.439803, -0.265884, -0.721690, 0.639116, 0.965898, -0.244797, 0.084355}; static float ps40 [120] = { 0.558523, -0.643113, 0.523886, 0.118807, 0.947226, 0.297739, 0.147131, -0.682186, 0.716222, 0.285042, -0.883821, 0.370960, 0.335250, -0.044445, 0.941080, 0.873413, 0.184236, 0.450784, 0.499484, 0.804442, 0.321540, 0.031536, -0.994644, 0.098427, -0.832278, 0.540204, 0.124473, -0.832799, -0.464545, 0.301072, -0.350077, -0.199964, 0.915129, 0.822155, -0.501563, 0.269251, -0.896134, -0.097505, 0.432939, 0.354502, 0.931427, -0.082298, -0.382487, 0.224761, 0.896207, 0.972570, -0.171596, -0.157042, -0.675831, 0.026545, 0.736579, 0.577818, -0.810686, 0.094418, 0.179984, -0.807595, -0.561602, -0.480516, 0.539719, 0.691236, -0.138537, -0.871912, 0.469657, -0.025579, 0.097641, 0.994893, 0.519215, 0.729128, -0.445857, 0.637324, 0.120443, 0.761125, 0.442010, -0.392731, 0.806467, -0.962447, 0.132955, -0.236682, 0.761366, -0.236438, 0.603671, 0.635300, 0.388715, -0.667304, -0.268758, -0.589576, 0.761689, 0.686201, 0.725438, -0.053554, 0.973461, 0.228837, 0.002569, 0.818706, 0.518341, 0.247070, 0.304040, 0.375695, 0.875450, 0.299135, -0.937617, -0.177181, -0.581244, 0.729844, 0.359837, 0.030601, -0.342747, 0.938929, 0.789913, -0.345411, -0.506684, -0.076637, 0.518479, 0.851649, 0.232583, 0.727661, 0.645302, 0.602447, 0.514123, 0.610520}; static float ps41 [123] = { 0.570240, -0.503812, 0.648845, -0.213208, -0.976102, 0.042047, -0.457635, -0.131533, 0.879357, 0.316770, -0.807971, 0.496830, 0.624689, -0.735275, 0.262935, -0.195457, -0.699901, 0.686975, 0.311562, -0.246405, 0.917722, -0.825116, 0.560457, 0.071214, 0.889796, -0.039074, 0.454683, -0.652207, -0.285222, -0.702335, -0.900608, 0.221247, 0.374105, 0.526334, 0.487232, -0.696834, 0.244279, -0.961976, 0.122185, 0.000000, 0.000000, 1.000000, 0.041279, 0.443230, 0.895457, 0.351628, 0.178778, 0.918910, -0.077842, 0.967549, 0.240394, -0.465230, -0.801424, 0.375873, 0.975310, -0.219224, 0.026687, 0.835478, -0.413691, 0.361714, 0.768507, 0.143169, -0.623618, -0.573996, -0.818799, -0.009854, -0.535477, 0.836017, 0.119751, -0.983473, -0.153943, -0.095302, 0.381211, 0.589665, 0.712021, 0.178675, -0.592369, 0.785604, -0.943716, -0.173476, 0.281615, -0.355285, 0.812979, 0.461343, -0.620613, -0.677921, -0.394034, 0.844211, 0.371366, 0.386516, -0.137437, -0.366020, 0.920402, -0.357821, 0.558649, 0.748248, -0.843430, -0.537235, -0.002233, 0.649835, -0.123856, 0.749916, -0.307755, 0.222194, 0.925158, -0.295019, -0.882404, -0.366506, -0.687405, 0.565538, 0.455675, -0.057362, -0.915503, 0.398200, 0.759638, 0.528964, -0.378348, -0.661319, 0.241290, 0.710237, 0.015192, 0.767478, 0.640896}; static float ps42 [126] = { -0.398081, 0.759978, 0.513774, -0.552704, 0.436246, 0.710076, 0.033739, -0.058664, 0.997707, -0.826846, 0.256869, 0.500344, -0.109287, 0.949319, 0.294702, -0.862751, -0.174568, 0.474538, 0.830917, 0.018557, 0.556086, 0.131261, -0.708656, 0.693237, 0.636126, 0.638353, 0.433416, 0.349266, 0.589509, 0.728349, -0.075739, -0.911351, 0.404602, 0.963324, 0.254117, -0.086206, 0.807793, 0.588220, 0.038308, 0.538507, 0.840319, 0.062237, 0.669202, -0.714242, 0.205003, 0.884388, 0.330360, 0.329728, 0.353187, -0.847851, 0.395483, 0.828046, -0.387895, 0.404818, 0.633020, 0.323865, 0.703134, 0.471747, 0.820072, -0.323940, 0.886390, -0.462936, 0.001550, 0.132193, 0.338336, 0.931694, -0.186235, 0.539339, 0.821237, -0.206069, 0.975165, -0.081175, 0.624803, -0.219936, 0.749166, 0.288831, -0.358754, 0.887622, -0.364703, -0.204777, 0.908327, -0.600328, -0.420416, 0.680336, 0.731451, -0.597018, -0.329468, 0.185236, 0.982546, -0.017063, 0.415947, 0.072692, 0.906479, 0.019880, 0.777833, 0.628157, 0.305069, 0.872705, 0.381208, 0.534377, -0.581454, 0.613475, 0.973964, -0.129556, -0.186035, -0.755350, -0.554569, 0.349141, -0.646828, 0.019773, 0.762380, 0.977793, -0.068381, 0.198101, -0.095416, -0.456877, 0.884398, -0.514263, 0.848324, 0.126016, -0.290488, 0.183591, 0.939101, -0.316725, -0.685919, 0.655134}; static float ps43 [129] = { 0.327172, -0.332909, 0.884381, -0.707217, 0.605258, 0.365386, 0.621561, 0.368700, 0.691175, -0.868663, -0.397352, 0.295864, 0.669593, -0.295823, 0.681274, -0.094650, 0.957781, 0.271471, 0.123828, -0.869340, 0.478450, 0.861175, 0.349879, 0.368730, 0.460114, -0.633911, 0.621653, -0.957033, 0.170378, -0.234645, -0.525769, -0.848901, -0.054167, -0.601393, -0.740231, 0.300641, 0.787918, -0.487166, 0.376636, -0.479980, 0.867981, 0.127389, -0.372140, 0.780485, 0.502350, -0.485079, 0.493392, 0.721985, -0.132336, 0.463386, 0.876219, -0.805300, 0.274682, 0.525397, -0.510420, 0.810062, -0.288568, -0.220230, 0.099346, 0.970376, -0.777915, -0.136173, 0.613437, 0.086576, -0.631340, 0.770658, 0.146883, 0.008276, 0.989119, -0.184836, 0.975408, -0.120059, -0.089089, -0.314400, 0.945101, -0.288923, -0.629213, 0.721536, 0.240141, 0.364283, 0.899795, -0.024708, 0.758329, 0.651404, 0.625107, 0.671246, 0.398334, -0.935819, 0.333248, 0.114840, -0.624029, -0.504833, 0.596432, -0.767853, 0.639891, -0.030674, -0.983440, -0.171816, -0.057664, 0.835538, 0.017897, 0.549141, 0.338465, 0.653977, 0.676576, -0.258020, -0.869623, 0.420929, -0.452894, -0.249633, 0.855903, 0.523477, 0.038123, 0.851186, -0.959435, -0.005811, 0.281869, 0.818358, 0.573503, 0.037221, -0.269155, -0.893014, -0.360669, -0.188642, -0.980358, 0.057555, -0.563722, 0.134783, 0.814894}; static float ps44 [132] = { -0.596036, -0.656008, -0.463028, -0.022036, -0.214364, 0.976505, 0.596617, -0.729594, 0.334275, 0.090359, 0.890559, -0.445803, 0.887970, 0.455759, 0.061578, 0.311082, 0.919639, 0.239775, 0.096871, 0.625006, -0.774586, 0.587039, -0.487625, 0.646225, -0.667177, -0.203258, -0.716632, -0.746048, 0.665787, 0.011841, -0.101943, 0.941299, 0.321813, -0.689537, 0.244984, 0.681558, 0.954141, -0.299066, -0.013245, 0.181979, -0.745978, -0.640625, -0.408008, -0.733166, 0.544057, 0.535432, -0.578156, -0.615669, 0.646409, 0.754447, 0.113862, 0.846978, -0.418792, 0.327478, 0.465343, -0.142186, 0.873636, 0.995382, 0.093084, -0.023446, -0.394107, -0.903817, 0.166716, -0.731363, -0.120353, 0.671285, 0.770722, -0.147546, 0.619853, -0.646607, -0.466494, 0.603558, 0.057423, 0.516086, 0.854610, -0.892784, -0.307478, 0.329234, 0.809853, -0.476385, -0.342338, -0.922154, 0.096921, 0.374484, -0.209954, -0.788475, -0.578123, -0.031432, -0.998855, 0.036057, 0.836691, 0.354882, 0.417143, 0.242734, -0.434238, 0.867478, -0.945514, 0.006311, -0.325521, 0.504769, -0.795924, -0.334236, -0.366949, -0.370753, 0.853165, -0.062489, 0.144212, 0.987572, 0.430909, 0.496456, 0.753557, 0.300561, 0.170102, 0.938471, 0.398928, -0.916734, -0.021336, 0.253944, -0.917845, 0.305078, 0.324389, -0.390635, -0.861496, -0.707550, -0.658526, 0.256351, 0.426736, -0.000145, -0.904376, -0.267070, 0.730281, -0.628778}; static float ps45 [135] = { 0.298955, -0.215433, 0.929631, -0.297442, -0.873770, 0.384777, 0.632052, -0.773892, -0.040010, 0.968554, 0.133869, -0.209718, 0.072197, 0.787748, 0.611752, -0.837044, 0.290110, -0.463889, 0.019865, 0.076051, 0.996906, -0.587741, -0.598292, 0.544616, 0.044730, -0.863975, 0.501544, -0.011159, -0.993184, 0.116018, -0.321757, -0.037976, 0.946060, 0.984630, -0.062219, 0.163196, 0.359032, -0.912025, 0.198257, -0.773305, 0.546841, 0.320879, -0.087410, -0.337063, 0.937416, 0.728136, 0.520034, 0.446524, -0.255219, 0.676121, 0.691175, 0.162332, -0.576820, 0.800579, 0.435270, 0.804446, 0.404235, 0.677012, -0.648409, 0.348167, -0.793036, -0.246694, 0.556988, 0.929835, 0.340690, 0.139060, -0.848564, 0.155392, 0.505760, 0.353515, 0.189803, 0.915971, 0.385974, -0.745330, 0.543606, 0.638512, 0.289412, 0.713122, -0.605468, 0.449624, 0.656694, -0.058665, -0.952812, -0.297839, -0.486302, -0.348482, 0.801294, -0.471106, 0.772195, 0.426349, -0.598824, -0.773521, 0.207543, 0.551288, -0.444212, 0.706228, -0.628567, 0.057489, 0.775628, 0.643981, -0.087707, 0.759998, 0.714346, 0.688239, 0.126635, 0.874696, -0.474150, 0.100445, 0.277115, -0.943200, -0.183254, -0.954924, 0.243797, 0.169360, 0.054173, 0.468508, 0.881797, -0.227749, -0.653133, 0.722182, 0.386933, 0.580055, 0.716812, 0.358034, 0.932553, 0.046443, 0.844205, 0.484161, -0.230014, -0.312274, 0.341673, 0.886423, 0.874433, 0.115438, 0.471212}; static float ps46 [138] = { 0.695433, 0.252224, 0.672871, -0.315506, 0.800360, 0.509785, 0.693347, 0.576227, 0.432703, 0.820390, -0.114337, 0.560256, 0.810799, 0.041318, -0.583865, 0.892979, -0.444929, -0.068017, -0.381466, -0.466025, 0.798313, -0.660932, 0.694959, 0.283197, -0.032971, -0.886047, 0.462421, 0.663946, -0.743873, 0.076341, -0.024528, 0.938980, 0.343095, 0.848983, 0.524501, 0.064240, -0.568647, 0.551431, 0.610380, 0.831876, -0.445710, 0.330642, 0.395598, 0.236689, 0.887401, -0.360723, -0.904350, 0.228100, 0.577381, -0.693169, 0.431448, -0.322062, 0.906745, -0.272193, -0.892349, -0.326999, 0.311104, -0.232602, 0.135109, 0.963142, 0.142252, -0.011309, 0.989766, 0.278696, -0.709243, 0.647536, -0.125915, -0.253818, 0.959021, 0.408239, 0.564120, 0.717711, -0.266410, 0.509866, 0.817962, 0.366453, 0.811359, 0.455421, -0.825321, 0.339325, 0.451336, -0.581493, 0.224931, 0.781839, -0.684826, -0.424360, 0.592395, -0.052206, -0.630855, 0.774142, -0.968247, 0.085558, 0.234901, 0.593779, -0.424308, 0.683659, 0.028069, -0.996452, 0.079344, -0.687420, -0.672427, 0.274403, 0.042562, 0.730393, 0.681700, -0.397632, -0.736256, 0.547555, 0.604551, 0.789957, 0.102403, -0.516896, -0.126197, 0.846695, 0.248122, -0.386963, 0.888085, -0.898079, -0.234008, -0.372417, 0.365573, -0.921872, -0.128483, 0.066355, 0.401248, 0.913563, 0.971788, -0.143029, 0.187538, 0.531045, -0.103411, 0.841010, -0.274516, -0.953110, -0.127367, -0.982801, -0.183905, -0.016781}; static float ps47 [141] = { -0.235568, -0.268822, 0.933939, -0.354819, -0.154863, -0.922020, -0.945400, 0.252190, -0.206446, -0.753631, -0.405973, 0.516940, -0.347493, 0.929743, 0.121764, -0.857169, 0.515027, 0.002750, 0.014396, 0.369920, 0.928952, -0.863474, -0.020151, 0.503991, -0.106241, -0.915288, 0.388537, -0.480319, -0.738059, 0.473881, 0.629100, -0.767652, 0.122246, -0.168153, -0.696892, 0.697184, 0.295252, 0.790159, 0.537099, -0.020288, 0.697935, 0.715873, -0.841834, -0.330980, -0.426343, 0.274851, -0.925622, 0.260157, -0.603880, -0.138815, 0.784894, -0.324496, 0.482091, 0.813812, -0.308871, -0.929494, -0.201591, 0.633596, -0.155534, 0.757869, -0.850171, 0.373363, 0.371227, 0.299348, -0.209948, 0.930759, -0.661090, 0.222194, 0.716652, 0.068233, -0.481456, 0.873810, -0.769491, 0.440603, -0.462334, 0.000000, -0.000000, 1.000000, -0.535437, 0.712932, -0.452808, -0.730775, -0.648636, 0.212697, 0.861626, -0.042472, 0.505764, 0.629290, 0.758702, 0.168419, -0.643732, 0.722412, 0.252449, -0.463002, -0.479482, 0.745470, 0.645513, 0.241953, 0.724411, 0.015388, 0.999488, -0.028046, -0.600231, 0.551472, 0.579312, -0.348733, 0.123167, 0.929094, 0.347116, 0.510927, 0.786425, -0.935614, -0.277447, 0.218286, -0.980745, 0.115406, 0.157544, 0.035249, -0.931276, -0.362606, 0.459658, -0.493888, 0.738098, -0.865999, -0.490811, -0.095657, -0.982639, -0.120539, -0.141032, -0.413147, -0.898248, 0.149865, 0.614240, 0.603194, 0.508788, -0.192843, 0.766002, -0.613231, -0.333980, 0.793001, 0.509516}; static float ps48 [144] = { -0.900302, 0.079145, 0.428010, 0.726183, 0.538020, 0.428010, 0.913389, 0.376477, 0.154874, 0.188308, 0.565148, 0.803211, -0.103414, 0.354087, 0.929477, 0.333389, -0.942753, 0.008279, 0.692523, 0.712545, 0.112654, -0.684916, 0.058848, 0.726242, 0.611951, 0.029447, 0.790347, -0.372141, 0.046290, 0.927021, 0.286024, 0.840328, -0.460476, -0.545125, -0.295394, 0.784589, 0.974370, -0.203717, -0.095406, 0.681627, -0.566802, 0.462731, 0.833467, 0.189789, 0.518954, -0.170331, 0.668514, 0.723931, -0.251530, 0.886634, 0.388089, 0.096344, 0.851841, 0.514864, -0.269231, -0.605852, 0.748638, -0.464602, 0.382792, 0.798508, 0.972997, 0.174193, -0.151437, 0.975729, 0.001727, 0.218977, 0.433122, 0.708525, 0.557133, 0.290163, 0.216666, 0.932127, -0.287807, -0.952924, 0.095406, 0.671102, -0.730095, 0.128781, 0.374314, -0.629541, 0.680858, 0.756250, -0.398574, -0.518869, -0.832060, -0.513260, 0.210333, -0.580721, 0.782528, 0.224529, 0.394574, 0.885895, 0.243930, 0.574960, -0.334517, 0.746673, 0.052557, -0.793071, 0.606858, 0.048811, -0.963948, 0.261575, 0.834781, -0.191764, 0.516109, 0.552354, 0.392401, 0.735477, 0.393069, -0.841244, 0.371221, 0.302647, -0.187492, 0.934479, -0.580868, -0.782419, 0.224529, 0.831553, -0.525224, -0.180717, -0.812671, -0.275965, 0.513234, 0.098654, -0.487438, 0.867567, -0.596348, -0.588589, 0.545832, 0.015015, 0.988624, 0.149657, -0.506653, 0.657956, 0.557133, 0.891416, -0.406151, 0.201047, -0.200646, -0.295024, 0.934185, -0.000000, -0.000000, 1.000000}; static float ps49 [147] = { 0.357717, -0.137210, 0.923695, 0.838543, -0.337831, 0.427454, -0.317996, -0.267279, 0.909638, -0.529443, 0.828200, -0.183778, -0.689971, 0.530826, 0.492101, -0.279028, -0.942153, 0.185720, -0.046442, 0.913995, 0.403058, -0.630851, -0.109360, 0.768158, -0.276853, -0.599762, 0.750758, 0.304543, 0.223179, 0.925983, -0.854643, 0.161266, 0.493538, 0.610467, 0.705494, 0.360012, -0.621237, 0.254478, 0.741151, 0.890673, -0.410740, -0.194920, 0.350941, 0.914569, 0.201009, 0.041261, -0.355820, 0.933643, 0.826642, 0.551816, 0.110282, -0.000000, 0.000000, 1.000000, -0.407353, 0.781370, 0.472783, -0.091752, -0.865118, 0.493106, 0.075960, -0.659638, 0.747735, 0.629056, 0.147965, 0.763148, 0.844883, 0.217315, -0.488823, 0.932100, 0.329770, -0.149805, 0.399940, -0.488068, 0.775782, 0.542299, 0.497945, 0.676730, 0.805637, 0.380433, 0.454115, 0.284114, 0.791333, 0.541361, 0.970225, -0.205600, 0.128031, 0.316663, -0.797706, 0.513216, 0.602345, 0.796324, -0.055209, 0.660486, -0.730183, -0.174901, -0.746285, -0.582639, 0.321856, 0.164213, -0.959169, 0.230280, 0.213400, 0.548647, 0.808360, -0.091659, 0.711400, 0.696784, 0.806564, -0.575548, 0.134902, 0.621773, -0.608293, 0.493334, 0.653689, -0.226907, 0.721945, -0.346165, 0.108949, 0.931826, 0.969087, 0.169674, 0.179112, 0.982386, -0.028355, -0.184700, 0.866461, 0.018986, 0.498883, 0.345004, -0.929492, -0.130452, -0.388419, 0.518785, 0.761572, -0.599309, -0.459575, 0.655454, 0.021711, 0.997509, 0.067112, -0.459078, -0.763562, 0.454115, -0.083373, 0.366642, 0.926619}; static float ps50 [150] = { 0.292398, 0.632726, 0.717050, -0.843833, 0.220921, -0.489019, 0.785259, 0.598608, -0.158229, -0.246495, 0.274622, -0.929421, -0.000000, 0.000000, -1.000000, 0.686000, 0.466526, 0.558353, 0.126829, 0.336422, 0.933132, 0.535711, -0.811680, 0.232785, -0.360725, -0.732516, 0.577319, -0.874102, 0.387697, 0.292638, 0.444951, -0.885998, -0.130480, -0.591382, 0.275693, -0.757800, -0.583170, 0.586267, -0.562321, 0.039175, 0.686594, -0.725985, 0.572177, -0.134776, -0.808980, -0.937808, 0.343315, -0.051486, 0.615523, -0.680490, -0.397574, 0.721149, 0.068523, 0.689383, 0.954292, 0.298630, 0.012096, -0.797347, -0.562403, -0.218954, 0.571225, 0.817386, 0.074716, -0.791417, 0.531793, -0.301421, 0.077086, -0.611571, -0.787426, -0.348912, -0.109463, 0.930741, 0.274444, -0.824626, 0.494644, -0.480310, -0.345587, -0.806146, 0.488682, 0.830487, -0.267359, 0.851245, -0.055223, -0.521854, 0.266684, 0.931720, 0.246531, 0.888295, 0.223094, 0.401449, 0.192710, 0.976944, -0.091891, 0.292776, -0.817780, -0.495498, 0.097361, -0.974745, -0.200979, -0.420389, -0.449396, 0.788236, 0.670427, 0.545344, -0.503117, -0.681322, -0.212859, 0.700351, -0.067466, -0.844666, -0.531024, 0.743502, -0.666714, -0.051930, 0.078278, 0.905458, -0.417154, 0.090735, 0.383555, -0.919050, -0.886715, -0.285804, 0.363391, -0.500435, -0.744752, -0.441486, 0.983486, -0.030143, -0.178457, -0.194325, 0.968880, -0.153330, -0.294107, 0.572993, -0.764971, -0.978598, 0.035285, -0.202734, 0.701930, -0.383871, -0.599947, 0.249265, -0.278339, -0.927574, -0.417932, 0.543917, 0.727658, 0.396822, 0.032728, 0.917312}; static float ps51 [153] = { -0.182631, 0.665442, 0.723763, 0.947000, -0.276145, -0.164122, -0.466354, 0.469307, 0.749844, -0.888561, 0.047701, 0.456272, 0.986230, -0.074324, 0.147735, 0.981014, 0.115685, -0.155654, 0.497602, 0.749709, 0.436266, 0.636566, 0.628530, -0.446916, -0.685683, 0.199945, 0.699900, -0.398021, 0.116063, 0.910005, 0.121705, -0.686485, 0.716887, 0.511679, 0.462981, -0.723763, 0.168346, 0.525634, -0.833888, 0.471613, 0.513474, 0.716887, -0.302804, 0.930227, -0.207333, 0.871604, -0.467420, 0.147735, 0.281395, 0.226883, 0.932385, -0.379594, -0.879849, 0.285961, 0.861218, 0.093932, 0.499481, -0.281355, -0.754449, 0.592998, -0.668385, -0.735021, 0.114045, -0.131659, 0.335564, 0.932772, 0.000000, -0.000000, 1.000000, 0.669329, -0.195176, 0.716872, 0.496954, -0.856187, -0.141351, 0.396115, -0.765549, 0.506978, -0.774932, 0.437373, 0.456272, 0.615082, 0.170587, 0.769789, -0.645511, -0.145087, 0.749844, -0.168555, 0.979072, 0.114045, 0.107153, 0.988909, -0.102850, -0.745510, -0.432652, -0.506978, 0.140565, 0.533734, 0.833888, 0.168256, 0.787428, 0.592998, 0.821783, 0.313391, -0.475876, 0.441176, 0.891508, 0.102850, -0.291387, -0.212204, 0.932772, 0.765076, -0.624844, -0.155654, -0.016646, 0.899664, -0.436266, 0.936466, 0.293148, 0.192600, 0.152816, 0.945978, 0.285961, 0.632125, -0.750549, 0.192600, -0.524536, 0.705978, 0.475876, 0.384023, -0.111981, 0.916508, -0.879262, -0.454883, 0.141351, -0.198962, 0.872170, 0.446916, -0.675748, 0.542111, -0.499481, 0.115342, -0.342572, 0.932385, 0.867127, -0.252854, 0.429134, 0.755338, 0.621674, 0.207333, 0.426988, -0.474454, 0.769789}; static float ps52 [156] = { -0.380828, 0.125600, 0.916076, 0.775463, 0.466398, 0.425594, 0.051490, 0.997061, 0.056727, -0.838226, 0.490955, 0.237362, 0.181976, 0.759386, 0.624674, 0.330409, -0.227234, 0.916076, 0.000000, -0.000000, 1.000000, -0.378272, -0.762516, 0.524862, -0.080269, 0.336748, 0.938167, 0.233251, 0.470185, 0.851187, -0.398125, 0.749051, 0.529545, -0.218447, -0.938897, 0.265996, 0.676634, -0.600863, 0.425594, 0.316689, 0.139824, 0.938167, 0.554318, -0.434200, 0.710072, 0.247499, -0.597866, 0.762431, 0.762649, -0.643302, 0.067299, -0.501304, 0.851612, -0.153137, 0.444405, 0.895826, 0.000000, -0.615405, -0.741972, 0.265996, 0.590752, 0.297563, 0.749978, 0.837278, 0.136188, 0.529545, 0.616183, -0.057059, 0.785533, -0.121326, -0.637128, 0.761149, 0.494541, 0.604328, 0.624674, 0.257553, 0.911733, 0.320013, -0.973618, 0.218032, 0.067299, 0.593075, -0.769300, -0.237569, -0.418228, 0.456096, 0.785533, 0.382369, -0.780812, 0.494091, -0.887788, 0.175222, 0.425594, 0.014067, -0.364205, 0.931212, -0.625771, -0.164650, 0.762431, -0.433890, -0.482070, 0.761149, -0.298498, -0.209147, 0.931212, 0.866300, 0.447124, -0.222720, 0.762727, 0.644228, 0.056727, 0.570118, 0.756675, 0.320013, -0.809388, 0.230579, -0.540115, -0.168111, 0.960278, -0.222720, -0.981363, -0.116085, 0.153137, 0.898041, -0.370379, 0.237362, 0.022325, -0.848267, 0.529098, -0.120485, 0.650397, 0.749978, 0.971347, -0.006784, 0.237569, 0.933261, 0.329669, 0.142626, -0.673278, 0.504948, 0.540115, -0.688913, -0.495434, 0.529098, -0.097807, 0.899613, 0.425594, -0.681085, 0.178664, 0.710072, -0.853034, -0.167949, 0.494091, -0.302142, 0.942533, 0.142626}; static float ps53 [159] = { -0.348682, 0.599436, 0.720484, 0.000000, -0.000000, 1.000000, 0.372542, -0.268634, 0.888284, -0.057626, -0.977512, -0.202854, 0.036699, -0.338665, 0.940191, -0.244555, -0.662520, 0.707997, -0.331527, 0.825257, 0.457210, -0.802318, -0.451736, 0.390155, -0.969400, 0.241289, -0.045207, 0.012489, 0.855232, 0.518094, 0.217138, -0.955800, 0.198234, -0.789741, 0.253663, 0.558538, 0.866327, -0.360922, 0.345272, -0.108084, -0.984138, 0.140676, -0.801560, 0.593495, -0.072562, 0.635958, 0.001051, 0.771723, -0.343472, -0.864386, 0.367239, 0.770181, 0.271893, 0.576971, -0.981093, -0.085486, -0.173635, -0.608463, 0.765359, 0.209756, -0.602214, -0.353568, 0.715771, -0.640018, -0.018789, 0.768131, -0.954667, 0.121600, 0.271705, -0.632384, 0.578023, 0.515733, 0.159638, 0.366365, 0.916675, 0.538947, -0.831151, 0.136838, 0.337613, -0.805040, 0.487778, -0.405776, -0.913468, -0.030360, -0.191793, 0.309247, 0.931440, 0.333518, 0.066039, 0.940428, -0.847538, 0.468937, 0.248550, 0.497733, 0.365845, 0.786396, -0.545561, -0.640483, 0.540504, 0.620704, 0.596871, 0.508401, 0.649557, -0.633433, 0.420521, -0.968139, -0.201519, 0.148650, -0.013376, -0.865067, 0.501478, 0.096149, -0.632834, 0.768295, -0.340704, -0.029687, 0.939702, 0.637917, 0.745616, -0.192663, 0.878769, -0.040591, 0.475518, 0.312339, 0.660340, 0.682931, -0.297469, -0.367782, 0.881050, -0.023460, 0.627774, 0.778042, 0.286390, -0.947536, -0.141969, 0.871706, 0.401712, 0.280634, -0.521447, 0.307019, 0.796136, 0.685060, -0.322135, 0.653392, 0.666681, 0.721428, 0.187289, 0.363034, 0.850010, 0.381693, 0.427974, -0.555655, 0.712802, 0.858522, 0.511214, -0.040007, -0.851421, -0.128550, 0.508485}; static float ps54 [162] = { 0.709865, 0.241411, 0.661674, -0.748020, 0.028172, 0.663077, -0.376106, -0.617862, 0.690501, -0.091531, -0.099182, 0.990851, -0.110710, -0.925445, -0.362346, -0.234756, 0.562199, 0.792983, -0.050816, -0.471016, 0.880660, 0.724650, 0.516268, 0.456452, -0.185310, 0.246558, 0.951246, -0.527518, 0.305721, 0.792628, 0.817754, 0.554723, -0.153493, 0.175059, 0.123698, 0.976757, -0.064560, -0.949174, 0.308061, -0.344522, -0.323431, 0.881304, -0.651019, -0.595072, 0.471236, 0.578307, -0.764202, 0.285582, 0.937600, -0.056872, -0.343032, -0.898571, -0.401443, -0.177242, 0.239467, -0.579742, 0.778816, -0.454078, -0.002350, 0.890959, 0.578286, -0.814557, -0.045618, -0.060241, -0.763322, 0.643204, -0.363894, -0.930405, -0.043917, 0.288465, -0.946959, 0.141625, -0.546578, 0.576549, 0.607326, 0.782565, -0.115962, 0.611674, 0.544881, -0.337552, 0.767570, -0.959831, -0.244713, 0.137263, 0.438414, 0.814427, 0.380135, 0.943764, -0.311961, -0.109501, -0.631694, -0.310992, 0.710103, 0.685430, 0.710182, 0.160709, 0.096748, 0.471056, 0.876782, 0.513770, -0.003168, 0.857922, -0.575420, -0.800158, 0.169228, -0.233129, 0.948335, 0.215202, -0.821116, 0.559553, -0.112557, -0.796056, 0.339694, 0.500903, 0.910650, 0.133184, 0.391125, 0.240406, -0.239312, 0.940710, 0.498580, -0.639217, 0.585508, 0.997852, -0.001922, 0.065473, -0.490770, 0.788039, 0.371670, 0.137120, 0.736330, 0.662583, -0.044953, -0.998846, -0.016883, -0.354060, -0.840741, 0.409630, -0.455729, -0.606172, -0.651818, -0.770915, 0.583057, 0.256388, 0.236443, -0.847294, 0.475592, 0.929074, -0.239849, 0.281593, -0.187444, 0.808212, 0.558263, -0.845490, -0.281278, 0.453904, 0.758200, -0.456413, 0.465640, 0.421717, 0.337689, 0.841499}; static float ps55 [165] = { -0.015909, 0.448575, 0.893603, 0.666417, -0.339498, 0.663799, 0.875151, -0.316481, 0.365993, -0.469502, -0.807589, 0.356885, 0.300782, 0.265277, 0.916056, -0.641373, 0.018210, 0.767013, 0.612013, 0.309996, 0.727560, -0.877396, 0.407800, 0.252736, -0.971698, 0.000287, 0.236227, 0.401943, 0.914315, -0.049703, -0.621052, -0.590604, -0.515249, -0.597297, -0.309859, 0.739746, 0.698082, -0.595744, 0.397204, -0.977334, -0.201859, -0.063799, -0.733807, -0.522444, 0.434257, 0.976089, -0.215734, 0.026650, -0.903853, -0.381318, 0.194029, -0.014070, -0.277146, 0.960725, -0.345197, -0.116239, 0.931304, 0.552654, -0.029334, 0.832894, -0.058518, 0.914358, 0.400655, 0.436426, -0.811225, 0.389162, 0.219989, -0.959757, 0.174560, 0.337259, -0.926936, -0.164459, 0.422095, -0.616459, 0.664691, 0.080279, -0.594703, 0.799927, -0.841672, -0.180149, 0.509053, -0.832739, 0.549684, -0.066282, -0.660227, 0.563262, 0.496826, 0.130126, -0.838760, 0.528723, 0.020582, 0.998479, 0.051142, -0.600168, 0.347650, 0.720374, 0.243140, -0.058419, 0.968230, -0.131827, -0.947270, 0.292064, 0.950626, 0.005396, 0.310291, -0.340449, 0.247329, 0.907151, 0.355941, -0.358806, 0.862881, 0.273073, 0.926311, 0.259575, 0.314832, 0.781978, 0.537951, -0.841584, 0.185419, 0.507304, -0.324866, 0.578840, 0.747934, -0.183515, -0.769541, 0.611661, -0.838030, -0.520321, -0.164233, -0.053234, 0.104383, 0.993111, 0.837970, 0.322207, 0.440441, 0.653416, -0.725000, -0.217765, 0.596317, 0.769839, 0.227494, -0.377327, 0.788545, 0.485614, 0.324956, 0.554280, 0.766275, -0.479965, -0.608981, 0.631487, 0.709230, 0.695980, -0.112268, 0.794714, -0.003197, 0.606976, -0.012685, 0.730467, 0.682831, -0.261559, -0.465580, 0.845472, -0.577327, 0.811806, -0.087549}; static float ps56 [168] = { -0.520068, -0.353303, 0.777629, -0.166496, -0.886506, 0.431724, -0.315085, 0.221733, 0.922798, -0.003832, 0.352646, 0.935749, -0.846862, 0.528154, 0.062274, -0.356128, -0.657155, 0.664319, 0.816219, 0.411889, 0.405134, -0.950968, -0.027798, 0.308038, -0.182603, -0.441971, 0.878247, -0.980866, 0.194460, -0.009339, -0.006141, -0.706497, 0.707689, 0.044773, 0.974405, 0.220297, -0.576024, 0.003527, 0.817425, 0.308583, 0.544317, 0.780061, 0.507227, -0.348368, 0.788264, -0.452919, 0.885578, -0.103034, -0.684323, -0.696510, -0.215812, 0.664361, -0.524628, 0.532344, 0.160124, -0.885473, 0.436232, -0.713710, 0.670900, -0.201277, 0.375576, 0.887838, 0.265869, -0.443845, 0.738719, 0.507244, -0.795474, 0.145941, 0.588151, 0.000000, -0.000000, 1.000000, 0.130077, -0.985644, 0.107640, -0.011531, 0.650254, 0.759629, 0.322444, -0.627657, 0.708573, 0.950047, 0.009801, 0.311954, -0.781659, -0.204361, 0.589276, -0.622445, 0.761227, 0.181919, 0.482789, 0.793530, -0.370438, 0.201864, 0.974290, -0.100045, -0.284166, -0.136822, 0.948962, 0.806896, 0.135313, 0.574986, -0.885639, 0.364493, -0.287728, -0.889178, -0.361076, 0.281046, -0.897715, 0.311783, 0.311287, 0.587032, 0.007783, 0.809526, -0.745122, -0.646269, 0.164713, -0.125835, 0.853303, 0.506003, 0.132472, -0.398015, 0.907764, 0.507452, 0.860771, -0.039559, -0.318724, 0.553237, 0.769638, 0.316005, 0.226166, 0.921407, -0.707147, 0.543845, 0.451858, 0.221071, 0.809247, 0.544286, -0.308431, 0.926689, 0.214751, -0.889993, -0.447593, -0.087021, 0.546896, 0.653271, 0.523585, 0.594357, 0.364880, 0.716660, -0.463003, 0.775496, -0.429226, -0.988053, -0.152969, -0.018744, 0.784792, -0.207287, 0.584066, -0.671699, -0.534738, 0.512714, 0.298089, -0.120230, 0.946936, -0.584389, 0.369064, 0.722691}; static float ps57 [171] = { 0.665408, 0.458591, 0.589005, 0.378260, 0.547667, 0.746311, 0.772045, -0.254063, 0.582579, -0.208126, -0.742529, 0.636659, 0.138385, -0.798334, 0.586099, 0.750396, 0.123783, 0.649295, -0.901149, 0.066572, 0.428368, -0.462962, 0.211995, 0.860654, 0.271035, -0.920438, 0.281662, 0.105101, -0.577745, 0.809423, -0.210078, 0.748062, 0.629500, 0.193096, 0.952612, 0.235043, 0.880229, 0.474446, -0.009834, -0.439789, 0.807861, 0.392360, -0.933100, 0.279155, -0.226708, -0.741437, 0.537681, -0.401460, -0.376305, 0.925006, 0.052517, -0.883412, 0.389487, 0.260543, -0.661648, -0.742220, 0.106450, 0.158412, 0.321376, 0.933608, 0.875021, 0.335607, 0.348864, 0.502572, 0.848903, 0.163658, 0.664228, -0.736310, -0.129031, -0.685850, 0.583474, 0.434934, -0.029410, -0.248062, 0.968298, 0.243574, -0.007366, 0.969854, -0.353224, -0.111956, 0.928816, 0.138545, 0.828568, 0.542476, 0.945681, 0.218998, -0.240264, -0.795832, -0.272062, 0.540956, 0.488159, 0.228953, 0.842188, 0.040276, -0.998730, 0.030281, -0.201511, 0.424307, 0.882812, 0.919985, -0.004926, 0.391922, 0.591938, -0.779162, 0.206194, -0.449253, -0.811861, 0.372900, -0.683536, -0.011523, 0.729826, -0.309256, -0.945490, 0.102025, 0.534944, 0.594904, -0.599937, 0.450533, -0.722702, 0.524139, -0.239671, -0.481254, 0.843180, -0.844352, 0.533305, -0.051537, 0.985801, 0.142638, 0.088608, -0.987091, 0.137053, 0.082872, 0.733312, 0.626785, 0.263427, -0.088311, -0.928230, 0.361373, 0.765942, 0.541243, -0.346972, 0.054159, 0.615469, 0.786298, 0.297773, -0.335848, 0.893609, 0.560419, -0.119224, 0.819583, -0.105514, 0.104676, 0.988893, 0.463308, 0.743448, 0.482318, -0.134864, 0.937811, 0.319879, -0.730466, 0.300858, 0.613110, 0.522285, -0.476888, 0.706962, -0.470911, 0.537748, 0.699335, -0.543084, -0.326176, 0.773737}; static float ps58 [174] = { 0.820117, -0.014660, 0.572008, 0.075174, 0.322588, 0.943550, 0.712592, -0.597969, 0.366941, 0.990451, -0.120492, -0.066989, -0.244907, 0.909521, 0.335845, 0.206946, -0.961050, 0.183182, 0.166497, 0.923535, 0.345488, -0.287177, -0.184945, 0.939854, -0.869715, -0.474466, 0.135934, -0.253629, -0.521925, 0.814412, -0.536671, 0.019953, 0.843556, -0.775379, -0.397640, 0.490580, 0.152543, -0.853345, 0.498531, -0.658757, -0.558407, -0.504203, 0.433341, 0.475421, 0.765631, -0.050036, 0.809510, 0.584971, 0.966651, -0.034297, 0.253789, -0.111704, -0.959148, 0.259919, 0.132551, 0.609991, 0.781243, -0.264386, 0.202911, 0.942829, -0.413268, -0.856470, 0.309305, -0.851318, 0.479498, 0.212931, 0.523185, 0.802034, 0.288129, 0.000000, 0.000000, 1.000000, 0.376379, 0.178894, 0.909030, 0.350548, -0.444177, 0.824513, -0.186802, -0.794590, 0.577695, -0.393594, 0.708904, 0.585268, 0.869675, 0.291154, 0.398616, 0.854829, -0.305202, 0.419666, -0.025552, 0.995595, 0.090211, -0.591713, 0.749755, 0.296215, -0.946301, -0.157041, 0.282581, 0.590209, -0.092048, 0.801986, 0.639519, -0.392490, 0.661035, 0.017423, -0.355465, 0.934527, -0.793401, -0.095373, 0.601181, -0.482708, 0.407404, 0.775252, -0.429416, 0.901447, 0.054727, 0.675238, 0.661677, -0.325942, 0.323937, 0.945635, 0.028978, -0.969457, -0.236566, -0.064723, 0.293938, -0.141491, 0.945294, 0.348290, 0.749225, 0.563344, 0.079284, -0.649286, 0.756401, -0.908323, 0.404821, -0.105210, 0.670186, 0.253293, 0.697634, -0.690301, 0.517339, 0.505811, -0.491313, -0.626713, 0.604848, 0.805850, 0.560120, 0.192018, -0.634032, -0.773099, 0.017950, -0.907334, 0.186460, 0.376798, -0.726473, 0.221679, 0.650457, 0.431296, -0.678583, 0.594567, -0.188334, 0.543588, 0.817950, -0.716180, 0.697283, -0.029708, -0.488552, 0.823272, -0.289034, -0.558508, -0.323605, 0.763773}; static float ps59 [177] = { 0.338641, 0.463168, 0.819023, -0.912123, -0.337929, 0.232025, -0.170514, 0.950043, 0.261426, 0.148012, 0.935326, 0.321337, 0.344380, 0.105944, 0.932833, -0.367740, 0.617429, 0.695376, 0.603382, 0.246002, 0.758560, -0.949114, 0.026120, 0.313847, 0.268861, -0.239866, 0.932833, 0.238882, 0.745278, 0.622492, 0.073615, 0.308465, 0.948383, 0.267109, -0.756717, 0.596685, -0.858898, 0.512110, 0.006108, -0.061681, -0.311071, 0.948383, 0.795432, 0.007442, 0.605997, 0.114724, -0.562175, 0.819023, 0.065139, -0.927031, 0.369284, -0.255386, -0.911878, 0.321337, -0.007441, 0.604442, 0.796614, -0.819837, -0.198732, 0.537003, 0.719913, -0.338368, 0.605997, -0.994194, -0.107426, 0.006108, -0.903924, -0.405416, -0.136230, 0.652619, -0.745339, 0.136230, -0.804261, 0.500179, -0.320913, 0.112239, -0.992161, 0.054952, 0.791324, 0.364309, 0.491005, 0.445673, 0.815478, 0.369284, -0.381172, -0.241300, 0.892458, -0.245876, 0.378237, 0.892458, -0.591658, -0.407913, 0.695376, 0.558255, 0.576471, 0.596685, 0.921455, -0.201230, 0.332305, -0.688206, 0.687414, 0.232025, -0.797389, 0.174136, 0.577795, 0.551049, 0.792466, -0.261425, 0.715674, 0.641155, 0.277003, -0.728519, -0.539288, 0.422408, 0.445895, -0.475147, 0.758560, -0.324654, 0.070899, 0.943172, 0.939558, 0.119358, 0.320913, 0.564491, -0.123275, 0.816182, -0.436847, -0.702046, 0.562402, -0.629803, -0.043613, 0.775529, 0.567406, -0.661033, 0.491005, -0.000000, -0.000000, 1.000000, 0.104404, -0.820246, -0.562402, 0.213355, 0.976975, 0.000000, -0.554284, 0.302197, 0.775529, 0.383231, -0.881137, 0.277003, -0.662350, 0.522417, 0.537003, 0.437373, -0.793899, -0.422408, -0.258746, -0.546312, 0.796614, 0.774380, 0.628334, -0.074373, -0.873595, 0.371929, 0.313847, -0.976975, 0.213355, 0.000000, -0.093561, -0.777014, 0.622492, 0.441937, -0.893958, -0.074373, 0.515637, 0.855043, 0.054952}; static float ps60 [180] = { 0.654875, 0.355659, 0.666817, 0.271924, 0.933965, 0.231877, -0.118810, 0.110437, 0.986756, -0.326879, 0.866547, 0.377155, -0.394817, -0.108337, 0.912350, 0.906253, -0.349334, 0.238058, 0.566330, -0.470917, 0.676393, -0.558540, 0.665203, 0.495518, 0.648904, 0.611989, 0.452098, -0.435216, 0.497941, 0.750095, -0.060085, 0.972644, 0.224396, 0.290295, -0.619397, 0.729435, -0.008761, -0.548745, 0.835944, 0.098843, 0.637960, 0.763700, -0.162887, -0.917294, 0.363371, 0.095045, -0.821836, 0.561740, -0.214960, 0.721063, 0.658681, 0.741627, 0.039918, 0.669624, -0.847852, -0.200363, 0.490920, -0.943158, 0.304222, 0.133799, -0.215650, -0.732737, 0.645439, -0.060360, -0.223624, 0.972805, 0.814723, 0.561120, 0.146185, 0.265965, -0.335097, 0.903866, 0.441982, -0.764517, 0.469218, -0.566124, 0.807614, -0.165116, 0.716591, -0.584614, 0.380425, 0.331272, -0.943028, -0.030940, 0.465735, 0.168038, 0.868823, -0.480716, -0.789299, 0.381994, 0.961362, 0.253123, 0.108216, 0.920360, -0.003999, 0.391053, 0.393331, 0.915435, -0.085260, 0.852276, 0.324551, 0.410233, 0.571183, 0.799445, 0.186110, 0.535413, -0.167226, 0.827870, -0.442791, 0.203222, 0.873291, -0.143848, 0.431269, 0.890682, 0.893460, 0.414910, -0.171983, -0.795825, 0.511407, 0.324230, 0.399108, 0.523871, 0.752511, 0.806535, -0.590581, 0.026762, -0.691380, -0.710203, 0.132686, -0.973847, -0.080055, 0.212633, -0.052107, -0.996034, 0.072118, -0.696694, 0.034360, 0.716545, -0.626272, -0.286200, 0.725171, 0.994108, -0.072683, 0.080414, -0.738939, -0.519516, 0.429037, -0.702182, 0.353175, 0.618230, -0.505053, -0.581614, 0.637689, 0.371230, 0.770180, 0.518664, 0.050870, 0.858370, 0.510502, 0.170569, 0.325484, 0.930036, -0.312160, -0.422488, 0.850917, -0.887018, 0.152189, 0.435932, -0.605767, 0.776332, 0.174228, 0.215791, -0.937112, 0.274326, 0.210754, -0.013433, 0.977447, 0.787853, -0.274495, 0.551307}; static float ps61 [183] = { 0.711156, -0.521238, 0.471772, 0.825805, 0.103849, 0.554312, 0.236383, 0.809263, 0.537788, 0.667514, -0.712896, 0.214953, -0.024701, 0.933635, 0.357372, -0.529212, -0.780306, 0.333253, -0.768617, 0.156595, 0.620247, 0.811014, -0.221622, 0.541425, 0.256857, -0.585829, 0.768654, -0.783756, -0.168342, 0.597819, 0.922436, 0.260420, 0.285120, 0.155602, -0.836028, 0.526161, -0.063482, -0.691472, 0.719608, -0.702744, -0.507748, 0.498341, 0.470004, 0.590868, 0.655722, -0.864986, 0.376390, 0.331859, -0.379188, 0.892039, -0.245933, 0.348611, 0.065688, 0.934963, 0.046808, -0.967541, 0.248340, -0.199968, -0.865116, 0.459987, -0.647223, 0.681775, 0.341006, 0.036415, -0.055852, 0.997775, 0.255655, -0.964692, -0.063331, -0.197936, 0.495458, 0.845779, 0.555199, 0.740447, 0.378803, 0.615572, -0.082775, 0.783722, -0.313221, -0.938246, 0.146922, 0.580413, 0.813958, 0.024380, 0.547354, -0.412122, 0.728395, 0.336118, 0.380412, 0.861575, -0.356683, 0.857520, 0.370725, -0.556651, -0.007596, 0.830712, 0.739159, 0.451895, 0.499434, 0.612270, 0.256188, 0.747993, -0.672867, 0.462511, 0.577351, 0.025205, -0.387849, 0.921378, -0.780170, -0.595100, -0.192850, 0.959601, -0.078081, 0.270313, 0.118420, 0.607212, 0.785666, -0.996699, -0.074532, 0.032204, -0.280011, -0.170904, 0.944662, -0.921415, -0.388399, 0.011887, -0.416270, 0.650719, 0.635047, 0.885276, -0.407510, 0.224100, 0.813508, -0.578233, -0.062058, -0.937095, 0.043562, 0.346345, -0.967061, 0.249731, 0.049274, -0.423511, -0.662178, 0.618190, -0.557333, -0.340449, 0.757281, -0.326883, -0.917291, -0.227428, 0.552853, -0.830607, -0.066672, -0.274164, -0.475434, 0.835941, 0.043395, 0.282633, 0.958246, -0.113553, 0.771535, 0.625970, -0.766507, -0.616055, 0.181501, -0.256259, 0.154151, 0.954237, 0.458667, -0.715745, 0.526625, 0.066042, 0.996389, 0.053365, -0.491295, 0.326140, 0.807628, 0.324296, -0.258502, 0.909950, -0.900329, -0.294326, 0.320592}; static float ps62 [186] = { 0.613428, -0.404937, 0.678036, 0.663289, -0.066595, 0.745394, -0.146632, 0.988109, -0.046257, 0.775482, -0.507281, 0.375890, 0.851827, 0.434292, -0.292885, 0.659022, -0.598760, -0.455166, 0.046419, -0.938290, 0.342719, -0.418627, -0.805342, 0.419734, -0.175218, 0.772659, 0.610161, -0.145225, -0.355369, -0.923376, -0.703753, 0.331392, 0.628419, 0.988511, 0.063222, 0.137295, -0.862812, 0.409674, 0.296181, -0.134150, -0.810783, 0.569767, 0.121550, 0.653868, 0.746782, -0.256544, -0.379826, 0.888773, 0.653627, 0.523931, 0.546140, 0.407762, -0.210195, 0.888566, -0.159395, 0.511415, 0.844422, -0.016639, -0.606255, 0.795096, 0.692030, -0.705754, -0.151673, 0.212407, -0.779178, 0.589716, -0.114627, -0.110167, 0.987281, 0.109259, -0.337709, 0.934888, 0.441278, -0.895450, -0.058678, -0.812304, -0.217626, 0.541111, -0.563562, -0.306087, 0.767273, 0.134489, 0.984787, 0.110033, -0.158282, 0.944964, 0.286338, -0.238416, -0.951502, 0.194425, 0.782679, 0.621810, 0.027685, 0.831801, -0.205354, 0.515691, 0.523338, -0.681507, 0.511533, -0.502676, -0.864166, 0.023107, 0.329227, -0.536210, 0.777231, 0.376913, 0.884276, 0.275668, -0.452906, 0.286030, 0.844431, -0.884005, 0.111203, 0.454059, 0.390861, 0.725412, 0.566573, -0.964569, -0.119653, 0.235136, -0.977954, 0.180028, 0.105814, 0.449170, 0.153922, 0.880088, 0.662248, 0.704074, -0.256333, -0.684393, 0.021474, 0.728797, -0.436913, 0.580414, 0.687188, 0.704373, 0.242667, 0.667062, 0.643867, 0.709475, 0.286496, -0.370502, -0.611014, 0.699564, -0.418336, -0.040287, 0.907399, 0.649737, -0.738626, 0.179650, -0.151495, 0.208735, 0.966167, 0.374461, -0.881523, 0.287570, -0.102890, -0.876525, -0.470232, -0.647456, -0.532607, 0.545097, 0.420003, 0.463570, 0.780192, -0.430112, 0.813479, 0.391478, 0.176156, 0.023979, 0.984070, 0.944071, -0.243921, 0.221884, -0.890639, -0.102158, -0.443086, 0.865679, -0.499390, 0.034792, -0.938963, -0.343729, -0.014139, 0.856123, 0.403896, 0.322367}; static float ps63 [189] = { 0.557048, 0.254557, 0.790505, 0.501828, -0.856777, 0.118753, 0.366133, -0.832181, 0.416439, 0.458902, -0.342363, 0.819876, 0.876786, -0.393604, 0.276264, 0.684179, -0.418767, 0.597104, -0.504411, -0.622034, 0.598868, 0.763420, 0.588533, 0.266118, 0.378565, 0.925263, 0.024027, -0.973098, -0.005409, 0.230330, 0.036207, 0.539129, 0.841445, -0.153898, 0.260962, 0.953003, 0.459908, 0.699647, 0.546790, 0.540504, 0.799090, 0.263271, -0.893126, 0.264375, 0.363912, -0.734197, 0.548949, 0.399512, 0.189445, -0.236455, 0.952995, 0.082573, -0.753309, 0.652463, -0.094532, 0.914517, 0.393347, 0.404328, -0.625886, 0.666922, -0.893846, -0.316945, 0.317153, -0.629940, 0.756256, 0.176786, -0.333618, 0.925140, 0.181148, -0.445620, 0.770837, 0.455230, 0.293398, -0.505611, -0.811341, -0.729767, 0.241250, 0.639717, 0.060323, -0.918212, 0.391468, -0.210101, -0.597555, 0.773812, -0.552993, 0.522508, 0.648987, 0.868961, 0.493684, -0.034392, 0.639407, -0.655156, 0.402404, -0.481084, 0.225299, 0.847230, 0.126826, -0.519656, 0.844910, -0.625969, -0.073665, 0.776361, -0.479368, -0.821721, 0.308191, -0.181997, -0.960933, 0.208531, 0.802857, 0.156738, 0.575198, 0.237577, 0.906435, 0.349188, 0.980397, 0.196412, 0.015613, 0.144655, 0.763767, 0.629074, -0.724790, -0.595435, 0.346607, -0.844126, -0.054426, 0.533376, -0.186549, 0.743670, 0.641993, 0.845555, -0.166505, 0.507261, 0.648531, -0.082191, 0.756737, -0.144061, -0.319350, 0.936623, -0.237930, -0.814969, 0.528408, 0.754640, -0.646528, 0.111892, -0.333825, -0.053261, 0.941129, 0.383661, 0.012884, 0.923384, 0.897479, 0.313172, 0.310570, -0.196705, 0.974233, -0.110349, -0.454846, -0.360333, 0.814417, 0.200471, 0.270688, 0.941562, 0.680149, 0.467463, 0.564691, 0.979258, -0.201661, 0.019660, 0.364240, 0.509525, 0.779560, -0.875779, 0.470288, 0.108808, -0.664927, -0.745382, 0.047733, -0.713694, -0.359820, 0.600975, -0.000000, -0.000000, 1.000000, 0.962848, -0.010571, 0.269836, 0.039092, 0.994194, 0.100253}; static float ps64 [192] = { 0.797023, 0.136705, 0.588273, -0.278590, 0.948576, 0.150306, 0.269452, -0.711937, 0.648492, -0.645004, -0.682074, 0.344595, -0.997625, 0.026724, -0.063488, -0.015834, 0.014472, 0.999770, 0.839210, 0.379789, -0.389213, 0.208215, -0.891081, 0.403263, 0.539573, -0.252383, 0.803221, -0.132838, -0.935923, 0.326194, 0.827364, -0.548564, -0.120610, 0.307510, -0.090828, 0.947200, 0.218118, 0.504810, 0.835219, 0.726209, -0.666170, 0.169821, -0.332668, -0.557425, 0.760663, -0.328467, 0.034648, 0.943880, 0.291451, 0.863987, 0.410588, -0.524955, 0.742151, -0.416694, -0.122014, 0.589755, 0.798312, 0.949992, 0.086143, -0.300156, -0.055576, 0.316879, 0.946836, -0.141862, 0.824696, 0.547496, 0.601245, -0.789791, -0.121382, 0.734088, 0.444365, 0.513473, 0.661510, 0.749911, 0.006173, -0.611822, -0.502190, 0.611129, -0.830952, 0.381428, 0.405009, -0.370819, 0.344175, 0.862576, -0.762479, -0.186326, 0.619604, 0.065038, -0.295413, 0.953153, 0.926285, -0.117378, 0.358076, -0.063469, -0.795508, 0.602610, 0.768559, -0.194100, 0.609624, 0.446139, -0.883423, 0.143262, -0.834875, -0.510044, -0.206975, -0.423944, -0.882753, 0.202533, -0.522214, -0.248724, 0.815738, -0.378698, -0.766359, 0.518923, -0.637493, 0.376534, 0.672179, -0.959665, 0.216672, 0.179153, 0.304862, -0.464001, 0.831722, -0.239236, -0.285484, 0.928044, 0.532848, 0.370235, 0.760920, -0.407192, 0.822667, 0.396753, -0.835774, 0.104423, 0.539052, 0.927325, 0.216334, 0.305397, 0.923215, -0.362997, 0.126124, -0.125640, 0.985406, -0.114845, -0.419397, -0.897620, -0.135587, 0.456964, 0.642255, 0.615380, 0.611904, 0.712455, 0.343485, 0.580539, 0.068549, 0.811342, -0.154722, -0.987867, -0.013398, -0.651714, 0.630831, 0.421095, 0.276048, 0.217697, 0.936165, -0.837437, -0.532713, 0.122130, -0.413285, 0.619494, 0.667400, 0.576347, -0.522314, 0.628500, 0.792823, -0.455369, 0.405057, -0.607712, 0.077141, 0.790402, 0.963101, 0.267540, -0.029315, 0.006778, 0.955284, 0.295611, -0.020026, -0.576391, 0.816928, 0.137929, 0.746604, 0.650813}; static float ps65 [195] = { 0.062708, -0.858600, 0.508797, 0.584679, -0.677329, -0.446514, 0.223552, -0.677808, 0.700429, -0.797685, -0.192161, -0.571640, -0.833387, 0.549920, -0.055262, -0.110259, -0.990666, -0.080144, -0.440792, -0.643039, 0.626261, -0.668866, 0.731483, 0.132480, -0.295096, 0.303587, 0.905954, -0.418542, -0.895656, -0.150407, 0.582057, 0.146941, 0.799761, 0.647646, 0.760598, -0.045227, -0.142844, 0.594825, 0.791062, 0.151006, -0.177234, 0.972515, -0.005207, 0.469083, -0.883138, 0.326648, -0.424895, 0.844254, 0.794224, -0.398328, 0.458850, 0.201001, 0.633134, 0.747489, -0.478759, 0.146635, -0.865614, -0.863722, -0.251902, 0.436497, -0.313970, 0.888937, -0.333487, -0.105369, 0.945447, 0.308265, 0.911225, -0.055942, 0.408093, -0.762107, -0.036203, 0.646438, -0.069980, 0.088294, 0.993633, -0.955156, 0.269870, 0.121848, 0.364629, 0.391243, 0.844970, -0.261306, -0.854740, 0.448484, 0.044670, 0.377010, 0.925131, 0.733289, -0.136689, 0.666036, 0.005037, 0.808941, 0.587869, -0.357268, -0.920554, 0.157927, -0.967919, -0.030735, 0.249375, 0.835161, 0.542783, 0.088843, -0.129061, -0.689712, 0.712489, 0.270791, 0.111467, 0.956163, -0.342540, -0.435450, 0.832496, -0.581814, -0.245630, 0.775344, -0.934059, -0.250560, -0.254468, 0.949492, 0.302087, -0.084904, 0.433742, 0.712721, 0.551268, 0.306000, -0.781460, -0.543769, 0.623541, 0.721745, 0.300468, 0.872864, -0.180568, -0.453324, -0.522232, 0.845263, -0.113160, -0.024672, -0.973867, 0.225775, 0.805004, 0.534289, -0.257882, 0.480688, -0.700513, 0.527467, 0.778134, 0.477959, 0.407508, -0.410622, -0.015340, 0.911677, -0.223380, 0.974566, -0.017964, -0.446061, 0.525145, 0.724743, 0.228546, 0.890852, 0.392619, 0.595995, 0.464027, 0.655338, 0.682614, 0.462275, -0.565986, -0.591730, 0.195033, 0.782188, 0.996991, 0.000177, 0.077517, 0.585962, -0.442002, 0.679178, -0.176851, -0.209334, 0.961719, -0.573411, -0.738938, 0.353794, -0.407794, 0.883175, 0.231746, -0.820888, 0.490498, 0.292497, 0.932807, -0.297778, 0.202977, -0.703978, 0.402970, 0.584833, 0.688012, -0.657035, 0.308131}; static float ps66 [198] = { -0.521329, -0.419036, 0.743387, -0.269227, -0.644814, 0.715355, -0.997659, 0.020268, 0.065314, 0.168269, -0.024156, 0.985445, -0.796049, -0.537148, 0.278889, 0.841662, 0.479152, 0.249036, 0.913646, -0.030944, 0.405332, -0.572064, 0.768372, -0.286963, 0.742061, -0.040706, 0.669096, 0.600592, -0.589687, 0.539962, -0.808281, 0.527345, -0.261894, -0.580852, -0.776337, 0.244770, -0.790538, 0.523367, 0.318019, -0.779942, -0.353154, 0.516694, 0.968496, 0.174376, 0.177785, 0.318739, -0.779021, 0.539936, -0.303277, -0.827253, 0.472944, 0.037843, -0.634374, 0.772099, 0.742627, -0.351341, -0.570144, -0.177771, 0.528871, 0.829875, 0.427570, 0.496317, 0.755549, -0.011512, 0.265032, 0.964171, -0.569251, -0.632513, 0.525243, 0.747034, 0.664545, 0.017896, -0.141830, -0.986789, -0.078302, 0.008223, -0.842871, 0.538053, 0.485149, 0.871816, 0.067582, 0.833340, 0.260442, 0.487559, -0.606835, 0.157875, 0.778991, -0.468262, 0.449670, 0.760610, 0.732211, -0.681072, 0.002805, 0.012707, 0.969010, -0.246693, 0.296985, 0.893786, 0.336076, -0.589146, 0.763637, 0.264133, -0.935940, -0.170165, 0.308320, -0.315512, 0.212198, 0.924891, 0.128832, 0.541673, 0.830658, -0.132611, -0.065210, 0.989021, 0.929384, -0.213945, -0.300788, 0.341311, -0.560699, 0.754403, 0.625323, 0.251953, 0.738574, -0.318457, 0.887049, 0.334260, 0.661159, 0.526278, 0.534696, -0.680925, -0.145050, 0.717845, 0.283771, -0.920780, 0.267655, -0.461396, 0.887194, 0.000685, 0.599663, -0.327682, 0.730089, -0.166145, 0.984635, 0.053762, 0.604293, 0.730771, 0.317496, 0.338320, -0.284010, 0.897150, -0.426997, -0.105397, 0.898090, -0.255969, 0.747019, 0.613549, -0.910636, 0.410196, 0.049805, 0.368493, 0.730404, 0.575085, -0.958369, 0.223458, -0.177752, -0.310263, -0.932279, 0.185992, 0.048358, -0.358445, 0.932298, 0.308507, 0.255294, 0.916323, -0.018286, 0.928071, 0.371955, -0.246306, -0.379783, 0.891683, -0.546466, 0.639696, 0.540522, 0.928879, 0.365676, -0.058868, 0.057272, 0.772644, 0.632251, 0.809762, -0.325116, 0.488451, 0.491885, -0.010475, 0.870597, -0.844861, 0.035702, 0.533794}; static float ps67 [201] = { 0.317637, 0.442274, 0.838749, -0.849332, -0.085926, 0.520818, 0.172297, 0.187230, 0.967088, -0.812030, 0.237130, 0.533269, -0.036417, -0.992662, 0.115304, 0.937603, 0.159011, 0.309220, 0.847487, -0.101735, 0.520976, -0.423868, -0.129491, 0.896420, -0.281093, -0.762496, 0.582741, -0.760362, -0.421726, 0.493960, -0.562359, -0.660399, 0.497620, 0.059769, 0.974510, 0.216237, 0.532808, -0.796335, 0.286299, -0.182366, -0.294414, 0.938117, 0.360629, 0.694556, 0.622526, 0.051750, -0.727669, 0.683974, 0.527281, -0.849672, -0.005697, -0.212257, 0.894780, 0.392830, -0.323703, -0.895439, 0.305621, -0.648645, 0.075837, 0.757304, -0.020148, -0.904853, 0.425246, -0.807626, -0.548734, 0.215942, -0.160576, 0.736564, 0.657030, 0.608971, 0.691374, 0.388789, 0.296908, -0.810142, 0.505485, 0.608542, -0.611151, 0.506132, -0.303007, 0.498676, 0.812101, -0.654211, -0.239455, 0.717405, 0.241860, -0.965874, -0.092686, 0.252992, -0.942078, 0.220191, 0.960217, -0.151645, 0.234494, 0.938324, 0.342940, 0.044055, 0.749387, -0.648263, -0.134811, -0.133208, 0.037626, 0.990374, 0.110554, -0.162880, 0.980433, -0.887420, 0.383659, 0.255523, 0.570765, 0.815779, 0.093449, 0.768473, -0.616979, 0.169664, 0.369721, -0.590993, 0.716962, -0.930385, 0.365088, -0.033082, -0.189909, -0.565571, 0.802536, -0.453758, 0.675898, 0.580746, -0.587100, 0.391177, 0.708727, 0.351245, 0.875159, 0.332751, 0.830102, -0.403780, 0.384569, 0.536545, 0.236778, 0.809972, -0.594974, -0.775441, 0.211419, -0.065176, 0.360860, 0.930340, 0.112134, -0.465838, 0.877736, -0.999576, -0.028807, 0.004191, -0.315475, -0.948922, -0.004622, 0.100032, 0.848008, 0.520458, 0.650611, -0.059055, 0.757111, 0.385669, -0.017099, 0.922479, 0.656407, -0.355616, 0.665332, -0.469371, -0.473257, 0.745465, -0.506338, 0.806431, 0.305435, 0.604214, 0.487827, 0.630040, 0.077453, 0.610754, 0.788023, 0.787944, 0.608906, 0.091532, 0.779666, 0.211016, 0.589571, -0.704219, 0.552831, 0.445481, -0.384157, 0.199442, 0.901469, -0.932572, -0.249715, 0.260678, 0.816668, 0.447074, 0.364937, 0.404433, -0.316817, 0.857940, -0.959215, 0.088990, 0.268305}; static float ps68 [204] = { -0.085763, -0.964111, 0.251266, 0.938348, 0.244179, -0.244702, 0.015517, 0.939415, 0.342430, 0.199039, 0.975076, 0.098036, -0.590522, 0.786338, 0.181540, 0.321964, -0.452468, 0.831632, -0.933574, -0.355526, -0.045173, 0.045990, -0.611951, 0.789557, -0.820674, 0.552150, 0.147056, -0.164075, 0.809871, 0.563195, 0.653538, 0.494670, 0.572878, 0.409726, 0.662238, 0.627348, 0.294572, 0.168039, 0.940739, -0.015767, -0.831829, 0.554808, -0.768714, 0.142691, 0.623473, 0.227683, 0.501252, 0.834809, 0.407978, -0.910495, 0.067478, 0.005374, 0.308107, 0.951336, 0.680297, -0.726162, 0.099423, -0.744245, -0.411600, 0.526009, 0.961121, -0.268478, -0.064549, 0.590157, 0.043909, 0.806093, 0.874945, -0.455584, 0.164055, -0.372325, -0.915384, 0.153120, 0.282219, -0.734125, 0.617586, 0.538673, -0.552163, 0.636355, -0.681672, 0.579772, 0.446304, -0.500118, -0.441654, 0.744865, -0.203562, -0.425113, 0.881953, -0.385692, 0.603716, 0.697688, 0.046522, -0.026691, 0.998561, -0.632651, -0.161122, 0.757491, 0.499006, 0.346401, 0.794355, -0.622833, -0.753101, 0.211937, 0.474217, -0.798668, 0.370469, -0.617152, -0.704248, -0.350940, -0.315320, 0.364049, 0.876380, -0.322145, -0.835813, 0.444567, 0.771345, 0.223650, 0.595824, -0.348680, -0.177220, 0.920334, -0.283111, 0.929385, 0.236836, -0.563997, -0.654477, 0.503555, -0.518349, -0.848582, -0.105937, -0.949384, 0.164767, -0.267437, -0.855276, 0.338669, 0.392181, 0.129119, 0.768832, 0.626279, -0.842388, -0.129177, 0.523159, 0.603799, -0.265127, 0.751754, -0.269839, -0.666224, 0.695221, -0.817205, -0.523754, 0.240536, 0.203765, -0.922101, 0.328953, -0.610245, 0.393163, 0.687767, -0.446865, 0.773167, 0.450027, 0.818317, -0.064306, 0.571159, -0.952002, 0.065113, 0.299086, 0.100906, -0.994893, 0.002310, -0.225876, 0.080369, 0.970835, -0.078474, 0.588641, 0.804577, 0.701967, -0.602378, 0.379978, 0.796508, -0.346349, 0.495598, -0.768169, -0.637231, -0.062079, -0.835166, -0.445522, -0.322502, -0.524787, 0.117184, 0.843129, 0.935737, 0.144377, 0.321795, 0.352995, -0.146893, 0.924022, 0.059074, -0.311021, 0.948565, 0.329624, 0.864448, 0.379576, -0.998993, -0.040829, -0.018605}; static float ps69 [207] = { 0.420628, -0.420531, 0.803881, -0.955900, -0.252851, 0.149406, 0.445538, 0.386313, 0.807625, -0.062686, -0.284350, 0.956669, 0.797773, -0.154844, 0.582736, 0.410010, 0.647265, 0.642605, -0.125944, 0.909929, 0.395181, -0.940963, 0.014955, 0.338179, 0.838786, 0.435577, 0.326668, 0.072243, 0.016055, 0.997258, 0.756281, -0.642462, 0.123619, -0.962368, -0.205928, -0.177315, -0.820002, 0.543571, 0.179242, 0.181352, 0.953236, 0.241772, 0.823745, -0.424932, 0.375336, -0.624278, 0.763645, 0.164690, 0.607192, -0.684901, 0.402776, -0.420986, 0.794663, 0.437357, 0.685692, 0.391997, 0.613322, -0.662210, 0.592995, 0.458078, 0.153836, 0.825716, 0.542704, -0.640720, -0.751820, 0.155708, -0.780969, 0.044197, 0.623005, -0.924932, 0.365390, -0.104839, 0.256451, -0.209806, 0.943512, -0.999426, 0.033783, -0.002508, 0.140922, 0.609548, 0.780123, 0.427064, 0.831815, 0.354540, -0.640135, -0.230680, 0.732813, -0.642727, 0.336852, 0.688064, 0.427344, 0.903572, 0.030584, 0.569900, -0.156051, 0.806760, -0.538308, -0.715705, 0.444961, -0.687274, -0.473515, 0.550852, 0.138662, 0.985251, -0.100271, -0.830188, 0.321164, 0.455676, -0.440392, -0.549435, 0.710054, 0.312408, -0.852421, 0.419260, -0.852919, -0.238280, 0.464492, -0.432723, 0.587829, 0.683527, -0.349580, -0.890891, 0.290012, -0.373471, 0.916881, 0.140885, -0.265879, -0.027223, 0.963622, -0.120879, 0.243468, 0.962347, -0.084791, 0.990814, 0.105346, 0.863643, 0.143914, 0.483124, 0.652587, -0.442915, 0.614781, -0.021002, -0.920479, 0.390228, -0.241028, -0.779617, 0.578016, -0.809956, -0.519053, 0.273046, 0.661961, 0.120415, 0.739802, 0.383598, -0.667796, 0.637887, -0.373924, -0.298775, 0.878017, 0.136056, -0.518754, 0.844028, 0.209411, -0.963582, 0.166303, -0.150185, 0.748629, 0.645754, 0.169462, 0.336732, 0.926226, -0.945715, 0.271061, 0.179300, 0.073097, -0.760690, 0.644986, 0.944898, -0.112964, 0.307257, 0.675529, 0.722847, 0.145442, -0.543015, 0.037762, 0.838874, 0.637760, 0.634245, 0.437031, 0.385752, 0.090555, 0.918148, 0.511837, -0.846823, 0.144616, 0.862678, 0.505056, 0.026565, -0.157444, -0.564627, 0.810190, -0.148503, 0.520199, 0.841035, -0.399512, 0.310350, 0.862597}; static float ps70 [210] = { -0.632083, -0.100805, 0.768316, -0.326319, 0.315787, 0.890952, -0.164525, 0.595720, 0.786161, -0.794836, 0.604268, -0.055646, -0.949016, -0.310929, 0.051889, 0.332731, 0.791680, 0.512379, 0.214754, 0.145336, 0.965794, -0.652071, -0.449212, 0.610747, -0.820826, 0.102655, 0.561878, -0.399404, 0.006705, 0.916751, -0.844610, -0.413921, 0.339563, 0.852303, 0.436193, 0.288643, 0.220917, -0.945682, 0.238498, -0.106029, 0.075760, 0.991473, -0.445136, -0.662910, 0.602000, 0.524653, 0.256073, 0.811890, -0.954620, 0.128510, -0.268675, -0.744274, 0.395867, 0.537908, 0.470998, 0.852656, 0.226138, 0.469785, 0.558145, 0.683941, -0.168574, -0.797514, 0.579271, 0.649231, -0.497422, 0.575388, -0.023370, 0.371988, 0.927943, -0.604009, 0.653568, 0.456095, -0.098207, -0.949890, 0.296756, -0.854094, 0.414387, -0.314337, -0.454483, -0.349542, 0.819308, -0.409544, 0.852290, 0.325385, 0.140685, 0.656402, 0.741177, -0.927526, 0.227126, 0.296833, 0.326536, -0.370787, 0.869420, 0.717048, 0.676585, 0.167558, -0.813972, -0.575288, 0.080573, 0.089537, -0.663921, 0.742423, -0.304166, -0.951807, 0.039325, -0.818931, 0.516109, 0.250964, -0.117196, 0.945919, 0.302494, 0.522428, -0.841223, 0.139331, 0.185582, 0.944552, 0.270890, -0.941888, 0.335890, -0.005052, -0.229541, -0.559632, 0.796318, -0.390544, -0.853893, 0.344009, -0.631330, 0.762385, 0.142099, -0.204785, -0.232598, 0.950769, -0.723491, -0.370106, -0.582738, 0.623317, 0.642327, 0.445973, -0.602419, 0.222504, 0.766540, -0.314794, 0.947708, 0.052484, 0.814766, -0.202553, 0.543258, 0.000187, 0.999997, 0.002594, 0.670239, -0.664066, 0.331355, 0.591760, -0.273477, 0.758308, -0.577294, -0.811804, 0.087789, 0.271795, 0.421008, 0.865378, 0.695603, 0.033665, 0.717637, -0.478670, 0.518876, 0.708268, -0.294052, 0.759162, 0.580695, 0.434338, -0.051156, 0.899296, -0.809663, -0.198506, 0.552306, 0.420325, -0.786484, 0.452514, 0.653847, 0.666597, -0.357956, 0.998864, -0.032942, -0.034444, 0.123168, -0.146201, 0.981557, -0.867207, -0.121609, -0.482870, 0.129424, -0.848570, 0.513010, 0.025912, -0.426779, 0.903984, 0.962944, 0.174971, 0.205243, -0.949079, -0.095741, 0.300138, 0.010281, 0.835840, 0.548877, 0.386863, -0.607474, 0.693767}; static float ps71 [213] = { -0.237232, -0.434598, 0.868819, 0.925021, -0.046467, 0.377062, -0.623051, -0.748151, 0.228205, -0.763643, -0.644402, -0.039950, -0.627166, -0.589647, 0.508900, 0.626948, 0.696147, 0.349736, -0.377969, -0.808529, 0.451022, 0.413352, -0.436620, 0.799064, -0.635981, -0.171910, -0.752313, -0.195374, 0.078648, 0.977570, 0.172595, 0.798800, 0.576306, -0.836589, 0.003710, 0.547819, 0.490691, -0.662234, 0.566276, -0.706667, 0.611619, -0.355730, 0.268016, -0.198439, 0.942756, -0.367488, -0.912757, 0.178402, 0.494805, -0.820738, 0.285581, -0.956870, 0.075733, 0.280470, 0.423657, 0.414067, 0.805645, -0.972735, 0.195551, -0.124685, -0.654653, 0.547333, 0.521398, 0.367707, 0.863828, 0.344373, 0.997433, 0.067619, -0.023562, 0.852443, -0.343659, 0.394005, 0.388250, 0.118823, 0.913862, -0.839948, 0.324036, 0.435303, -0.286392, 0.906302, 0.310800, -0.154186, 0.616159, 0.772382, -0.063527, -0.206550, 0.976372, 0.825931, 0.215863, 0.520807, -0.812209, -0.512991, 0.277771, -0.409927, 0.716178, 0.564844, 0.226566, -0.951331, 0.208893, -0.177766, 0.364900, 0.913918, -0.681855, 0.257483, 0.684672, -0.856609, 0.504149, -0.109793, 0.103191, 0.059261, 0.992895, -0.386083, -0.155965, 0.909183, 0.222553, -0.847523, 0.481845, -0.925340, -0.228220, 0.302757, -0.665478, 0.401600, -0.629171, -0.460813, 0.173957, 0.870282, 0.103300, -0.992530, -0.064906, 0.081495, 0.868377, -0.489163, 0.129235, 0.344965, 0.929676, 0.439136, 0.661044, 0.608424, -0.223298, -0.971323, -0.081669, -0.674205, 0.737768, -0.033851, 0.219195, -0.667398, 0.711711, -0.772370, -0.308235, 0.555371, 0.152815, 0.596224, 0.788140, 0.547974, -0.145367, 0.823767, 0.769829, -0.100602, 0.630272, 0.374860, 0.628824, -0.681220, 0.074174, 0.974348, -0.212473, -0.564281, 0.773499, 0.288594, 0.044396, 0.943433, 0.328577, -0.921173, -0.388710, 0.018544, -0.425498, 0.904480, 0.029470, 0.089366, -0.455806, 0.885582, -0.545513, -0.374357, 0.749848, -0.533367, -0.842216, -0.078686, -0.446624, 0.470578, 0.760976, -0.081657, -0.686126, 0.722885, -0.643255, -0.068015, 0.762625, -0.125970, 0.818188, 0.560982, -0.782325, 0.581925, 0.222106, 0.663183, 0.461760, 0.589038, 0.949374, 0.213024, 0.230889, -0.932518, 0.335223, 0.134297, 0.824093, 0.477613, 0.304559}; static float ps72 [216] = { -0.115683, -0.463514, 0.878506, 0.871651, -0.266696, 0.411216, 0.005362, -0.687842, 0.725840, 0.799129, 0.584576, -0.140228, -0.649736, -0.758601, -0.048660, 0.431880, -0.896164, 0.101836, -0.000000, -0.000000, 1.000000, -0.913278, 0.111970, 0.391646, 0.107896, 0.746541, 0.656533, 0.234467, -0.521836, 0.820190, -0.686573, -0.303320, 0.660768, 0.335792, -0.919666, -0.203613, -0.674853, 0.620353, 0.399669, -0.346446, -0.836199, 0.425142, 0.725959, 0.224216, 0.650162, -0.132922, 0.858998, 0.494423, -0.878673, 0.444506, -0.174208, 0.425553, -0.293043, 0.856172, -0.934986, -0.319437, 0.154148, -0.049458, -0.867813, 0.494423, 0.823822, 0.388803, 0.412492, -0.857950, 0.396556, 0.326596, 0.192224, 0.894635, 0.403333, 0.261320, -0.766661, 0.586467, 0.446831, 0.862338, 0.238151, 0.784505, -0.070008, 0.616158, -0.127314, -0.966738, 0.221829, 0.991593, 0.025836, -0.126790, -0.044679, 0.971523, 0.232696, 0.302897, -0.006729, 0.953000, 0.415382, 0.732569, 0.539260, 0.912175, 0.090560, 0.399669, -0.529859, 0.536810, 0.656570, 0.598362, 0.502728, 0.623880, -0.426697, 0.777461, 0.462043, -0.685548, 0.710807, -0.157408, -0.810119, 0.579164, 0.090973, -0.208560, 0.921158, -0.328590, 0.596191, -0.788724, -0.149903, -0.529766, -0.112242, 0.840684, 0.664924, -0.337324, 0.666400, -0.757805, 0.007565, 0.652437, 0.484887, 0.273006, 0.830875, -0.603669, -0.735601, 0.307368, -0.885309, -0.180781, 0.428423, -0.287977, -0.673464, 0.680820, 0.497403, -0.775087, 0.389655, 0.321098, 0.541650, 0.776860, 0.115288, -0.273553, 0.954923, -0.232611, -0.201155, 0.951540, -0.958779, 0.274375, 0.073902, -0.779535, -0.466871, 0.417560, 0.491042, -0.576940, 0.652701, -0.562242, 0.212891, 0.799100, 0.966253, 0.219906, 0.134151, 0.717726, -0.547846, 0.429807, -0.427449, -0.896692, 0.115022, 0.207746, 0.975387, 0.073902, 0.664070, 0.658827, 0.353494, 0.571507, -0.025829, 0.820190, 0.207840, 0.286397, 0.935296, -0.555678, -0.594828, 0.580863, -0.740983, 0.321920, 0.589332, 0.850789, 0.506061, 0.141638, -0.322145, 0.090482, 0.942356, -0.088550, 0.281301, 0.955525, 0.006787, 0.538938, 0.842318, -0.424248, -0.411413, 0.806693, -0.235907, 0.670057, 0.703826, -0.979564, 0.103765, -0.172299, -0.331316, 0.416163, 0.846781, -0.129065, 0.990294, -0.051572}; static float ps73 [219] = { -0.994967, 0.012813, 0.099380, 0.071611, 0.284941, -0.955867, -0.652946, -0.725634, 0.217063, -0.642952, 0.765884, 0.005760, -0.958319, -0.282800, -0.040593, -0.214846, 0.874605, -0.434634, -0.393449, -0.573014, 0.718925, -0.000000, 0.000000, -1.000000, -0.847351, -0.469907, -0.247354, 0.463081, -0.359894, 0.809958, -0.850617, 0.520060, -0.077380, 0.456275, 0.888855, -0.041838, 0.248690, -0.181439, 0.951438, 0.979327, 0.037588, 0.198758, 0.535688, -0.057285, 0.842470, -0.750192, 0.107871, 0.652362, 0.810339, 0.183801, -0.556388, -0.351481, 0.496081, 0.793955, -0.313636, -0.119247, -0.942026, -0.169881, -0.692253, -0.701374, 0.692426, -0.662771, 0.285098, -0.937894, 0.306732, 0.162079, 0.957219, -0.250554, 0.144758, 0.249156, -0.887861, -0.386813, 0.659943, -0.584594, -0.471937, -0.302976, -0.043869, 0.951988, -0.114980, -0.560008, 0.820470, 0.356831, -0.929805, -0.090187, -0.919866, 0.053299, 0.388595, -0.829551, 0.335054, 0.446748, 0.549116, 0.676293, -0.491019, -0.371582, -0.869305, 0.325937, -0.539171, -0.270770, -0.797482, 0.789239, -0.577789, -0.207993, 0.234807, 0.949156, 0.209684, 0.535451, -0.792896, -0.290875, 0.717303, 0.691691, 0.083904, 0.611875, -0.392096, -0.686927, 0.068897, 0.924527, -0.374837, -0.652556, -0.634856, -0.413676, 0.852618, 0.510045, -0.113565, -0.480061, -0.573877, -0.663481, -0.065692, 0.746945, -0.661633, 0.747319, 0.082595, 0.659312, 0.717025, 0.391022, 0.577042, 0.145233, -0.979083, 0.142489, -0.440116, 0.876581, -0.194691, -0.506307, -0.827685, -0.242055, 0.059144, -0.985625, -0.158255, -0.056459, -0.889558, -0.453320, -0.227322, -0.778858, 0.584555, -0.053303, 0.532527, 0.844733, 0.591974, 0.119894, -0.796989, 0.930507, 0.243396, -0.273706, 0.166370, -0.466212, 0.868889, 0.414515, -0.699337, -0.582327, -0.286147, -0.445461, -0.848342, 0.367589, 0.322668, -0.872218, 0.162665, 0.982784, -0.087609, -0.886161, -0.219460, -0.408112, -0.503293, 0.170464, 0.847136, 0.629724, 0.396707, -0.667886, -0.340048, 0.630705, -0.697552, 0.830058, -0.401390, 0.387156, 0.230393, -0.256843, -0.938590, -0.776250, -0.478876, 0.410016, 0.887439, -0.107201, 0.448286, -0.626687, 0.513127, -0.586484, 0.351655, 0.797019, 0.491019, 0.475870, -0.746172, 0.465590, 0.714010, -0.233997, 0.659875, -0.132433, 0.747801, 0.650580, -0.064481, -0.284249, -0.956580}; static float ps74 [222] = { 0.874230, -0.347852, 0.338704, 0.349258, 0.846485, -0.401847, 0.915364, 0.371333, -0.155627, 0.724771, -0.316082, 0.612208, -0.888913, -0.438982, -0.130874, 0.881132, -0.063362, 0.468605, -0.789870, 0.590730, -0.164754, -0.315993, 0.937649, 0.144782, 0.575189, -0.779000, 0.249633, 0.562140, 0.715595, 0.414636, -0.333130, -0.424024, 0.842157, -0.358447, -0.666754, 0.653417, -0.503976, 0.362388, 0.784017, -0.592166, -0.466925, 0.656749, -0.287516, 0.843278, 0.454111, 0.780015, 0.239874, 0.577960, -0.705531, 0.569562, 0.421693, -0.298734, -0.947700, 0.112350, 0.470280, -0.016577, 0.882362, -0.080291, -0.595540, 0.799303, -0.881994, 0.112355, 0.457670, 0.479014, -0.080292, -0.874128, 0.989233, 0.144990, 0.019918, -0.093928, -0.812306, 0.575618, -0.200477, 0.698867, 0.686581, -0.596823, -0.679097, 0.427353, 0.775834, 0.487582, 0.400431, -0.709497, 0.064535, 0.701747, -0.478035, -0.865612, -0.148988, 0.000000, 0.000000, 1.000000, 0.497722, -0.297430, 0.814744, 0.472669, -0.551722, 0.687158, 0.032795, 0.346562, 0.937454, -0.239166, 0.469138, 0.850123, -0.065402, 0.997432, -0.029186, -0.559410, -0.815957, 0.145860, -0.535985, 0.779665, 0.323795, -0.483434, 0.617803, 0.620170, -0.886157, 0.362617, 0.288505, 0.334411, 0.687960, 0.644112, 0.172797, -0.892486, 0.416664, 0.557513, 0.251011, 0.791311, 0.218547, -0.470344, 0.854993, -0.726718, 0.344314, 0.594415, -0.714763, -0.684634, -0.142791, 0.420995, -0.763433, 0.489830, 0.682310, -0.568538, 0.459583, 0.256829, 0.162876, 0.952633, 0.707277, -0.030322, 0.706286, 0.180691, 0.972522, 0.146806, -0.224757, 0.188639, 0.955981, -0.070121, -0.954679, 0.289260, -0.291777, -0.867656, -0.402542, -0.044269, -0.326651, 0.944108, 0.582860, 0.504223, 0.637207, 0.933904, 0.141978, -0.328125, -0.983467, 0.106716, 0.146302, -0.277012, -0.137653, 0.950955, -0.046923, -0.824479, -0.563944, 0.977837, -0.104650, 0.181338, 0.325962, -0.930723, 0.165843, -0.054163, 0.950031, 0.307421, 0.931218, -0.363930, 0.019678, 0.328483, 0.442605, 0.834386, -0.782435, -0.200321, 0.589633, -0.779235, 0.612964, 0.130646, 0.229022, -0.183791, 0.955913, -0.555237, -0.208885, 0.805033, 0.180674, -0.710811, 0.679783, 0.768685, 0.621658, -0.150546, 0.071617, 0.607828, 0.790832, 0.927482, 0.197284, 0.317578, 0.576757, -0.816235, -0.033334, -0.790385, -0.444782, 0.421260}; static float ps75 [225] = { -0.352631, -0.561433, 0.748628, -0.374110, -0.926709, 0.035378, -0.961478, -0.227706, 0.153980, 0.427431, -0.593109, 0.682294, -0.281127, 0.869375, 0.406393, 0.321475, 0.836461, 0.443832, -0.463292, -0.312069, 0.829442, 0.111170, -0.263922, 0.958116, 0.419366, -0.299479, 0.856997, 0.209318, 0.956801, 0.201789, -0.158145, 0.272300, 0.949127, -0.797216, -0.401470, -0.450854, 0.596501, 0.422743, 0.682257, 0.724351, -0.658694, 0.203564, 0.015491, 0.892463, 0.450854, 0.471533, 0.212443, 0.855876, -0.318919, 0.506918, 0.800828, 0.801219, -0.130176, 0.584040, -0.163985, -0.778869, 0.605370, 0.121806, 0.720894, 0.682257, 0.641660, -0.373791, 0.669741, -0.970788, 0.054989, 0.233555, -0.672349, -0.739389, 0.035378, -0.715882, -0.609791, 0.340099, 0.330354, -0.815804, 0.474688, 0.889668, -0.439263, 0.124653, 0.465160, -0.665224, -0.584040, -0.554995, 0.767867, 0.319938, 0.513248, 0.817158, -0.262354, -0.719319, -0.212505, 0.661379, 0.990183, 0.085524, 0.110559, -0.719874, 0.127501, 0.682294, 0.595115, -0.067177, 0.800828, 0.613907, 0.652787, 0.443832, -0.471059, 0.850621, -0.233555, -0.845127, 0.262590, 0.465626, 0.204014, -0.507568, 0.837110, -0.982331, 0.185407, -0.025489, -0.860019, -0.500764, 0.097991, 0.771010, 0.604007, 0.201789, -0.212363, 0.964983, -0.153980, -0.238465, -0.909652, 0.340099, 0.052957, -0.914790, 0.400443, -0.352906, 0.929104, 0.110559, 0.000000, 0.000000, 1.000000, -0.726625, 0.541864, 0.422373, 0.932688, -0.166532, 0.319938, 0.120907, -0.740243, 0.661379, -0.451867, 0.247733, 0.856997, -0.630410, -0.485912, 0.605370, -0.185402, -0.295183, 0.937280, -0.453111, -0.721412, 0.523694, -0.615330, 0.415712, 0.669741, 0.920024, 0.354645, 0.166680, 0.405728, 0.645972, 0.646611, 0.734680, 0.161285, 0.658963, 0.603506, -0.647282, 0.465626, -0.079950, -0.552842, 0.829442, 0.905211, 0.124248, 0.406393, -0.286015, -0.014454, 0.958116, 0.291940, 0.464806, 0.835898, 0.519710, 0.827445, 0.212688, 0.077666, 0.992152, -0.097991, 0.154912, 0.246641, 0.956645, 0.803625, -0.419271, 0.422373, -0.593554, 0.804391, 0.025489, 0.907879, -0.366493, -0.203564, -0.013373, 0.517007, 0.855876, 0.313959, -0.024224, 0.949127, -0.847049, -0.349506, 0.400443, -0.781995, 0.610692, 0.124653, -0.878329, -0.056642, 0.474688, -0.173717, 0.731840, 0.658963, 0.080015, -0.982759, -0.166680, -0.545809, -0.036612, 0.837110}; static float ps76 [228] = { 0.818184, 0.350134, 0.456049, -0.125723, -0.777783, 0.615830, 0.846214, 0.525447, 0.088474, 0.379488, 0.910114, 0.166379, -0.985134, -0.165693, 0.045352, 0.490001, 0.858268, -0.152561, 0.130656, -0.846533, 0.516053, -0.777836, -0.461409, 0.426699, -0.705261, 0.610504, 0.360406, -0.000000, -0.000000, 1.000000, 0.014731, 0.301156, 0.953461, 0.477353, -0.825398, 0.301416, -0.579778, -0.688839, 0.435153, 0.391238, -0.730260, 0.560047, 0.890262, -0.242389, 0.385591, -0.252197, 0.941426, 0.223859, 0.727816, 0.598632, 0.334549, 0.078075, 0.971958, 0.221816, -0.490450, 0.075742, 0.868171, -0.829189, 0.498764, -0.252348, -0.816703, 0.572705, 0.070751, -0.765258, 0.367343, 0.528620, 0.707466, 0.201338, 0.677462, -0.730282, 0.066840, 0.679868, -0.923814, -0.167673, 0.344172, 0.275056, 0.122731, -0.953562, 0.894766, 0.414191, -0.166852, 0.521001, -0.246022, 0.817331, -0.338895, -0.396947, 0.852985, -0.341206, 0.453063, 0.823598, -0.027940, -0.298363, 0.954044, -0.580818, 0.324240, 0.746672, 0.594086, 0.457164, -0.661864, -0.259322, 0.713097, 0.651341, 0.745854, -0.097337, 0.658959, -0.559909, -0.197335, 0.804711, -0.373776, -0.645276, 0.666266, 0.608481, 0.516043, 0.602868, 0.938743, 0.271007, 0.212879, -0.248677, 0.198623, 0.948002, 0.892713, 0.054419, 0.447328, 0.224560, 0.865405, 0.447936, 0.072843, -0.997153, 0.019475, 0.228553, 0.970733, -0.073770, -0.428202, 0.802295, 0.415892, 0.524081, 0.041767, 0.850644, 0.476792, 0.353221, 0.804925, 0.274403, 0.174939, 0.945568, -0.534379, 0.590366, 0.604903, -0.097360, -0.555246, 0.825968, 0.216772, -0.941671, 0.257422, -0.724290, -0.667093, 0.174330, 0.267173, -0.126517, 0.955307, 0.673694, -0.729051, 0.120917, 0.650242, -0.616890, 0.443432, 0.223898, 0.492599, 0.840962, -0.778168, -0.206747, 0.593051, 0.363436, 0.664932, 0.652518, 0.069054, 0.739617, 0.669476, -0.983185, 0.103269, 0.150607, 0.475128, -0.509681, 0.717272, -0.404898, 0.914187, -0.017864, 0.633390, 0.767516, 0.098668, -0.339284, -0.848400, 0.406330, -0.587265, 0.791918, 0.167290, -0.075637, 0.549654, 0.831961, -0.891524, 0.104964, 0.440644, 0.718458, -0.376431, 0.584908, 0.099193, -0.880934, -0.462727, 0.946144, -0.318612, 0.057426, 0.082647, 0.943908, -0.319699, 0.162697, -0.646611, 0.745268, 0.502117, 0.766016, 0.401370, 0.237708, -0.405737, 0.882537, 0.983612, -0.046004, 0.174330, -0.893607, 0.366475, 0.259157}; static float ps77 [231] = { -0.839647, -0.135974, 0.525836, -0.645936, -0.250283, 0.721197, -0.832479, 0.146739, 0.534272, 0.952662, -0.104855, 0.285379, -0.152737, -0.175599, 0.972541, -0.631494, -0.741833, -0.225607, -0.383695, -0.900449, 0.204867, 0.125547, 0.228414, 0.965435, -0.538356, 0.776560, 0.327302, 0.696647, -0.683395, 0.218298, 0.395251, 0.608707, 0.687934, 0.642865, -0.156059, 0.749913, -0.379443, 0.924510, 0.036113, -0.350104, -0.805765, 0.477672, -0.124268, 0.399851, 0.908117, -0.059710, 0.982874, 0.174339, 0.811915, 0.531507, -0.241443, 0.810447, -0.262968, 0.523472, -0.089571, 0.663931, 0.742410, 0.596721, 0.401550, 0.694753, -0.146726, 0.107903, 0.983274, 0.577895, -0.439657, 0.687561, 0.642171, 0.596750, 0.481150, -0.799233, -0.600144, -0.032463, -0.754939, 0.600232, 0.264176, 0.939509, 0.342331, 0.011531, -0.655125, 0.041023, 0.754406, -0.605759, -0.697927, 0.382040, -0.292712, 0.903294, 0.313656, 0.245484, -0.756945, 0.605618, 0.166207, 0.986032, -0.010744, -0.269296, -0.650645, 0.710028, -0.756364, -0.423059, 0.498934, -0.609095, 0.327947, 0.722118, 0.454222, -0.857747, 0.240733, -0.998412, -0.056328, 0.000424, -0.397638, 0.223486, 0.889909, 0.418307, 0.796608, 0.436389, -0.414108, -0.364483, 0.834066, -0.616997, -0.780917, 0.097383, 0.417231, 0.901390, 0.115823, 0.332565, -0.535640, 0.776203, 0.148365, 0.521145, 0.840474, -0.055361, -0.824560, 0.563060, 0.800264, 0.300704, 0.518801, 0.629457, -0.775965, -0.040768, -0.766507, 0.416409, 0.488948, -0.910980, 0.328293, 0.249679, 0.929146, 0.254367, -0.268301, 0.193332, 0.928544, 0.316904, -0.534605, -0.557948, 0.634738, -0.199889, 0.905647, -0.373962, 0.041875, -0.629929, 0.775523, 0.170225, 0.767210, 0.618395, -0.562583, 0.601451, 0.567237, 0.972471, -0.232772, 0.010797, 0.638594, 0.125850, 0.759183, -0.363095, 0.511682, 0.778680, 0.497357, -0.709512, 0.499228, -0.103559, -0.946662, 0.305134, -0.424182, -0.072101, 0.902702, 0.132128, -0.067668, 0.988920, 0.128451, -0.355849, 0.925674, 0.838145, 0.020115, 0.545076, 0.715687, -0.530623, 0.454127, 0.883008, -0.396602, 0.251005, 0.833627, 0.472294, 0.286365, -0.959737, 0.040691, 0.277936, 0.397373, -0.250448, 0.882820, 0.400313, 0.038452, 0.915571, 0.848172, -0.529716, -0.002192, 0.136341, -0.984531, 0.110042, 0.378281, 0.327954, 0.865650, -0.149076, -0.444203, 0.883436, 0.943478, 0.184047, 0.275639, -0.315052, 0.752072, 0.578904, -0.052539, 0.873164, 0.484586}; static float ps78 [234] = { 0.427950, 0.624180, 0.653649, 0.637135, 0.763607, -0.104710, 0.938404, 0.167906, 0.302004, 0.000000, -0.000000, 1.000000, 0.244328, 0.185147, 0.951853, 0.417663, -0.879414, 0.228449, 0.655808, 0.470002, 0.590774, -0.307821, -0.677172, 0.668345, 0.309610, 0.442718, 0.841512, 0.476515, 0.040045, 0.878254, 0.169653, 0.740945, 0.649783, 0.048505, 0.554181, 0.830982, 0.704635, -0.005531, 0.709548, 0.917957, 0.390341, 0.070635, 0.283882, -0.430635, 0.856718, -0.015331, 0.301597, 0.953312, 0.260096, -0.139652, 0.955430, 0.081261, 0.917834, 0.388558, 0.260793, -0.690283, 0.674905, 0.797290, 0.215115, 0.563963, -0.560917, -0.551829, 0.617136, -0.283153, 0.381579, 0.879899, -0.513984, -0.067825, 0.855114, -0.405343, 0.737584, 0.540061, 0.709640, -0.529780, 0.464483, -0.217352, 0.620897, 0.753157, -0.502017, 0.508920, 0.699271, -0.880731, 0.148079, 0.449872, 0.880508, -0.346366, 0.323631, 0.399539, 0.904000, -0.152160, -0.723243, 0.342684, 0.599573, 0.019848, -0.309281, 0.950763, -0.700903, -0.259407, 0.664412, 0.825218, 0.442810, 0.350621, 0.949229, -0.310654, -0.049584, -0.277271, 0.104727, 0.955067, 0.145428, -0.974556, 0.170559, 0.264621, 0.951463, 0.157142, 0.553176, 0.291381, 0.780444, -0.248189, -0.186250, 0.950638, 0.029770, -0.586252, 0.809582, -0.101639, 0.807259, 0.581380, 0.737990, -0.284245, 0.612025, -0.937567, -0.270791, 0.218265, 0.521346, 0.839473, 0.153244, -0.877885, -0.139149, 0.458208, -0.783730, -0.437626, 0.440739, -0.343816, 0.936970, 0.062272, 0.514929, -0.513966, 0.686067, -0.864391, 0.394878, 0.311287, 0.192926, -0.873289, 0.447377, 0.759455, 0.636989, 0.132182, -0.770510, 0.616981, 0.160151, -0.367661, -0.823404, 0.432239, -0.977576, 0.061455, 0.201415, 0.522190, -0.246984, 0.816282, -0.844153, 0.526146, -0.102840, -0.222682, -0.475696, 0.850956, 0.474315, -0.737522, 0.480714, -0.470510, -0.356080, 0.807358, 0.670303, -0.699700, 0.247210, 0.821461, 0.544485, -0.169522, -0.668847, 0.593715, 0.447377, -0.046814, -0.786505, 0.615806, -0.534186, 0.227742, 0.814112, 0.604713, -0.796422, -0.005790, -0.528284, 0.800755, 0.282325, 0.615674, 0.683091, 0.392851, 0.136866, 0.985733, -0.097969, -0.616214, -0.691605, 0.376779, 0.977017, -0.128466, 0.170099, -0.243990, 0.907235, 0.342628, -0.730716, 0.038072, 0.681619, 0.884113, -0.072925, 0.461547, -0.104174, -0.922230, 0.372344, -0.993772, -0.109695, -0.019626, 0.362323, 0.827896, 0.428148, -0.052860, 0.990009, 0.130718}; static float ps79 [237] = { -0.118538, 0.490723, 0.863215, 0.312615, -0.770199, 0.555937, 0.583600, -0.668099, 0.461578, 0.493701, -0.869459, -0.017316, -0.990635, 0.131585, -0.036426, -0.278806, -0.741675, 0.610070, 0.161552, 0.405033, 0.899916, 0.581561, 0.616211, 0.531103, -0.045226, -0.095966, 0.994357, -0.304287, -0.018495, 0.952401, 0.786934, 0.441205, 0.431361, 0.983487, 0.167954, 0.067419, -0.802266, 0.348785, 0.484477, 0.952378, 0.030066, 0.303434, 0.119874, 0.657098, 0.744212, -0.638940, -0.742088, 0.202637, 0.391877, -0.873958, 0.287455, -0.125887, 0.734403, 0.666937, -0.235439, -0.325420, 0.915789, -0.321815, 0.916893, 0.236099, 0.899230, 0.394687, 0.188698, -0.538759, 0.065040, 0.839945, 0.018780, -0.792556, 0.609510, 0.367353, -0.365469, 0.855269, -0.977038, -0.068465, 0.201767, -0.083699, 0.208652, 0.974402, 0.458738, 0.823017, 0.334965, 0.917991, -0.265041, 0.295036, 0.910293, -0.413917, 0.006182, -0.575560, 0.376971, 0.725688, 0.633069, -0.747459, 0.201319, 0.328185, 0.740866, 0.586014, 0.445773, 0.236930, 0.863221, -0.867219, -0.262734, 0.422968, -0.620004, 0.585692, 0.522073, -0.774953, -0.530420, 0.343660, -0.153309, -0.911354, 0.382009, -0.919106, -0.367417, 0.142300, 0.590584, -0.757135, -0.279208, -0.732360, -0.139592, 0.666456, 0.847298, 0.181935, 0.498985, 0.492004, -0.538642, 0.683957, -0.391282, 0.771101, 0.502296, 0.707762, 0.660352, 0.251015, 0.149001, 0.884746, 0.441614, 0.068185, 0.992090, -0.105396, -0.024944, 0.984082, 0.175956, -0.801560, -0.597733, 0.014713, 0.350028, 0.930809, -0.105239, 0.197643, 0.130319, 0.971573, 0.401212, 0.509383, 0.761287, 0.055222, -0.389862, 0.919216, 0.689228, 0.060349, 0.722027, -0.503185, -0.237308, 0.830957, 0.940615, -0.243065, -0.236987, -0.411010, -0.511811, 0.754400, -0.734750, 0.146018, 0.662436, -0.892335, 0.035918, 0.449942, 0.747296, -0.663409, -0.037909, 0.829424, -0.128498, 0.543639, 0.645532, 0.349790, 0.678922, 0.124445, -0.927778, 0.351769, 0.121531, -0.889765, -0.439940, -0.347307, 0.295611, 0.889939, -0.422582, -0.832198, 0.358984, -0.559995, -0.645701, 0.519110, 0.809131, -0.527528, 0.258884, -0.221099, 0.973638, -0.056077, 0.225905, -0.150850, 0.962399, -0.805735, 0.526317, 0.271628, 0.476826, -0.052047, 0.877456, -0.116359, -0.590346, 0.798719, 0.628459, -0.256539, 0.734320, 0.195116, -0.606664, 0.770642, 0.261323, 0.950623, 0.167411, -0.670049, -0.408805, 0.619607, 0.743908, -0.417185, 0.522071, -0.369595, 0.576026, 0.729104, -0.560134, -0.826174, -0.060711}; static float ps80 [240] = { 0.818898, -0.387108, 0.423737, 0.764945, 0.595369, 0.245754, -0.795110, -0.283210, 0.536276, -0.531255, 0.169946, 0.829992, -0.079992, 0.926088, 0.368730, 0.190091, -0.489581, 0.850985, -0.972785, -0.024246, 0.230438, 0.856415, -0.484623, -0.178028, 0.601702, -0.615171, 0.509430, -0.764076, 0.203314, 0.612251, 0.777064, 0.114137, 0.618987, -0.687366, -0.061993, 0.723660, -0.099456, 0.610501, 0.785746, 0.233614, 0.968439, -0.086893, 0.395813, 0.599609, -0.695558, -0.898885, 0.424931, -0.106955, -0.585402, -0.341551, 0.735287, 0.827600, -0.142215, 0.543004, 0.545592, -0.799581, 0.250996, 0.930518, 0.337342, 0.142608, -0.231136, 0.794946, 0.560925, -0.949104, -0.277659, 0.148684, 0.749593, -0.605032, 0.268414, 0.393566, 0.909936, 0.130850, 0.362963, -0.001446, 0.931802, 0.835381, 0.443258, -0.325055, 0.682188, 0.682011, -0.263592, 0.355428, 0.721737, 0.593941, 0.066754, 0.789911, 0.609578, 0.160161, 0.787210, -0.595524, -0.975333, 0.211931, 0.061730, 0.726898, -0.686728, 0.004871, -0.109798, -0.602680, 0.790393, 0.835011, 0.548811, -0.039529, 0.139325, -0.726251, 0.673163, 0.437275, 0.485146, 0.757248, 0.423611, -0.298320, 0.855312, -0.477788, -0.859200, 0.183015, -0.491041, 0.870382, 0.036247, 0.040425, -0.987470, 0.152540, -0.995738, -0.058675, -0.071149, 0.524042, 0.783481, 0.333972, 0.266312, 0.294573, 0.917772, -0.640141, -0.553013, 0.533288, -0.876386, -0.035358, 0.480309, 0.645397, -0.366145, 0.670373, -0.902541, 0.247173, 0.352598, 0.618297, 0.598295, 0.509659, 0.218060, -0.971785, -0.089908, 0.533942, 0.190360, 0.823813, 0.750692, -0.482590, -0.451186, 0.232613, 0.892635, 0.386127, 0.164172, -0.193427, 0.967282, -0.383727, 0.868789, 0.312985, 0.445840, 0.767420, -0.460752, 0.175649, 0.569765, 0.802817, -0.153972, -0.118803, 0.980907, -0.076628, -0.986035, -0.147861, -0.202574, -0.912194, 0.356183, -0.055451, -0.369860, 0.927431, 0.951409, -0.174971, 0.253388, -0.928567, -0.096404, -0.358426, -0.531634, 0.683704, 0.499913, -0.243368, 0.137019, 0.960207, 0.643347, 0.764463, 0.041253, -0.373093, 0.598786, 0.708701, -0.622101, 0.091479, -0.777574, 0.411986, -0.574193, 0.707510, -0.318036, 0.381509, 0.867931, 0.670601, 0.365653, 0.645439, 0.304664, -0.929068, 0.209794, -0.022869, 0.361766, 0.931988, -0.593125, 0.417802, 0.688218, 0.442526, 0.100633, -0.891092, 0.361061, -0.794237, 0.488695, 0.067036, 0.087603, 0.993897, -0.334474, -0.370951, 0.866327, -0.652200, 0.713259, 0.256702, 0.834880, 0.366510, 0.410666, 0.088211, -0.896039, 0.435124}; static float ps81 [243] = { -0.737993, -0.666655, -0.104586, 0.651782, 0.323950, -0.685738, -0.920548, -0.311625, 0.235544, 0.007978, -0.114228, 0.993423, 0.652743, 0.633431, 0.415562, -0.211509, 0.418791, 0.883107, -0.262988, -0.102494, 0.959339, 0.936107, 0.213585, 0.279438, -0.043615, 0.928216, 0.369477, -0.750363, 0.506315, -0.424970, 0.775185, 0.353418, 0.523626, 0.399884, 0.359322, -0.843197, -0.835418, -0.473198, -0.279573, 0.888300, -0.452558, -0.078199, -0.859190, -0.192790, 0.473946, 0.555534, 0.499470, 0.664764, 0.841217, -0.228781, 0.489911, -0.920579, 0.324239, -0.217722, 0.964373, -0.057474, 0.258228, 0.984393, -0.172982, -0.032370, 0.540259, -0.800477, -0.259532, -0.251049, -0.913580, -0.319916, -0.113872, 0.790873, 0.601292, -0.598766, -0.708915, 0.372719, -0.636745, 0.196912, 0.745508, 0.375637, -0.540731, 0.752667, 0.424114, 0.743003, 0.517759, -0.319030, 0.633610, 0.704811, -0.849896, 0.129120, 0.510885, -0.732615, 0.401607, 0.549533, 0.639840, -0.404621, 0.653366, -0.196523, 0.975054, -0.103191, -0.100270, 0.164398, 0.981284, -0.250736, 0.759543, -0.600188, -0.753498, 0.577485, 0.314248, 0.163793, 0.797056, 0.581269, 0.400892, 0.334052, 0.853050, -0.612885, 0.747164, -0.257135, 0.070910, -0.597216, 0.798940, -0.730712, -0.056970, 0.680304, -0.467622, 0.883281, -0.033824, -0.046584, -0.776099, 0.628888, -0.787197, -0.589755, 0.180304, 0.198143, 0.147154, 0.969064, 0.377723, -0.863822, 0.333373, 0.586649, 0.806347, -0.075145, -0.559849, 0.639074, 0.527403, 0.162650, 0.898642, -0.407417, 0.289654, 0.588445, 0.754873, 0.516930, 0.824604, 0.229807, -0.114338, 0.915933, -0.384700, -0.757871, -0.473176, 0.449150, 0.514303, 0.083101, -0.853573, -0.695019, 0.101741, -0.711757, 0.283289, -0.117402, 0.951821, -0.384275, 0.181324, 0.905237, -0.342016, 0.827201, 0.445830, 0.099581, 0.395856, 0.912897, 0.913121, 0.407176, 0.020457, -0.525105, -0.561695, 0.639346, -0.273972, 0.944870, 0.179332, -0.963510, -0.002897, 0.267656, 0.028671, 0.993072, 0.113957, 0.115879, 0.376248, -0.919244, 0.328498, 0.943764, 0.037393, -0.496434, 0.431377, 0.753304, 0.481507, -0.272692, 0.832941, 0.183106, -0.373707, 0.909294, 0.657560, 0.209131, 0.723795, 0.490800, 0.049218, 0.869881, 0.521835, -0.667770, 0.530821, -0.698134, 0.713940, 0.053840, 0.359191, 0.757469, -0.545182, 0.992836, 0.119476, 0.001190, -0.006423, 0.614979, 0.788517, -0.391471, -0.885788, 0.249261, -0.902829, 0.302127, 0.305974, 0.098814, 0.983724, -0.150078, 0.849661, 0.063676, 0.523471, -0.805271, 0.570979, -0.159751, -0.240779, -0.595060, 0.766765}; static float ps82 [246] = { 0.159779, 0.694686, 0.701343, -0.677855, 0.388286, 0.624297, 0.073351, 0.490925, 0.868108, 0.490070, 0.871564, 0.014423, 0.057701, -0.266218, 0.962184, -0.242590, -0.842802, -0.480452, -0.679152, -0.578511, -0.451750, -0.945255, -0.050982, 0.322325, -0.330518, 0.773583, 0.540673, -0.230152, 0.928461, 0.291532, -0.058722, 0.998195, -0.012614, 0.900102, -0.206647, 0.383553, -0.568252, 0.821758, 0.042469, -0.433986, -0.366368, 0.823062, 0.735394, -0.666070, 0.124683, 0.338268, -0.356668, 0.870840, 0.372207, -0.797760, 0.474385, 0.739997, -0.425214, 0.521150, -0.292310, 0.109704, 0.950010, 0.835250, 0.546108, -0.064220, -0.362238, -0.623506, 0.692838, 0.286951, -0.069565, 0.955416, -0.888059, 0.457805, 0.042025, 0.474178, 0.203732, 0.856533, -0.477750, 0.288559, 0.829752, -0.212210, 0.941215, -0.262833, -0.491875, -0.064347, 0.868285, 0.214871, 0.975706, -0.042752, -0.489797, 0.842147, -0.225582, -0.853264, 0.203297, 0.480219, 0.135162, -0.670926, -0.729102, 0.636635, -0.658025, 0.402117, 0.110975, -0.513751, 0.850732, -0.519877, -0.720976, 0.458172, -0.075940, -0.698058, 0.712002, 0.381287, 0.885287, -0.266244, 0.752945, -0.147081, 0.641436, 0.354073, 0.465253, 0.811278, -0.062745, 0.267298, 0.961569, -0.488182, 0.816649, 0.307834, -0.516040, -0.781924, -0.349710, 0.323595, -0.945952, -0.021466, -0.659677, -0.234075, 0.714168, 0.833596, 0.323785, 0.447528, 0.074936, -0.853585, 0.515536, -0.733335, 0.652357, 0.191443, 0.537244, -0.073768, 0.840195, 0.756906, 0.552973, -0.348301, 0.440804, 0.655872, 0.612800, 0.080088, 0.952188, -0.294830, -0.232835, -0.184747, 0.954807, 0.950162, 0.295169, 0.100340, -0.955474, 0.219532, 0.197169, 0.237508, -0.680718, 0.692974, 0.641856, 0.744835, -0.182322, 0.218502, 0.219499, 0.950830, -0.618358, 0.627685, 0.472911, 0.870446, 0.062931, 0.488225, -0.310444, -0.924578, -0.220863, 0.615702, 0.412218, 0.671556, -0.824474, 0.444765, 0.349897, -0.971767, 0.213213, -0.101041, 0.688443, 0.713143, 0.132186, 0.853686, -0.454545, 0.254184, -0.827292, -0.316113, 0.464393, -0.171900, -0.461931, 0.870098, 0.489103, -0.579730, 0.651683, -0.817262, -0.056330, 0.573506, -0.669382, 0.113422, 0.734209, -0.244549, 0.447249, 0.860328, 0.040329, 0.965840, 0.255980, 0.969153, 0.060920, 0.238813, 0.702363, 0.147529, 0.696363, 0.573799, -0.339479, 0.745325, -0.445317, 0.563361, 0.695929, -0.045029, 0.853328, 0.519426, -0.618188, -0.497134, 0.608853, -0.237357, -0.825979, 0.511293, -0.930045, -0.312737, 0.192902, 0.836195, 0.497642, 0.230501, 0.000000, -0.000000, 1.000000, -0.997990, -0.041366, 0.048018}; static float ps83 [249] = { 0.196848, -0.201914, 0.959417, -0.445878, -0.198878, 0.872720, 0.585404, 0.113311, 0.802784, -0.702680, -0.711453, -0.008611, 0.595504, 0.398453, 0.697575, 0.820789, -0.503415, 0.269961, 0.045276, -0.423014, 0.904991, -0.041182, 0.974571, 0.220263, 0.652397, -0.565043, 0.505079, 0.906810, 0.238530, 0.347561, -0.871281, -0.137300, 0.471188, -0.934829, 0.105128, 0.339181, 0.833546, 0.506915, 0.219630, 0.298742, 0.437456, -0.848166, 0.747038, 0.601179, -0.283758, -0.271851, 0.894561, 0.354764, -0.289946, 0.040972, 0.956166, 0.986182, 0.082579, -0.143618, 0.035273, 0.887065, 0.460294, -0.546818, -0.452810, 0.704240, 0.866745, 0.495221, -0.059239, -0.906858, -0.322699, 0.271059, -0.338496, -0.848075, 0.407662, 0.710552, -0.703635, 0.003683, -0.880488, 0.474064, -0.002214, -0.191582, 0.547069, 0.814870, 0.939656, -0.255241, 0.227811, 0.384810, 0.326064, 0.863484, -0.491202, 0.743760, 0.453368, -0.166751, 0.656195, -0.735936, -0.512114, 0.840021, 0.179174, -0.641511, -0.710036, -0.290366, -0.813284, 0.292775, 0.502843, -0.550775, 0.063343, 0.832247, -0.977713, 0.201181, 0.060023, 0.987531, 0.008323, 0.157207, -0.131982, 0.287406, 0.948672, 0.335259, 0.040100, 0.941272, -0.764961, 0.060355, 0.641243, -0.268913, 0.961623, 0.054473, -0.354254, -0.671133, 0.651218, -0.720435, 0.642274, 0.261644, 0.423445, -0.637255, 0.643895, -0.571774, -0.662381, 0.484072, -0.672517, 0.534354, 0.512042, -0.227640, 0.765801, 0.601440, -0.390081, 0.320357, 0.863255, -0.100412, -0.810333, 0.577303, 0.336546, 0.576227, 0.744782, -0.152053, -0.226219, 0.962136, 0.599994, -0.379153, 0.704450, 0.338302, -0.430464, 0.836811, -0.877257, 0.403199, 0.260483, 0.028425, 0.712093, 0.701510, 0.491446, -0.173397, 0.853472, 0.138813, 0.236167, 0.961747, 0.265425, 0.780269, 0.566330, -0.680873, -0.200831, 0.704329, -0.289449, -0.948073, 0.131819, -0.472785, 0.874013, -0.112138, 0.544697, 0.810099, -0.216897, -0.062885, -0.941429, 0.331295, 0.092595, 0.493380, 0.864871, -0.619585, 0.325729, 0.714153, -0.102625, -0.618414, 0.779122, -0.170177, 0.839106, -0.516663, -0.441735, 0.572124, 0.691046, 0.392961, 0.851531, 0.347097, 0.000000, 0.000000, 1.000000, 0.482232, 0.873191, 0.070644, 0.221118, 0.960632, 0.168207, 0.779531, 0.181671, 0.599439, 0.012065, 0.998155, -0.059514, 0.897891, -0.039275, 0.438461, 0.534220, 0.647661, 0.543271, -0.755790, -0.412837, 0.508280, 0.810739, -0.310604, 0.496213, 0.750055, 0.460034, 0.475170, 0.641838, -0.717495, 0.270639, 0.422370, -0.806442, 0.413830, 0.960383, 0.270634, 0.066496, 0.727855, -0.103983, 0.677801, -0.217853, 0.945328, -0.242685}; static float ps84 [252] = { 0.613955, 0.551610, 0.564611, 0.400037, -0.482886, 0.778968, 0.795429, 0.362609, 0.485600, 0.356110, 0.509661, 0.783219, 0.849259, -0.067099, 0.523695, -0.193281, 0.382603, 0.903470, 0.388740, 0.707336, 0.590387, 0.195736, -0.265895, 0.943921, -0.175161, -0.982924, 0.056383, -0.303006, -0.491343, 0.816559, -0.303347, -0.198985, 0.931872, -0.008103, -0.845547, 0.533839, -0.082521, -0.656918, 0.749433, 0.571015, 0.339044, 0.747657, -0.507438, -0.027865, 0.861238, -0.930379, 0.248278, 0.269729, -0.534379, -0.313294, 0.785039, 0.280901, -0.853405, 0.439084, -0.284471, -0.753881, 0.592233, -0.622090, 0.419815, 0.660877, -0.953009, 0.141572, -0.267826, -0.479438, 0.817522, 0.319056, -0.562773, 0.826451, -0.016315, 0.821420, 0.569888, 0.022304, -0.498250, -0.576604, 0.647514, 0.455899, -0.217649, 0.863009, -0.094058, 0.995490, 0.012373, 0.027690, 0.197328, 0.979946, -0.388874, 0.545503, 0.742430, -0.310980, 0.767051, 0.561181, -0.343164, 0.932693, 0.111006, 0.435950, 0.893086, -0.111104, -0.188251, 0.922537, 0.336878, -0.464880, -0.797787, 0.383957, -0.451909, 0.269645, 0.850335, -0.572273, 0.644426, 0.507167, 0.486460, -0.667186, 0.564109, -0.810706, 0.274763, 0.516973, 0.834547, 0.487838, -0.256018, -0.027521, 0.840888, 0.540509, 0.920267, 0.145025, 0.363423, 0.052641, -0.960575, 0.272991, 0.618515, 0.779284, 0.100776, 0.739083, 0.145011, 0.657821, -0.130100, 0.638829, 0.758269, -0.979155, 0.203093, 0.002989, 0.135277, -0.518400, 0.844371, 0.312407, 0.267807, 0.911417, -0.252488, 0.096283, 0.962798, 0.216435, -0.713272, 0.666632, -0.732643, -0.131113, 0.667865, 0.541392, -0.784310, 0.302906, -0.082294, -0.366165, 0.926904, 0.880912, -0.012496, -0.473116, -0.666918, -0.725789, 0.168676, -0.908642, -0.367934, -0.197470, 0.889203, -0.415178, 0.192212, 0.821220, -0.333963, 0.462674, -0.712500, 0.580600, -0.394015, -0.753029, 0.648178, -0.113194, -0.875301, 0.474588, 0.092814, -0.890785, -0.245514, 0.382393, -0.680843, 0.135690, 0.719751, 0.992484, 0.084286, 0.088719, -0.662658, -0.612363, 0.431156, -0.030905, -0.083347, 0.996041, -0.217508, -0.916002, 0.337092, 0.071854, 0.969293, 0.235176, 0.522795, 0.067969, 0.849744, 0.632976, -0.423009, 0.648387, 0.136832, 0.693516, 0.707328, 0.949555, 0.302214, -0.083736, 0.233369, 0.870714, 0.432893, 0.979811, 0.030816, -0.197539, -0.727905, -0.384050, 0.568032, 0.746816, 0.591882, 0.303219, -0.696913, 0.692042, 0.188122, 0.081897, 0.462159, 0.883007, 0.523709, 0.772686, 0.358728, 0.677550, -0.152559, 0.719480, -0.778939, 0.505631, 0.370934, 0.356762, 0.918924, 0.168224, 0.257723, 0.003361, 0.966213, 0.324600, -0.929644, 0.174345}; static float ps85 [255] = { -0.614093, -0.338016, 0.713187, -0.784859, 0.550295, 0.284908, 0.891086, -0.258574, 0.372967, -0.915459, 0.391802, 0.091788, -0.276317, 0.062317, 0.959044, -0.927581, -0.292636, -0.232287, 0.541038, -0.840716, 0.021768, -0.293922, -0.812010, -0.504232, -0.385241, 0.899590, 0.205735, 0.180474, 0.461586, 0.868543, -0.953445, -0.151259, 0.260890, -0.151812, 0.735553, 0.660238, -0.471052, -0.151089, 0.869070, -0.096675, 0.528448, 0.843443, 0.665517, -0.707514, 0.237720, 0.434990, -0.305681, 0.846961, -0.168398, -0.949859, 0.263459, 0.551400, 0.680711, 0.482276, -0.973335, 0.201881, -0.108916, -0.086628, -0.488843, 0.868060, 0.738086, -0.294622, 0.606982, -0.873268, 0.301182, 0.383005, -0.884503, 0.031104, 0.465497, 0.778215, 0.497683, 0.383005, -0.823467, 0.028957, -0.566625, 0.210289, 0.219844, -0.952600, -0.053181, -0.856937, 0.512671, 0.388833, 0.600514, 0.698707, 0.436344, 0.861127, 0.260890, -0.689800, 0.491454, 0.531647, -0.333852, -0.809951, 0.482206, 0.638702, 0.445473, 0.627386, 0.338467, -0.643918, 0.686156, 0.015816, 0.875915, 0.482206, -0.168637, -0.951626, -0.256846, 0.517101, -0.709868, 0.478220, -0.483218, -0.604903, 0.632923, 0.621286, -0.116941, 0.774809, 0.834154, 0.244112, 0.494566, 0.259779, -0.964916, 0.038117, 0.708462, 0.064149, -0.702827, 0.027097, 0.999516, -0.015297, -0.368659, 0.585435, 0.722050, 0.123223, 0.695768, 0.707618, -0.532458, 0.122655, 0.837523, 0.066829, -0.271017, 0.960252, -0.975287, 0.123358, 0.183298, 0.215837, -0.471332, 0.855137, -0.760777, 0.648649, 0.021768, -0.112539, 0.966115, 0.232287, -0.218986, -0.676410, 0.703217, -0.506193, 0.694895, 0.510774, 0.219739, 0.192068, 0.956465, -0.050348, 0.275215, 0.960063, -0.578757, -0.815495, 0.002919, -0.744912, 0.210982, 0.632923, -0.113450, 0.953484, -0.279279, 0.307989, 0.951327, 0.010971, 0.280761, -0.104966, 0.954021, -0.941521, -0.333758, 0.046300, 0.949203, 0.019221, 0.314076, -0.556362, 0.483307, -0.675926, 0.708093, 0.497795, -0.500804, -0.598141, -0.709540, 0.372534, 0.363682, 0.430686, -0.825981, 0.744682, 0.650907, -0.147538, 0.466448, 0.078279, 0.881078, -0.316414, 0.336381, 0.886978, -0.605493, 0.751865, 0.260916, 0.062738, -0.693890, 0.717343, 0.825089, 0.241459, -0.510808, -0.000000, -0.000000, 1.000000, 0.436455, 0.870695, -0.226708, -0.854358, -0.437154, 0.281014, -0.669883, -0.706658, -0.227796, 0.674101, 0.176090, 0.717343, -0.834975, -0.543109, -0.088601, -0.551430, 0.386257, 0.739412, -0.736839, 0.517800, -0.434685, 0.861839, -0.473781, 0.181013, 0.445392, 0.353269, 0.822695, 0.235406, -0.831687, 0.502872, 0.405047, -0.873050, 0.271514, -0.997095, -0.068868, -0.032548, -0.284352, 0.845846, 0.451319}; static float ps86 [258] = { -0.112237, -0.294066, 0.949172, 0.258861, 0.590611, 0.764310, 0.348854, -0.837672, 0.420246, 0.223743, 0.202621, 0.953354, -0.371315, -0.915498, 0.154881, -0.865391, -0.448933, -0.222616, 0.060394, -0.040851, 0.997338, -0.964293, 0.236669, 0.118857, -0.497528, 0.716847, 0.488463, -0.371317, -0.684902, 0.626924, -0.701570, 0.645447, 0.301991, -0.602888, -0.796149, 0.051710, -0.240469, -0.516533, 0.821808, -0.933178, 0.095642, 0.346456, 0.720881, -0.513663, 0.465275, 0.416251, -0.296743, 0.859464, 0.456312, 0.875196, 0.160659, -0.217108, -0.022226, 0.975895, 0.923483, -0.366988, 0.111798, 0.234574, 0.910917, 0.339418, 0.339520, -0.044389, 0.939551, -0.226160, -0.862066, 0.453536, 0.667955, -0.744199, 0.002049, -0.001713, 0.676517, 0.736425, 0.194913, -0.736613, 0.647619, -0.076966, 0.220201, 0.972413, 0.713561, 0.539005, 0.447554, -0.436223, 0.538666, 0.720797, 0.775638, -0.212326, 0.594394, 0.757401, 0.084493, 0.647460, 0.040797, -0.543144, 0.838648, 0.932774, 0.188701, -0.307122, -0.814625, -0.579612, 0.020870, 0.319142, -0.536600, 0.781159, 0.212359, 0.975041, 0.064804, 0.657747, 0.349442, 0.667277, -0.252937, 0.729822, 0.635124, 0.260314, 0.777635, 0.572294, -0.342174, 0.270097, 0.899980, -0.626888, -0.581882, 0.518097, -0.104013, -0.967452, 0.230689, 0.596438, -0.414561, 0.687314, -0.036157, 0.962981, 0.267134, -0.207799, 0.953468, -0.218445, -0.479774, -0.793847, 0.373663, -0.012333, 0.854396, 0.519476, 0.529095, 0.142897, 0.836444, 0.457321, -0.881828, 0.115054, -0.697580, -0.665341, 0.265899, 0.057772, -0.887070, 0.458005, 0.981371, -0.097655, 0.165452, 0.962306, 0.180609, 0.203341, 0.079302, 0.433073, 0.897863, -0.847178, -0.444171, 0.291550, 0.879677, -0.301934, 0.367430, 0.486111, -0.654230, 0.579379, -0.469013, 0.021693, 0.882925, 0.500337, 0.760694, 0.413530, 0.606420, -0.115211, 0.786753, 0.590847, -0.741995, 0.316768, 0.158067, -0.304520, 0.939299, -0.684719, 0.061278, 0.726226, -0.672425, 0.496330, 0.549091, 0.506284, 0.586857, 0.631882, -0.297127, 0.949323, 0.102477, 0.905704, -0.007818, 0.423838, 0.050955, -0.998693, 0.003957, 0.281390, -0.877943, -0.387345, -0.630481, -0.208909, 0.747563, -0.192572, 0.495663, 0.846897, 0.846532, 0.278330, 0.453779, -0.380967, -0.254928, 0.888750, -0.944437, -0.326198, 0.040408, 0.407394, 0.378538, 0.831107, -0.514312, 0.830880, 0.212419, -0.090427, -0.732716, 0.674499, -0.798481, 0.239579, 0.552295, -0.765237, -0.347929, 0.541626, -0.689914, -0.692920, -0.209478, -0.576935, 0.310041, 0.755659, -0.839635, 0.535712, 0.089592, -0.508669, -0.455021, 0.730898, -0.834224, -0.079047, 0.545730, -0.855707, 0.396289, 0.332747, 0.785360, -0.584226, 0.204671, 0.996237, 0.046194, -0.073334}; static float ps87 [261] = { -0.898778, -0.347801, 0.266894, -0.823343, -0.557229, 0.107711, -0.186537, -0.969920, 0.156395, -0.515034, -0.714826, 0.473036, 0.358522, -0.204202, 0.910914, 0.405771, 0.737452, 0.539921, -0.194273, 0.419022, 0.886949, -0.293514, 0.152884, 0.943651, 0.144728, -0.445496, 0.883508, -0.568604, -0.260373, 0.780318, 0.769920, 0.323612, -0.549999, -0.026972, -0.791930, 0.610016, 0.768022, 0.265751, 0.582683, 0.660783, 0.745782, 0.084704, -0.520057, 0.711210, 0.472992, 0.192964, 0.972594, 0.129710, -0.058443, 0.966876, 0.248468, -0.416850, -0.868746, 0.267425, 0.432804, 0.860502, 0.268733, -0.094620, 0.651373, 0.752835, -0.387268, 0.564483, 0.728960, 0.820795, -0.420679, 0.386425, -0.313866, -0.680810, 0.661805, 0.410420, -0.453498, 0.791136, 0.429817, -0.666882, 0.608708, -0.536905, 0.840500, -0.072749, 0.936853, -0.190223, 0.293464, -0.347302, -0.153871, 0.925043, 0.548825, -0.810788, -0.203506, -0.980706, 0.194983, -0.014060, -0.469791, 0.322934, 0.821590, 0.159811, 0.725714, 0.669178, 0.595427, -0.199314, 0.778293, 0.477031, 0.056901, 0.877043, 0.643610, -0.425587, 0.636114, -0.914806, -0.273094, -0.297573, -0.687034, 0.226155, 0.690534, 0.642688, -0.620480, 0.449395, -0.988173, -0.082450, 0.129288, 0.643188, 0.740173, -0.196094, -0.359853, -0.447339, 0.818775, -0.853103, 0.115528, 0.508791, 0.199012, 0.891203, 0.407617, 0.020320, -0.940321, 0.339681, -0.229818, -0.860445, 0.454773, -0.628428, 0.488005, 0.605747, 0.004090, 0.242722, 0.970087, 0.708822, 0.038513, 0.704335, -0.738259, -0.075060, 0.670328, -0.721929, 0.662383, -0.200168, -0.278935, 0.763554, 0.582392, 0.891332, 0.042732, 0.451333, -0.888297, 0.443908, -0.117793, -0.309158, 0.888429, 0.339286, 0.184780, -0.662784, 0.725654, -0.057785, 0.997718, -0.034925, 0.557146, 0.302244, 0.773458, -0.948655, -0.315876, -0.016631, 0.208672, 0.054664, 0.976457, 0.097213, 0.491091, 0.865667, -0.735848, -0.551019, 0.393580, 0.750524, -0.657862, -0.062706, -0.907749, -0.120526, 0.401827, -0.102160, -0.022438, 0.994515, 0.096634, -0.196442, 0.975742, 0.355762, 0.540765, 0.762238, 0.802876, -0.196134, 0.562957, -0.573218, -0.507713, 0.643155, -0.536895, 0.032327, 0.843029, -0.136738, -0.335177, 0.932180, -0.952797, 0.161996, 0.256779, -0.724849, 0.604762, 0.329935, 0.626052, 0.692334, 0.358794, -0.475385, 0.810520, -0.342148, 0.586309, 0.528188, 0.614215, 0.829376, 0.534442, 0.162808, -0.773472, -0.474692, -0.420009, -0.819824, 0.372882, 0.434566, 0.986765, 0.050761, 0.154008, 0.273362, -0.939062, 0.208413, -0.093804, -0.587363, 0.803869, 0.303638, 0.301499, 0.903826, -0.891447, 0.424093, 0.159586, 0.232042, -0.840398, 0.489783, -0.041231, 0.857455, 0.512904, -0.439863, -0.898065, 0.000108, 0.314889, -0.946448, -0.071289}; static float ps88 [264] = { -0.329296, -0.363572, 0.871424, -0.077793, -0.269098, 0.959966, 0.670002, -0.492828, 0.555175, -0.295075, 0.631780, 0.716788, -0.724696, -0.248340, 0.642762, -0.467008, 0.124074, 0.875505, 0.902010, -0.005019, 0.431686, 0.986002, 0.071614, 0.150569, 0.657418, -0.660719, 0.362287, 0.580107, 0.814255, -0.021554, -0.635473, 0.319916, 0.702729, 0.723972, -0.075027, 0.685737, -0.979271, -0.166320, 0.115611, -0.127633, 0.434756, 0.891458, 0.150167, -0.426797, 0.891792, 0.427047, -0.825211, 0.369672, -0.128019, 0.937782, 0.322763, -0.300393, -0.794609, 0.527598, -0.397529, 0.391040, 0.830095, 0.410590, 0.581915, 0.701990, -0.548565, -0.656361, 0.517944, -0.876724, -0.442778, 0.187891, 0.615202, -0.310420, 0.724684, 0.604168, 0.620305, 0.500202, -0.893609, -0.248124, 0.374028, -0.286579, -0.084961, 0.954282, 0.462631, -0.150078, 0.873756, -0.528001, -0.168886, 0.832282, -0.950934, 0.201745, -0.234572, 0.587457, -0.796364, 0.143870, 0.384718, -0.921877, 0.046216, -0.333501, -0.941783, 0.042682, -0.953296, 0.047088, 0.298345, 0.203098, -0.945327, 0.255163, -0.709117, -0.654520, 0.262216, 0.592202, 0.374149, 0.713659, 0.043980, 0.990196, -0.132584, -0.497801, -0.817822, 0.288725, 0.293700, 0.075933, 0.952877, -0.824992, 0.231338, 0.515627, 0.402503, -0.445289, 0.799818, 0.176748, 0.505533, 0.844510, -0.093778, -0.536422, 0.838724, -0.681288, 0.045865, 0.730577, -0.151955, 0.986711, 0.057535, -0.330798, -0.609067, 0.720840, 0.402881, 0.788313, 0.465027, -0.031608, 0.649842, 0.759411, 0.617063, -0.776933, -0.124934, -0.592324, 0.707920, 0.384710, 0.990884, -0.128131, -0.041621, -0.746043, 0.481996, 0.459455, 0.194605, 0.743889, 0.639342, -0.920656, 0.390093, -0.014820, 0.387173, 0.896223, 0.216523, 0.826454, -0.261841, 0.498411, -0.780443, -0.625180, -0.007700, -0.536750, 0.568618, 0.623357, -0.058240, -0.747410, 0.661805, -0.796388, 0.570836, 0.199781, -0.928228, -0.364408, -0.074828, 0.802511, 0.536286, 0.261482, 0.192279, -0.644753, 0.739813, 0.249746, 0.921777, -0.296569, 0.210652, -0.184575, 0.959978, -0.845726, -0.035438, 0.532439, 0.762430, 0.412222, 0.498772, -0.389129, 0.890186, 0.236953, -0.353901, 0.793177, 0.495606, -0.552049, -0.443524, 0.706065, 0.147579, 0.902122, 0.405459, 0.017561, 0.902574, -0.430176, -0.748708, -0.468285, 0.469198, 0.773121, 0.169875, 0.611086, 0.085001, 0.264197, 0.960716, 0.000000, 0.000000, 1.000000, 0.907542, 0.255726, 0.333124, 0.372352, 0.323526, 0.869876, 0.451987, -0.653257, 0.607423, -0.910113, 0.322731, 0.259883, 0.215362, -0.816866, 0.535116, 0.118498, 0.982243, 0.145451, 0.620014, 0.745310, 0.245144, 0.840770, -0.453077, 0.296356, -0.086326, 0.823203, 0.561146, 0.559386, 0.108322, 0.821799, -0.207360, 0.185217, 0.960571, -0.782936, 0.617340, -0.076822}; static float ps89 [267] = { 0.394237, 0.801920, 0.448890, 0.871911, 0.189679, 0.451435, 0.053024, -0.995932, 0.072862, 0.483488, 0.229926, 0.844615, 0.829289, -0.050835, 0.556502, 0.771800, -0.460856, 0.438105, 0.591275, 0.776111, 0.219192, -0.756801, 0.126552, 0.641278, -0.201887, 0.560163, 0.803405, 0.619880, 0.730437, -0.286724, -0.168336, -0.846191, 0.505592, -0.116245, -0.903202, -0.413174, 0.711879, 0.202713, 0.672411, -0.762301, -0.141751, 0.631509, 0.351663, -0.836616, 0.420009, 0.606121, 0.642441, 0.468922, -0.756047, 0.615616, -0.222281, -0.414288, -0.264373, 0.870903, -0.421374, 0.832314, 0.360135, -0.429410, -0.540015, 0.723872, 0.768953, 0.434173, 0.469260, -0.547780, 0.228059, 0.804939, 0.631140, -0.031582, 0.775026, 0.343761, 0.914513, 0.213295, 0.836417, -0.541540, -0.084503, -0.134618, -0.954266, 0.266936, 0.112429, -0.925745, 0.361048, -0.698454, 0.385355, 0.603046, 0.307140, -0.941433, 0.139175, 0.061947, -0.601037, 0.796817, -0.208555, -0.450214, 0.868224, -0.904145, -0.056486, 0.423476, -0.937562, -0.261819, 0.228970, -0.988020, -0.152913, -0.020832, 0.195940, 0.192148, 0.961606, -0.587929, 0.622512, 0.516545, 0.515324, -0.274835, 0.811731, 0.295534, 0.425349, 0.855417, -0.055594, -0.983034, -0.174793, 0.580283, 0.438921, 0.686017, -0.426158, -0.735575, 0.526611, -0.465319, 0.488385, 0.738213, -0.617866, -0.353363, 0.702407, 0.806002, 0.530440, -0.262667, 0.536820, -0.816259, 0.213412, -0.582758, -0.053934, 0.810854, 0.033522, -0.360603, 0.932117, 0.557063, -0.506248, 0.658326, -0.938712, 0.306973, 0.156805, -0.799786, 0.481031, 0.359098, -0.653839, 0.706678, 0.270372, 0.159317, -0.897038, -0.412239, 0.725110, -0.280019, 0.629131, 0.917651, 0.328693, 0.223332, -0.222682, 0.962237, 0.156568, -0.904484, 0.401171, -0.144813, 0.962981, 0.022129, 0.268660, 0.582528, -0.675529, 0.452019, -0.982113, 0.033148, 0.185353, -0.644673, -0.565551, 0.514343, 0.082897, 0.586824, 0.805460, -0.298353, 0.315237, 0.900895, -0.013538, 0.371138, 0.928479, -0.348268, 0.718260, 0.602339, -0.172465, -0.169514, 0.970320, 0.388813, -0.006817, 0.921291, 0.088866, -0.063521, 0.994016, -0.185534, -0.678776, 0.710521, 0.515373, 0.856242, -0.035215, -0.255901, -0.966218, 0.030625, -0.088448, 0.764513, 0.638511, 0.086338, -0.793288, 0.602694, 0.309187, -0.489053, 0.815617, 0.675833, -0.737042, -0.004391, -0.986037, 0.151360, -0.069438, -0.902983, 0.232657, -0.361238, -0.360902, 0.035306, 0.931935, -0.895582, -0.444529, 0.018098, 0.336776, -0.688759, 0.642022, -0.466487, 0.880145, 0.087941, 0.273591, -0.247529, 0.929450, -0.179289, -0.759922, -0.624799, 0.784406, 0.577250, 0.226914, -0.882708, 0.221388, 0.414504, -0.105113, 0.121822, 0.986970, -0.392389, -0.873400, 0.288450, -0.814075, -0.348567, 0.464525, 0.392515, 0.616705, 0.682354, 0.731864, 0.680939, -0.026395}; static float ps90 [270] = { 0.876356, -0.199226, 0.438531, 0.255493, -0.061115, 0.964877, 0.143704, -0.218048, -0.965300, -0.104453, -0.993046, -0.054300, 0.166079, 0.833431, 0.527078, -0.189773, -0.945424, 0.264875, -0.958006, -0.176794, 0.225760, 0.014731, -0.892302, 0.451199, -0.016691, 0.732764, -0.680279, -0.640357, -0.687917, -0.341634, 0.507245, 0.847081, 0.158606, 0.000000, 0.000000, 1.000000, 0.773851, 0.613406, -0.157758, -0.616326, 0.030864, 0.786886, 0.273225, -0.570599, 0.774445, -0.965234, 0.018286, -0.260748, 0.852775, 0.189261, -0.486780, 0.037685, -0.277267, 0.960054, -0.346952, -0.936704, 0.047014, 0.020790, -0.521810, 0.852808, -0.000988, 0.461547, 0.887115, 0.293599, -0.887321, -0.355612, 0.935551, -0.062385, -0.347639, 0.578971, 0.564453, 0.588375, -0.942361, 0.283991, 0.176931, -0.574469, 0.738741, 0.352487, 0.497023, -0.117474, 0.859749, 0.638823, 0.103235, 0.762396, 0.779140, 0.473554, 0.410716, -0.803463, 0.057014, 0.592619, 0.148899, 0.230034, 0.961724, -0.168282, 0.978007, 0.123222, -0.273987, 0.423198, 0.863617, -0.712027, 0.155429, -0.684734, 0.961676, -0.246848, 0.119355, 0.053696, -0.985430, 0.161383, 0.404637, 0.165594, 0.899360, -0.396883, 0.731729, 0.554127, -0.735365, -0.301063, -0.607124, 0.875623, -0.482929, -0.008007, 0.904763, 0.233078, 0.356480, 0.747498, -0.645259, 0.157758, -0.111987, 0.823198, 0.556601, 0.837719, 0.049154, 0.543885, -0.481829, 0.525168, 0.701455, 0.692529, -0.713765, -0.104609, -0.689299, 0.303247, 0.657958, 0.875421, 0.453854, 0.166296, 0.679879, -0.607517, 0.410716, -0.462806, -0.667810, 0.582957, -0.667948, 0.542006, 0.509975, -0.201461, 0.644691, 0.737419, 0.801869, -0.531576, -0.272823, 0.642855, 0.663573, -0.382633, -0.554298, 0.822145, -0.129738, -0.000355, -0.943811, -0.330484, -0.466439, -0.200650, 0.861495, -0.429369, -0.837699, 0.337496, 0.524962, -0.377018, 0.763068, 0.517202, 0.376563, 0.768571, 0.997701, -0.040141, -0.054597, 0.269387, 0.926994, 0.260985, 0.488816, -0.272836, -0.828625, -0.255761, 0.904363, -0.341634, -0.475111, -0.450154, 0.756063, 0.342089, 0.647041, 0.681405, -0.685044, -0.219667, 0.694595, 0.857876, -0.422574, 0.292371, 0.460513, -0.876156, -0.142401, -0.912634, -0.399043, 0.088676, -0.214829, -0.150362, 0.965008, 0.485326, -0.783647, 0.387757, 0.420214, 0.787842, 0.450251, 0.266830, -0.768051, 0.582150, 0.076285, 0.672761, 0.735916, 0.722072, -0.397224, 0.566414, 0.291855, -0.332087, 0.896961, -0.843770, 0.311013, 0.437405, -0.498847, 0.605659, -0.619942, 0.272023, 0.450197, 0.850486, -0.580274, -0.806320, 0.114590, 0.323380, -0.942105, 0.088676, -0.232344, -0.402559, 0.885416, 0.733861, 0.672506, 0.095831, 0.977793, 0.192317, 0.083283, -0.677662, -0.459739, 0.573947, -0.230689, -0.815249, 0.531180, 0.832093, 0.423171, -0.358535, -0.362831, 0.064678, 0.929608, -0.234759, -0.629659, 0.740553}; static float ps91 [273] = { -0.069414, 0.511496, 0.856477, 0.119132, -0.636741, 0.761819, -0.758800, -0.584610, 0.287146, -0.930099, 0.151200, 0.334747, -0.675341, 0.296810, 0.675144, 0.439606, 0.857508, -0.267257, 0.166433, -0.975826, -0.141644, -0.167846, -0.205938, 0.964063, 0.532516, 0.798552, 0.280609, -0.316301, -0.405247, 0.857746, 0.348728, -0.872651, 0.341861, 0.528091, -0.720402, 0.449600, 0.262976, -0.045152, 0.963745, 0.811366, -0.088480, -0.577803, -0.175993, -0.920155, 0.349774, 0.486560, 0.086032, 0.869401, -0.175935, -0.643388, 0.745050, 0.920479, 0.176889, 0.348467, -0.434891, -0.583661, 0.685718, 0.281386, -0.954277, 0.100883, -0.003535, 0.929551, 0.368677, -0.687623, -0.598277, -0.411387, 0.673746, -0.516942, 0.528050, 0.449510, 0.729786, 0.515125, -0.421589, -0.118486, 0.899013, 0.092299, -0.923538, 0.372235, 0.910901, 0.109469, -0.397840, 0.957579, 0.275522, 0.084439, 0.061514, 0.697956, 0.713494, -0.492441, 0.191809, 0.848947, -0.487267, 0.481845, 0.728283, -0.294976, -0.911465, -0.286741, -0.566036, -0.698873, 0.437241, 0.787523, 0.346730, 0.509496, 0.826076, 0.365931, -0.428594, -0.041153, -0.458421, 0.887782, 0.903368, -0.393954, -0.169492, 0.436666, -0.213263, 0.873980, 0.575155, -0.372854, 0.728132, 0.444512, 0.358932, 0.820717, -0.301444, 0.884303, 0.356567, -0.984155, 0.162394, 0.071189, 0.854165, 0.453210, 0.254957, 0.944068, -0.295752, 0.145827, 0.658127, -0.084675, 0.748131, 0.780706, -0.250667, 0.572420, 0.118722, -0.266396, 0.956524, -0.036937, -0.809408, 0.586084, 0.845679, 0.533199, -0.022925, 0.918491, -0.127003, 0.374493, 0.714183, 0.686757, 0.135307, 0.109371, 0.986061, 0.125388, -0.683395, 0.728473, 0.047937, 0.288227, -0.443369, 0.848734, 0.762942, -0.589141, -0.266144, 0.193113, 0.828079, 0.526300, 0.423371, -0.599835, 0.678936, 0.446832, -0.888056, -0.108161, 0.466509, 0.883586, 0.040561, -0.318748, -0.783477, 0.533445, -0.643791, 0.561328, 0.520043, 0.541443, -0.826311, 0.155079, -0.563271, 0.763560, 0.315757, 0.666638, 0.218157, 0.712742, 0.247697, -0.778558, 0.576622, -0.840332, 0.415963, -0.347588, -0.037976, 0.263719, 0.963852, 0.585444, 0.496897, 0.640585, -0.261238, 0.085888, 0.961446, -0.556689, -0.312132, 0.769851, -0.756212, -0.193276, 0.625130, -0.423260, 0.723171, 0.545779, 0.822018, 0.046025, 0.567598, 0.332428, 0.616638, 0.713617, 0.986829, 0.091300, -0.133539, -0.294985, 0.364160, 0.883386, 0.988901, 0.004365, 0.148513, -0.015412, 0.992269, -0.123144, -0.258999, -0.961735, 0.089364, 0.815914, -0.365863, -0.447692, -0.636541, -0.008280, 0.771198, 0.186971, 0.461900, 0.867001, 0.844110, -0.533738, 0.051005, -0.644704, -0.754673, 0.121759, -0.258249, 0.633106, 0.729715, 0.232655, 0.213906, 0.948744, 0.000000, -0.000000, 1.000000, -0.133868, 0.812657, 0.567158, 0.717251, -0.647610, 0.257200, -0.654544, -0.484715, 0.580192, -0.920855, -0.342594, 0.186160}; static float ps92 [276] = { -0.553960, -0.437925, 0.708061, 0.912246, 0.334723, 0.236152, 0.588257, -0.302998, 0.749764, -0.516962, 0.675997, 0.525146, 0.779357, -0.611841, 0.135105, -0.248488, 0.737523, 0.627944, 0.760596, -0.342689, 0.551415, -0.731304, 0.073523, 0.678078, 0.994923, 0.094072, 0.035744, -0.841731, -0.533684, -0.081672, -0.884577, 0.385773, 0.262112, 0.347600, -0.256946, 0.901750, 0.142569, 0.523736, 0.839866, -0.337800, 0.338101, 0.878396, -0.594963, 0.755914, 0.273156, -0.200789, 0.979283, -0.026234, 0.403769, 0.834059, 0.375920, -0.750157, -0.290811, 0.593880, -0.230479, 0.119464, 0.965716, 0.786176, 0.403854, 0.467792, -0.231968, -0.757785, 0.609879, -0.779731, 0.610043, 0.140952, -0.392673, -0.292769, 0.871834, -0.621369, -0.721408, 0.305730, 0.348011, 0.660223, 0.665578, 0.914306, -0.404852, 0.011813, -0.241170, -0.957814, 0.156297, 0.136935, -0.466545, 0.873833, -0.132738, -0.903835, 0.406770, 0.144407, -0.960896, -0.236276, -0.404950, 0.544413, 0.734595, 0.030506, 0.715483, 0.697964, 0.567294, -0.557972, 0.605677, -0.952644, -0.084762, -0.292034, -0.620894, 0.426573, 0.657667, -0.042615, 0.972195, -0.230263, -0.342390, -0.932189, -0.117438, -0.815102, -0.540734, 0.207886, -0.555131, 0.212608, 0.804132, -0.728028, 0.543631, 0.417661, -0.488290, -0.867009, 0.099337, -0.392328, -0.841103, 0.372322, -0.613864, 0.789306, -0.012965, -0.487131, -0.665683, 0.565305, -0.706996, -0.526806, 0.471839, 0.580779, 0.791717, 0.189418, 0.136045, 0.945197, 0.296807, 0.734295, 0.605614, 0.306664, 0.396072, 0.443535, 0.803992, 0.576520, -0.761440, 0.296367, 0.941135, 0.331827, -0.064461, -0.349370, 0.850857, 0.392407, 0.562361, 0.660787, 0.497103, 0.675620, 0.200184, 0.709552, -0.878946, -0.323593, 0.350345, -0.795531, 0.288701, 0.532712, 0.967111, 0.099736, -0.233986, 0.234238, -0.684244, 0.690611, -0.619948, -0.150854, 0.770005, 0.972708, -0.163746, 0.164395, 0.387343, -0.493242, 0.778895, 0.240694, -0.891664, 0.383409, -0.144317, 0.549843, 0.822706, -0.920551, 0.137357, 0.365675, 0.289211, -0.002524, 0.957262, -0.051178, 0.329913, 0.942623, -0.400958, 0.900043, -0.170750, 0.028559, 0.053899, 0.998138, -0.313756, -0.552588, 0.772143, 0.417650, -0.751960, 0.510024, -0.067973, -0.996826, -0.041437, 0.464821, 0.199384, 0.862663, -0.072517, 0.874429, 0.479704, -0.443766, -0.011761, 0.896066, 0.208911, 0.267703, 0.940580, 0.606856, 0.453196, 0.652947, 0.843134, 0.150345, 0.516256, 0.719292, -0.569935, 0.397230, 0.543632, -0.052328, 0.837691, -0.039449, -0.643126, 0.764743, -0.696153, -0.717181, 0.031971, -0.981965, 0.158458, 0.103131, 0.878057, -0.381694, 0.288660, 0.057974, -0.823400, 0.564492, 0.082540, -0.215940, 0.972912, -0.128733, -0.406516, 0.904529, 0.198063, 0.823698, 0.531312, 0.889254, -0.135744, 0.436808, -0.411256, 0.902449, 0.128276, -0.860110, -0.074252, 0.504676, 0.746354, -0.072648, 0.661573, -0.185789, -0.147262, 0.971492}; static float ps93 [279] = { 0.309878, -0.602967, 0.735124, 0.661656, 0.595358, 0.455807, 0.431368, -0.743552, 0.510932, -0.194172, 0.183582, 0.963636, -0.099391, 0.668528, 0.737016, 0.994929, 0.077243, 0.064421, 0.918183, -0.396130, -0.004661, -0.327822, -0.811355, 0.483979, -0.877192, -0.409811, 0.250180, -0.874096, -0.205885, 0.439963, 0.037291, -0.616614, 0.786382, -0.278009, 0.773923, 0.568994, 0.895651, -0.343295, -0.282768, -0.179927, -0.485224, 0.855678, 0.976819, -0.181201, 0.113977, -0.804304, 0.579439, 0.131702, 0.346121, 0.588009, 0.731058, -0.857604, -0.458412, -0.233180, 0.548917, -0.538275, 0.639492, 0.439437, -0.892499, -0.101688, 0.626383, 0.779226, -0.021245, 0.465276, -0.102365, 0.879227, -0.366621, 0.572660, 0.733246, 0.939327, -0.066254, 0.336565, -0.041194, -0.895220, 0.443717, 0.794367, 0.372255, 0.480007, -0.818103, -0.574076, 0.033812, 0.501966, 0.168423, 0.848330, 0.980616, -0.128633, -0.147801, -0.146521, 0.987537, 0.057471, 0.448757, 0.722987, 0.525269, 0.749905, -0.435976, 0.497562, -0.504992, -0.816506, 0.279823, -0.942910, -0.332944, -0.008253, -0.213332, 0.928194, 0.304868, 0.328680, -0.936079, 0.125398, 0.150409, 0.738358, 0.657423, -0.435044, 0.076740, 0.897133, -0.128809, -0.991609, 0.010937, -0.416558, 0.337329, 0.844209, -0.969164, -0.142712, 0.200886, 0.821537, -0.186119, 0.538922, -0.160807, 0.440722, 0.883123, -0.065319, -0.270746, 0.960432, 0.157223, -0.784208, 0.600249, 0.264344, 0.096892, 0.959549, 0.066541, 0.277143, 0.958522, 0.712383, 0.647639, -0.270324, -0.384069, -0.320799, 0.865782, 0.884571, -0.364013, 0.291598, -0.000000, 0.000000, 1.000000, -0.543457, 0.647653, 0.534042, -0.639981, 0.726426, 0.250460, -0.613109, 0.426674, 0.664866, 0.518843, -0.817154, 0.251122, 0.632024, -0.288939, 0.719069, -0.237226, -0.936417, 0.258549, 0.103349, 0.519924, 0.847937, 0.683957, -0.026646, 0.729035, -0.553900, -0.657621, 0.510616, -0.566949, -0.128036, 0.813742, 0.683872, 0.245868, 0.686926, 0.405183, -0.365254, 0.838103, -0.636783, 0.169301, 0.752226, 0.562735, 0.466448, 0.682463, -0.742843, -0.467831, 0.478873, 0.934278, 0.208420, 0.289286, -0.716346, -0.257238, 0.648596, 0.914588, -0.068742, -0.398502, -0.551562, -0.446622, 0.704492, 0.213526, -0.168637, 0.962272, 0.662695, -0.646364, 0.378219, 0.334533, 0.361628, 0.870237, -0.132631, -0.748115, 0.650180, -0.246591, -0.863629, -0.439702, 0.843159, 0.096285, 0.528972, -0.033192, 0.861399, 0.506843, -0.793579, 0.586680, -0.161364, -0.515257, -0.813405, -0.269968, -0.713468, -0.669994, -0.205113, -0.746293, 0.520620, 0.414730, 0.643362, -0.765026, 0.028644, 0.052566, -0.976906, 0.207103, 0.147217, -0.415862, 0.897433, 0.436168, -0.823091, -0.363702, -0.263566, -0.104697, 0.958943, -0.780242, -0.001021, 0.625477, 0.050100, 0.964243, 0.260242, -0.354832, -0.614472, 0.704641, -0.798404, 0.273158, 0.536596, 0.251223, -0.891716, 0.376471, 0.308354, 0.932159, 0.189728, -0.407977, -0.911913, 0.044375}; static float ps94 [282] = { 0.758827, 0.029781, 0.650611, -0.066061, 0.937111, 0.342723, 0.062325, -0.015840, 0.997930, -0.072117, 0.819955, 0.567867, 0.114964, -0.968610, 0.220406, 0.314155, -0.526638, 0.789911, 0.034085, 0.660594, 0.749969, 0.177710, 0.825785, 0.535256, -0.847119, -0.233710, 0.477251, -0.104334, 0.993040, 0.054640, 0.463934, 0.721627, 0.513829, -0.877992, 0.049230, 0.476136, 0.140302, 0.987784, -0.067813, 0.459289, -0.303239, 0.834925, -0.952350, 0.188947, 0.239435, 0.213865, 0.210751, 0.953858, 0.561149, 0.787445, 0.255034, 0.752367, 0.642212, 0.146653, -0.316797, 0.829459, 0.460040, 0.759871, -0.589042, 0.275002, -0.728106, -0.084945, 0.680181, -0.732299, 0.170595, 0.659269, -0.333435, -0.210484, 0.918977, -0.999138, 0.040678, 0.008299, 0.458745, 0.174114, 0.871342, -0.587717, -0.752361, 0.297559, 0.856700, -0.168922, 0.487370, 0.163849, -0.874185, 0.457115, -0.544961, 0.255231, 0.798670, -0.064920, -0.243000, 0.967851, -0.716569, 0.580329, 0.386971, -0.048571, 0.242988, 0.968813, 0.339597, -0.936316, 0.089371, -0.771226, -0.620823, 0.140672, 0.379847, 0.921767, 0.077857, -0.412511, 0.481886, 0.773060, 0.298095, 0.642928, 0.705537, 0.643285, 0.257911, 0.720879, -0.250780, 0.673041, 0.695791, 0.963847, -0.088735, 0.251249, -0.324915, -0.681834, 0.655388, -0.895578, 0.348483, -0.276584, -0.356550, -0.825257, 0.437977, -0.311101, 0.252566, 0.916202, 0.685400, -0.257779, 0.681012, 0.958967, 0.087222, -0.269768, -0.500418, 0.654243, 0.567052, -0.559377, -0.232523, 0.795632, -0.309544, 0.927531, 0.209449, -0.974965, -0.218006, 0.043777, 0.063093, -0.481063, 0.874413, 0.586268, -0.681014, 0.438760, 0.376538, -0.722792, 0.579475, -0.214664, 0.013769, 0.976591, 0.575069, -0.055641, 0.816211, -0.496250, 0.016278, 0.868027, -0.557023, -0.631818, 0.539010, -0.832613, 0.326276, 0.447548, 0.390686, 0.422240, 0.817971, 0.130486, 0.455006, 0.880876, -0.224273, -0.445742, 0.866611, -0.719002, 0.684457, 0.120642, 0.888296, 0.114899, 0.444666, 0.892075, 0.451004, 0.028241, -0.087905, -0.828399, 0.553198, 0.570048, 0.510597, 0.643689, -0.598399, -0.800765, 0.026327, -0.458873, -0.471769, 0.752907, -0.687327, -0.386523, 0.614965, -0.522869, 0.849761, 0.067187, -0.751592, -0.527889, 0.395528, -0.542102, 0.775637, 0.323284, 0.134095, 0.970176, 0.201933, 0.208436, -0.278804, 0.937456, 0.613716, -0.773269, 0.159399, 0.960929, 0.181963, 0.208580, 0.381358, 0.905375, -0.186714, -0.778914, -0.344756, -0.523866, -0.147642, 0.478220, 0.865741, -0.652151, 0.440804, 0.616759, -0.954661, 0.296959, -0.020918, 0.840466, -0.539812, 0.047121, -0.869197, 0.449538, 0.205941, -0.096307, -0.648038, 0.755495, 0.329278, -0.054176, 0.942677, 0.326170, 0.880458, 0.344104, 0.143583, -0.714049, 0.685213, 0.691072, 0.592768, 0.413575, 0.549691, -0.510313, 0.661378, 0.862957, 0.413873, 0.289853, -0.893864, -0.373271, 0.248346, -0.127132, -0.937072, 0.325166, 0.750481, -0.436693, 0.496062, 0.402156, -0.855170, 0.327039}; static float ps95 [285] = { 0.472850, 0.874495, 0.108034, -0.705798, 0.198813, 0.679944, -0.719260, 0.582792, 0.378179, -0.817418, 0.327503, 0.473888, 0.591500, 0.455493, 0.665322, -0.452978, -0.161340, 0.876801, 0.709187, 0.648699, -0.276122, 0.678740, -0.275871, 0.680593, 0.785295, 0.258622, 0.562518, 0.079182, -0.957213, -0.278341, 0.482109, -0.474711, 0.736356, -0.951755, -0.293148, -0.090702, -0.209380, -0.611263, 0.763228, 0.233831, -0.120305, 0.964806, 0.425333, 0.836017, 0.346651, -0.460483, 0.688025, 0.560872, 0.800905, -0.003476, 0.598782, -0.451921, -0.584160, 0.674184, -0.304376, -0.402247, 0.863454, 0.304204, 0.891437, -0.335857, 0.990249, 0.048362, -0.130645, 0.166986, -0.947079, 0.274149, -0.000000, 0.000000, 1.000000, 0.254460, -0.402379, 0.879398, -0.401706, 0.843230, -0.357205, -0.420741, -0.062969, -0.904993, 0.937500, -0.143540, -0.317001, 0.209056, -0.821221, 0.530934, 0.453639, -0.681564, 0.574179, 0.990903, 0.033871, 0.130245, 0.269497, 0.778857, 0.566351, 0.898421, 0.282638, 0.336088, -0.634424, 0.489336, 0.598377, -0.503970, 0.097671, 0.858181, 0.757610, -0.640169, 0.127317, 0.831048, 0.423877, -0.360121, -0.181966, 0.726622, 0.662502, -0.664482, -0.522851, 0.533939, -0.831157, 0.457779, -0.315622, -0.843162, -0.532313, 0.075635, 0.846983, -0.241332, 0.473686, -0.346404, 0.935141, -0.074271, 0.652937, 0.705038, 0.276758, -0.510223, -0.735912, 0.445092, 0.352510, 0.583361, 0.731729, -0.673546, -0.080000, 0.734804, -0.568763, -0.354440, 0.742214, 0.914293, 0.146749, -0.377535, 0.455288, -0.232036, 0.859577, 0.004601, -0.518332, 0.855167, -0.771895, -0.265061, 0.577859, 0.000641, 0.853132, 0.521695, -0.520952, 0.348953, 0.779000, -0.078197, -0.980405, 0.180805, -0.743812, -0.501724, -0.441607, -0.105462, 0.994300, 0.015651, 0.899567, -0.434485, 0.044744, -0.188074, -0.921180, -0.340670, 0.831984, 0.522055, 0.187779, 0.687829, 0.725708, 0.015429, -0.357146, 0.551775, 0.753652, 0.020682, -0.288374, 0.957294, -0.204907, -0.188722, 0.960415, 0.839116, -0.030404, -0.543102, -0.536524, -0.824143, 0.181469, 0.528090, 0.667176, 0.525355, -0.265839, -0.779228, 0.567568, -0.043911, 0.271811, 0.961348, -0.322226, -0.943354, 0.079078, 0.978301, -0.201715, -0.047317, 0.084942, 0.678099, 0.730045, 0.155692, 0.982253, 0.104589, 0.925687, 0.020397, 0.377739, 0.201344, 0.182957, 0.962282, -0.276095, 0.853456, 0.442023, 0.045432, 0.895652, -0.442429, -0.291716, 0.321826, 0.900739, 0.240351, -0.630776, 0.737803, -0.102429, 0.522600, 0.846402, 0.637704, -0.673251, 0.374255, 0.939566, 0.302986, -0.159423, 0.949061, -0.220949, 0.224643, -0.261067, 0.068232, 0.962906, 0.336421, -0.922291, -0.190266, 0.886537, -0.403680, -0.226042, 0.682755, -0.488768, 0.543094, 0.562899, -0.811469, 0.157044, 0.156589, 0.451683, 0.878329, 0.763927, -0.631632, -0.132125, 0.401435, 0.342444, 0.849460, 0.617538, 0.211278, 0.757634, -0.573788, 0.813690, 0.093146, 0.624356, -0.045344, 0.779823, 0.001022, -0.742830, 0.669480, 0.535999, -0.774141, -0.336764}; static float ps96 [288] = { 0.629447, -0.366066, 0.685414, 0.181079, -0.983468, -0.001226, -0.117583, 0.547931, 0.828219, -0.562286, -0.668479, 0.486795, -0.209346, -0.566021, 0.797367, -0.854242, 0.518757, 0.034096, -0.288161, 0.143813, 0.946721, 0.661689, 0.162289, 0.732004, 0.196943, 0.908374, 0.368877, -0.381142, 0.605037, 0.699043, 0.019746, -0.155880, 0.987579, 0.557727, 0.647053, 0.519868, 0.540259, -0.793022, -0.281488, 0.674368, -0.736353, -0.054875, 0.801320, 0.262022, 0.537802, -0.590876, -0.280892, 0.756284, 0.256246, -0.693922, 0.672911, 0.441517, -0.896409, -0.038914, -0.757433, -0.574644, 0.309968, 0.140553, -0.861444, 0.488015, -0.746543, -0.663990, 0.042331, 0.841313, 0.008512, 0.540482, 0.124890, 0.637267, 0.760456, 0.458661, 0.824301, 0.331901, 0.998558, -0.014257, 0.051751, 0.513196, -0.597983, 0.615667, 0.847910, 0.511944, 0.137699, -0.069362, 0.329003, 0.941778, -0.483067, -0.066207, 0.873076, 0.679473, -0.106109, 0.725987, -0.782988, -0.212414, 0.584645, -0.366629, 0.792476, 0.487406, 0.208673, -0.328990, 0.920989, -0.875516, 0.192221, 0.443309, -0.969638, -0.154944, 0.189195, 0.185865, 0.948815, -0.255352, 0.330663, 0.751878, 0.570387, 0.879644, -0.408953, 0.242867, 0.481736, 0.046238, 0.875096, 0.745870, -0.478465, 0.463410, -0.338943, 0.389847, 0.856234, -0.304394, -0.942590, -0.137364, -0.896144, 0.370177, 0.244734, 0.948312, 0.078845, 0.307389, -0.898702, -0.050447, 0.435649, 0.079987, 0.810999, 0.579554, -0.573976, 0.428931, 0.697545, -0.313751, -0.721788, 0.616913, 0.092174, -0.546872, 0.832127, 0.468321, -0.226788, 0.853957, -0.893520, -0.433058, 0.118671, -0.745729, 0.605732, 0.277447, 0.393224, 0.913082, -0.107966, -0.006070, 0.976957, 0.213348, 0.612971, -0.684624, 0.394407, -0.757414, 0.626704, -0.183211, -0.357943, -0.335384, 0.871432, 0.551862, -0.814235, 0.180192, 0.377161, -0.476556, 0.794131, -0.695816, -0.456694, 0.554320, -0.022205, -0.727716, 0.685519, 0.943034, -0.169671, 0.286179, 0.115378, -0.893837, -0.433293, 0.070363, -0.964544, 0.254370, -0.527665, 0.190746, 0.827760, 0.175630, 0.424980, 0.888001, 0.966975, 0.248151, 0.058145, -0.559700, -0.825739, -0.069937, 0.613339, 0.424052, 0.666330, 0.388730, -0.801564, 0.454295, -0.389044, -0.836741, 0.385369, -0.097136, -0.995091, 0.018949, -0.594066, -0.772910, 0.222926, -0.973401, 0.109456, 0.201272, 0.750628, 0.503939, 0.427322, 0.437614, 0.309834, 0.844095, -0.093563, -0.374373, 0.922546, -0.702212, -0.014613, 0.711818, 0.319799, -0.919743, 0.227602, 0.680249, 0.687740, 0.253525, 0.265572, -0.067452, 0.961729, -0.960869, 0.276426, -0.017891, 0.897169, 0.323099, 0.301157, -0.731014, 0.218574, 0.646409, -0.870639, -0.331912, 0.363074, -0.021189, 0.090236, 0.995695, 0.223935, 0.185758, 0.956738, 0.384966, 0.551065, 0.740357, -0.582666, 0.635470, 0.506634, 0.822288, -0.242989, 0.514586, -0.158738, 0.735885, 0.658236, -0.293053, 0.923484, 0.247582, -0.239788, -0.115533, 0.963926, -0.122016, -0.863621, 0.489153, -0.473880, -0.522932, 0.708505, -0.758522, 0.437549, 0.482903}; static float ps97 [291] = { 0.480667, 0.584228, 0.653940, 0.683600, 0.454256, 0.571264, -0.386581, 0.290338, 0.875362, 0.994438, -0.058025, 0.087904, 0.681773, -0.730512, 0.039209, 0.976469, 0.198025, 0.085407, -0.330643, 0.900182, 0.283454, 0.057105, 0.338974, 0.939061, -0.626575, -0.107711, 0.771882, -0.793576, 0.049762, 0.606432, 0.926478, -0.180973, 0.329981, 0.943575, 0.094697, 0.317331, 0.063637, 0.075670, 0.995100, -0.362247, 0.579986, 0.729653, -0.160594, -0.358809, 0.919492, -0.204549, -0.881101, 0.426405, 0.516357, -0.848561, -0.115413, 0.799152, 0.597744, 0.063702, 0.948125, -0.306615, 0.083936, 0.716912, 0.186638, 0.671717, -0.917980, -0.390287, 0.070628, -0.586242, 0.594913, 0.549908, -0.369080, 0.767798, 0.523705, -0.183920, 0.452174, 0.872761, -0.171432, 0.181288, 0.968373, -0.572071, 0.744178, 0.344868, 0.184167, -0.663273, 0.725363, 0.288433, -0.957441, -0.010634, 0.533551, 0.083676, 0.841619, 0.128590, 0.929651, 0.345274, -0.044965, 0.994994, -0.089246, 0.618758, 0.765473, 0.176603, 0.842511, -0.534521, 0.066805, 0.266461, -0.927146, 0.263435, 0.691994, -0.662374, 0.287062, 0.847923, -0.004696, 0.530098, 0.027364, 0.581835, 0.812846, -0.899072, 0.402694, 0.171777, -0.746338, 0.314312, 0.586675, 0.891293, 0.394995, 0.222654, 0.483097, -0.776600, 0.404364, -0.889999, -0.310201, 0.334181, -0.773952, 0.491494, 0.399290, 0.840953, -0.436372, 0.319963, 0.308771, 0.222855, 0.924660, 0.242679, 0.668907, 0.702617, 0.979536, 0.120377, -0.161304, 0.749792, 0.568185, 0.339083, 0.031608, -0.933917, 0.356090, 0.559549, 0.707118, 0.432307, 0.444147, -0.647749, 0.618994, 0.302413, -0.028398, 0.952754, -0.532304, -0.581702, 0.615041, 0.176936, 0.980207, 0.088819, 0.388296, 0.883513, 0.261974, 0.042173, -0.188463, 0.981174, -0.193188, -0.086925, 0.977304, -0.354684, -0.491620, 0.795305, -0.917349, -0.038666, 0.396201, -0.081526, 0.979735, 0.182959, 0.203014, 0.963780, -0.172954, -0.087064, -0.602218, 0.793570, -0.891609, 0.229280, 0.390467, -0.647754, -0.756387, 0.091072, -0.750204, 0.633652, 0.188887, -0.417130, 0.024676, 0.908512, -0.132661, 0.886989, 0.442325, 0.488927, -0.857725, 0.158928, 0.665298, -0.544146, 0.511159, 0.275446, -0.281453, 0.919192, -0.976316, 0.144973, 0.160590, -0.802764, -0.554524, 0.219257, 0.841039, 0.288001, 0.457941, -0.612204, 0.153466, 0.775664, -0.738421, -0.466047, 0.487375, 0.287989, 0.459184, 0.840364, 0.095503, -0.457826, 0.883897, -0.790155, -0.217133, 0.573156, -0.598913, -0.357308, 0.716683, 0.697380, -0.098283, 0.709931, 0.374978, -0.479380, 0.793465, 0.526203, 0.345265, 0.777112, 0.242048, -0.822838, 0.514151, -0.638079, -0.682786, 0.355891, 0.502592, -0.191069, 0.843145, -0.429793, -0.769944, 0.471661, -0.428956, -0.903225, -0.013489, 0.328388, 0.803259, 0.496926, -0.407041, -0.242664, 0.880586, 0.601990, -0.384165, 0.700018, -0.553822, 0.410741, 0.724274, -0.153567, 0.716289, 0.680696, -0.011649, -0.798777, 0.601515, 0.066392, 0.809726, 0.583040, 0.791846, -0.287182, 0.538986, -0.265597, -0.707608, 0.654789, -0.442768, -0.865226, 0.235246}; static float ps98 [294] = { 0.614078, -0.522903, 0.591169, 0.552818, 0.259746, 0.791786, 0.648852, 0.443690, 0.618167, 0.679308, -0.711828, 0.178444, 0.331393, 0.921580, 0.202161, -0.448546, -0.857321, 0.252602, -0.662257, -0.262973, 0.701613, 0.760592, -0.543091, 0.355741, 0.402044, -0.683925, 0.608775, -0.528567, -0.087536, 0.844366, 0.979602, 0.007674, 0.200800, 0.154923, -0.789218, 0.594251, -0.114042, -0.828611, 0.548086, -0.509107, -0.860265, -0.027451, 0.698207, 0.598339, 0.393061, -0.727090, 0.010342, 0.686464, -0.434772, 0.895182, 0.098092, -0.996827, -0.063016, 0.048624, -0.012085, -0.990532, 0.136746, -0.201970, -0.925369, 0.320780, -0.592954, 0.736597, 0.325316, -0.032655, -0.247989, 0.968212, 0.130044, -0.926493, -0.353129, -0.368129, 0.349825, 0.861454, 0.847469, 0.492772, 0.197413, 0.440339, -0.183049, 0.878974, -0.699087, -0.703194, -0.129594, 0.836095, 0.545899, -0.054219, 0.329596, -0.858317, 0.393265, -0.295340, -0.184468, 0.937414, -0.734869, 0.282982, 0.616352, -0.118750, 0.467087, 0.876201, 0.825544, 0.360300, 0.434352, 0.318165, 0.314612, 0.894310, -0.548644, 0.455752, 0.700914, -0.134352, 0.242059, 0.960915, -0.834551, -0.177270, 0.521632, 0.637883, -0.271725, 0.720605, 0.041695, 0.824370, 0.564514, -0.854922, 0.349388, 0.383452, -0.349293, 0.083156, 0.933316, -0.949390, -0.098645, 0.298206, -0.227872, 0.788631, 0.571083, 0.889018, 0.344140, -0.302018, 0.782363, -0.575446, -0.238265, -0.962341, 0.151656, 0.225613, -0.914509, 0.173766, -0.365348, 0.073753, -0.923923, 0.375402, -0.534927, -0.549371, 0.641907, -0.527766, -0.789349, -0.313672, -0.276132, -0.958995, 0.063879, -0.049877, -0.673818, 0.737212, 0.416739, 0.506428, 0.754890, -0.313927, 0.593246, 0.741289, -0.733296, -0.434974, 0.522565, -0.224929, -0.442052, 0.868330, 0.556517, -0.724635, 0.406439, 0.124166, 0.929230, 0.348015, -0.567251, 0.187380, 0.801945, 0.226359, -0.593343, 0.772467, -0.457611, -0.366340, 0.810177, -0.065602, -0.991742, -0.110197, 0.026585, -0.478194, 0.877852, 0.113364, 0.195278, 0.974174, 0.749418, 0.187130, 0.635102, -0.915921, 0.384084, 0.116479, 0.442155, -0.445433, 0.778517, 0.899395, -0.382558, 0.211513, -0.304762, -0.633489, 0.711205, 0.947752, 0.314898, -0.051050, 0.315144, 0.816585, 0.483604, -0.372579, 0.860086, 0.348478, 0.498806, 0.660220, 0.561518, 0.243759, -0.958392, 0.148549, 0.386365, 0.068346, 0.919810, -0.767827, -0.564907, 0.302194, -0.042550, 0.668333, 0.742645, 0.193208, -0.975469, -0.105499, -0.650747, 0.755646, 0.074346, 0.944491, 0.258668, 0.202554, 0.617895, -0.002811, 0.786256, -0.475103, 0.683578, 0.554074, -0.089211, -0.004669, 0.996002, -0.690989, 0.531035, 0.490445, 0.230338, 0.676131, 0.699851, 0.794821, -0.082814, 0.601166, 0.477418, -0.864097, 0.159400, -0.585179, -0.690167, 0.425716, 0.826191, -0.562031, 0.039118, 0.789753, -0.339675, 0.510795, 0.895511, 0.101072, 0.433409, 0.133150, 0.480659, 0.866740, -0.364391, -0.781494, 0.506446, 0.178497, -0.071581, 0.981333, 0.657996, 0.739014, -0.144564, -0.872551, 0.095125, 0.479172, 0.235759, -0.328399, 0.914643, 0.978633, -0.199401, 0.050165}; static float ps99 [297] = { 0.805055, 0.591947, 0.038544, 0.400332, 0.652555, 0.643355, -0.415404, 0.759269, 0.500950, 0.808173, -0.203275, -0.552753, -0.501568, -0.171721, -0.847904, -0.859239, 0.510659, -0.030607, -0.810419, 0.495893, -0.311947, 0.712379, -0.686224, 0.147011, -0.614950, -0.639024, 0.462044, -0.295812, -0.921893, 0.250216, -0.638795, -0.439359, 0.631589, -0.759829, -0.025812, 0.649611, -0.734265, -0.643706, 0.215633, 0.710646, -0.204854, 0.673065, -0.630958, 0.650673, -0.422512, -0.792708, -0.490699, -0.361701, 0.907230, 0.391033, 0.155009, -0.386223, 0.161559, 0.908147, 0.279892, -0.488418, 0.826504, 0.044684, 0.899845, 0.433915, -0.202012, 0.465726, 0.861563, 0.146089, 0.757516, 0.636261, -0.756701, 0.445124, 0.478819, 0.547411, 0.709785, 0.443336, -0.205435, -0.509963, 0.835305, -0.195401, -0.714996, 0.671267, -0.846460, -0.265729, -0.461404, -0.174646, -0.019156, 0.984445, -0.928871, -0.229052, 0.291092, 0.393421, -0.784796, 0.478868, -0.156075, -0.872640, 0.462752, 0.687402, 0.042773, 0.725016, 0.511469, -0.110419, 0.852178, -0.798695, -0.459035, 0.389067, -0.708123, 0.695125, 0.123952, -0.319305, 0.933337, -0.164095, -0.556104, 0.556233, 0.617538, 0.253986, -0.695788, 0.671841, 0.051883, 0.401229, 0.914507, -0.233967, 0.899662, 0.368602, -0.639944, 0.307777, 0.704092, -0.431987, -0.595076, 0.677696, 0.225196, 0.948058, 0.224660, 0.486987, -0.584826, 0.648708, -0.314935, 0.636212, 0.704308, 0.053716, -0.811865, 0.581369, 0.191646, -0.902878, 0.384815, -0.649227, 0.658382, 0.380838, -0.804326, -0.253064, 0.537605, 0.943683, -0.074442, 0.322366, 0.029927, -0.617933, 0.785661, 0.531242, -0.847218, -0.001968, -0.493149, 0.829472, 0.262259, 0.231979, 0.547788, 0.803812, -0.427382, -0.373806, 0.823173, -0.956089, 0.283820, 0.073072, -0.616359, -0.210269, 0.758873, 0.285720, 0.293242, 0.912345, -0.904843, -0.011112, 0.425601, 0.953519, 0.165578, 0.251765, -0.980146, -0.197065, 0.021900, 0.845738, 0.017089, 0.533325, 0.107138, -0.993026, 0.049211, 0.982805, -0.025582, -0.182864, 0.077577, 0.127737, 0.988769, -0.039247, 0.978752, 0.201257, -0.022099, -0.963597, 0.266445, 0.530494, 0.808425, -0.255001, -0.397500, -0.778998, 0.484929, -0.590490, 0.072882, 0.803748, -0.894628, -0.426480, 0.133247, 0.044219, -0.391477, 0.919125, -0.911990, 0.253896, 0.322198, -0.154182, 0.236875, 0.959228, 0.060706, -0.138439, 0.988509, -0.150452, -0.988376, 0.021838, 0.688131, 0.685269, 0.238498, -0.306570, 0.944581, 0.117393, -0.192999, -0.273175, 0.942405, 0.995983, -0.054409, 0.071116, -0.848306, 0.267815, -0.456784, -0.412314, -0.113310, 0.903968, 0.691883, -0.443745, 0.569551, 0.477418, 0.426997, 0.767949, -0.516835, 0.816007, -0.258872, -0.029489, 0.634423, 0.772423, -0.435506, 0.396375, 0.808221, 0.933975, -0.303659, 0.188368, 0.837865, -0.493886, -0.232506, -0.473114, -0.851294, -0.226853, 0.512881, -0.359809, 0.779417, -0.643557, -0.511628, -0.569272, -0.138963, 0.795081, 0.590369, 0.303111, 0.014832, 0.952840, -0.621392, -0.783476, 0.006110, 0.291095, -0.250808, 0.923233, 0.310817, 0.837377, 0.449658, -0.399799, -0.916520, 0.012340, 0.691265, 0.285524, 0.663798}; static float ps100 [300] = { -0.347525, -0.619580, 0.703809, 0.302255, -0.336903, 0.891705, 0.810019, -0.424441, 0.404623, -0.600593, 0.332731, 0.727033, -0.434892, -0.384048, 0.814479, -0.256787, 0.030420, 0.965989, 0.913518, 0.162240, -0.373045, 0.515225, 0.162765, 0.841458, 0.641736, -0.756502, 0.126012, 0.870980, 0.486810, 0.066405, -0.707903, 0.466592, 0.530250, 0.750779, -0.268205, 0.603653, -0.805454, -0.058584, 0.589755, 0.108435, 0.357285, 0.927680, 0.545766, -0.310945, 0.778109, 0.279921, -0.943915, 0.175125, -0.075707, 0.838424, 0.539735, -0.580116, -0.500152, 0.642894, 0.282654, 0.143715, 0.948395, -0.012972, 0.687364, 0.726197, -0.172335, -0.485701, 0.856968, -0.847951, -0.405076, 0.341896, 0.848909, 0.216426, 0.482197, 0.585397, 0.650722, 0.483602, -0.648836, 0.061633, 0.758428, -0.465187, -0.096043, 0.879987, 0.442818, -0.091827, 0.891897, -0.255133, -0.252746, 0.933288, -0.936416, 0.322432, -0.138428, 0.477187, -0.825644, 0.301004, 0.204821, -0.975873, -0.075637, -0.406616, -0.868907, 0.282248, -0.920668, 0.091004, 0.379591, -0.171379, -0.932429, 0.318128, -0.619191, -0.751820, 0.226647, 0.387047, 0.811989, 0.436885, -0.130286, 0.938937, 0.318470, -0.252552, -0.805905, 0.535476, 0.657576, -0.060744, 0.750936, -0.787903, 0.210572, 0.578678, 0.663375, -0.646106, 0.377466, 0.022999, 0.127615, 0.991557, -0.081256, -0.682385, 0.726463, -0.632713, -0.218934, 0.742793, -0.381851, 0.885528, 0.264631, 0.004028, -0.837408, 0.546564, 0.331933, 0.923102, 0.194175, -0.101692, 0.496560, 0.862025, 0.456007, -0.889975, 0.001310, -0.600511, 0.778704, 0.181678, 0.988136, 0.060440, -0.141185, -0.757130, 0.577446, 0.305466, -0.367402, 0.436311, 0.821370, -0.971135, 0.195638, 0.136467, 0.259222, 0.963787, -0.062600, 0.992405, -0.076185, 0.096587, -0.799574, -0.578270, 0.162129, -0.502208, 0.580272, 0.641149, 0.123621, -0.544719, 0.829457, -0.870695, 0.343400, 0.352089, -0.702141, -0.710927, -0.039746, 0.888663, 0.361589, 0.282012, 0.393042, -0.533759, 0.748745, 0.138882, 0.910217, 0.390149, 0.203278, -0.106825, 0.973276, -0.445810, 0.185248, 0.875749, 0.939730, 0.319030, -0.122991, -0.561525, 0.707684, 0.428803, 0.411147, 0.621389, 0.666959, 0.208082, -0.714432, 0.668048, 0.495994, 0.868190, -0.015352, 0.075475, 0.985665, 0.150890, -0.689419, -0.586649, 0.424904, 0.831703, -0.031012, 0.554355, 0.034403, -0.342848, 0.938761, -0.049357, -0.114276, 0.992222, 0.975069, 0.199391, 0.097385, 0.195800, 0.565090, 0.801459, 0.077541, -0.942158, 0.326077, -0.897550, 0.430220, 0.096511, 0.371071, 0.382385, 0.846220, 0.200032, 0.770110, 0.605738, 0.749951, 0.599573, 0.279438, 0.911711, -0.194980, 0.361615, -0.331241, 0.799874, 0.500481, 0.575745, 0.424972, 0.698510, -0.187513, 0.276080, 0.942666, -0.768325, 0.637733, 0.054531, 0.560691, 0.791563, 0.243008, 0.463487, -0.694610, 0.550179, -0.760861, -0.325422, 0.561418, -0.487143, -0.722273, 0.490931, 0.818877, -0.545138, 0.179625, 0.274155, -0.846696, 0.456009, 0.703729, 0.197627, 0.682429, 0.948433, 0.057595, 0.311701, 0.000724, -0.995887, 0.090597, 0.625131, -0.497044, 0.601797, -0.267172, 0.658836, 0.703246, 0.738950, 0.447524, 0.503662}; static float ps101 [303] = { -0.656303, 0.538641, 0.528330, 0.098306, 0.728407, 0.678055, -0.493388, 0.805891, -0.327273, 0.587785, 0.466172, 0.661205, -0.998272, 0.038547, -0.044350, -0.971100, -0.237759, -0.020870, 0.133141, 0.331410, 0.934046, -0.015359, 0.863622, 0.503906, -0.851914, 0.377565, 0.362887, 0.413174, -0.254902, 0.874250, -0.950875, 0.291869, -0.103194, -0.287432, 0.832904, 0.472920, -0.431758, 0.005418, 0.901973, 0.051812, -0.766546, 0.640096, 0.282559, 0.811107, 0.512120, 0.508184, -0.022274, 0.860960, 0.876657, 0.306806, 0.370598, -0.289768, -0.210493, 0.933663, -0.425760, 0.656065, 0.623143, 0.381553, 0.633494, 0.673129, 0.163414, 0.931373, 0.325331, 0.556765, 0.828265, 0.063166, -0.795840, 0.047622, 0.603631, -0.636459, -0.053547, 0.769449, -0.785501, -0.563910, 0.254941, -0.784360, -0.414121, 0.461826, 0.858257, -0.370529, 0.355110, -0.649744, 0.747129, -0.140110, 0.871941, 0.059943, 0.485929, -0.885632, -0.141672, 0.442250, 0.576910, 0.216855, 0.787495, 0.127669, -0.318003, 0.939454, -0.911037, 0.123658, 0.393346, -0.372432, 0.900085, 0.226146, -0.592591, -0.466387, 0.656749, -0.175060, -0.636676, 0.750997, 0.736481, 0.508008, 0.446681, 0.196797, 0.543211, 0.816206, 0.856434, 0.477153, 0.197093, 0.545928, 0.681083, 0.487942, -0.422424, -0.893414, 0.152873, 0.332638, 0.157314, 0.929841, -0.216858, 0.975842, 0.026545, -0.126435, 0.948167, 0.291536, -0.358793, -0.466044, 0.808747, 0.718826, 0.013772, 0.695053, 0.516336, -0.470278, 0.715706, -0.701732, 0.613263, -0.362603, -0.621282, -0.754588, 0.211201, -0.035616, -0.993848, -0.104870, -0.377649, 0.265341, 0.887116, -0.194216, -0.976840, 0.089794, 0.042107, -0.983895, 0.173719, -0.764545, 0.642105, 0.056330, 0.637885, -0.234463, 0.733574, -0.171619, 0.715481, 0.677225, -0.195923, -0.806074, 0.558443, -0.893306, 0.434919, 0.113353, -0.735318, -0.240169, 0.633740, -0.450061, 0.891439, -0.052735, -0.967113, 0.198245, 0.159350, -0.300868, 0.505600, 0.808608, 0.296623, -0.670736, 0.679800, -0.053436, 0.542979, 0.838044, -0.201672, -0.920457, 0.334794, 0.323610, 0.938278, 0.122111, 0.963031, 0.126479, 0.237856, 0.682211, 0.684504, 0.256987, 0.043160, -0.905565, 0.422006, 0.943128, -0.126612, 0.307375, -0.605640, 0.196222, 0.771166, 0.060021, 0.098872, 0.993288, -0.535178, 0.433116, 0.725256, -0.754313, 0.302278, 0.582786, 0.292969, -0.471827, 0.831594, -0.529404, 0.748080, 0.400134, -0.887915, -0.457874, 0.044255, -0.200119, 0.066142, 0.977537, 0.451560, 0.835615, 0.312796, -0.276665, 0.929264, -0.244797, 0.707255, -0.437884, 0.555021, -0.121347, -0.405033, 0.906214, -0.587702, 0.795559, 0.147282, 0.241647, -0.083957, 0.966725, -0.413656, -0.659874, 0.627260, -0.044156, -0.143141, 0.988717, -0.513951, -0.268495, 0.814717, 0.398157, 0.390696, 0.829956, -0.915800, -0.312148, 0.252734, 0.518510, -0.661979, 0.541231, 0.836733, -0.524940, 0.155936, -0.127647, 0.314671, 0.940579, 0.623069, 0.634809, -0.456948, -0.977995, -0.066981, 0.197586, 0.283490, -0.827186, 0.485177, -0.746765, -0.665051, -0.007045, 0.061074, -0.572579, 0.817572, 0.752708, 0.270938, 0.600019, 0.816775, -0.190721, 0.544521, -0.736727, 0.604457, 0.303094, -0.429855, -0.806139, 0.406650}; static float ps102 [306] = { -0.562294, 0.181234, 0.806833, 0.624838, -0.283908, 0.727306, 0.583800, -0.537572, 0.608436, 0.186654, -0.320199, 0.928780, 0.272833, 0.757214, 0.593456, 0.433207, -0.901035, 0.021616, -0.060932, -0.843222, 0.534101, -0.743328, 0.063136, 0.665941, 0.065083, -0.941568, 0.330474, -0.544125, -0.066036, 0.836401, -0.677796, -0.694572, 0.241168, -0.925122, 0.311877, 0.216523, 0.666079, 0.718104, 0.201656, -0.311792, -0.161185, 0.936379, 0.361697, 0.063877, 0.930105, 0.670777, 0.405322, 0.621105, 0.220647, -0.833758, 0.506124, 0.078865, -0.714587, 0.695087, 0.744913, 0.159633, 0.647782, 0.977170, 0.009468, 0.212248, -0.381028, 0.602804, 0.701032, -0.312771, -0.775907, 0.547853, 0.465379, -0.849416, -0.248828, -0.536816, -0.676261, 0.504480, -0.630069, -0.439548, 0.640165, -0.027917, -0.495203, 0.868328, 0.432099, -0.426489, 0.794605, 0.989981, -0.136510, -0.036079, -0.253410, 0.952857, 0.166876, 0.785096, 0.619291, -0.010168, 0.149813, -0.079837, 0.985486, 0.890433, 0.090247, 0.446076, 0.259486, 0.573665, 0.776901, -0.709673, -0.192609, 0.677691, -0.965848, 0.025809, 0.257821, 0.257671, 0.891226, 0.373259, 0.436461, -0.753920, -0.491026, 0.547970, 0.208489, 0.810100, -0.413090, -0.568038, 0.711822, -0.492578, -0.315391, 0.811108, 0.067166, 0.251198, -0.965603, -0.467544, -0.829246, 0.306193, -0.347723, 0.356238, 0.867285, 0.005653, 0.948548, 0.316582, 0.296470, 0.316136, 0.901201, 0.193642, -0.974967, 0.109277, 0.358826, 0.928647, -0.094118, 0.469128, 0.440206, 0.765596, -0.583937, 0.786040, -0.202875, 0.939625, 0.231665, -0.251867, -0.128732, 0.272758, 0.953431, 0.349673, -0.892220, 0.285783, -0.618095, 0.571327, 0.539948, -0.734262, 0.314706, 0.601514, 0.484894, -0.749951, 0.449946, -0.806444, 0.571244, 0.152738, -0.727557, -0.535809, 0.428451, 0.034265, 0.672876, 0.738961, 0.212188, -0.541227, 0.813664, -0.853035, -0.472747, 0.221001, 0.105040, 0.172025, 0.979476, 0.834088, 0.505431, 0.220990, 0.924929, 0.380139, -0.000543, -0.772071, 0.624658, -0.117085, 0.891589, -0.172910, 0.418534, -0.191737, 0.749749, 0.633335, -0.877507, 0.190435, 0.440131, 0.451608, 0.876276, 0.167902, 0.585681, 0.809574, -0.039583, -0.825300, -0.311085, 0.471281, 0.952550, -0.240224, 0.186927, -0.024774, 0.996916, 0.074458, 0.651358, -0.688369, -0.319188, 0.594329, -0.036078, 0.803413, 0.907728, -0.419196, 0.017467, -0.225026, -0.911956, 0.343073, -0.220473, -0.967329, -0.125168, 0.065113, 0.439306, 0.895974, -0.343914, 0.099122, 0.933755, 0.034008, 0.841290, 0.539513, -0.172437, -0.659523, 0.731638, -0.872835, -0.066953, 0.483401, 0.829927, 0.344994, 0.438407, 0.847960, -0.441306, 0.293620, 0.991588, 0.127668, -0.021301, -0.265580, -0.418631, 0.868456, 0.495538, 0.627148, 0.600939, -0.165289, 0.534584, 0.828794, 0.690738, -0.614048, 0.381872, 0.690707, 0.584372, 0.425950, -0.106074, 0.006599, 0.994336, 0.939678, 0.258455, 0.224069, -0.545520, 0.417913, 0.726469, -0.104045, -0.984948, 0.138031, 0.764111, -0.371442, 0.527413, 0.360011, -0.666803, 0.652507, 0.405602, -0.188075, 0.894491, 0.774829, -0.096475, 0.624766, -0.799613, 0.457733, 0.388714, -0.226094, 0.882004, 0.413462, 0.490679, 0.774429, 0.399367, -0.641239, 0.764842, 0.061884}; static float ps103 [309] = { 0.307533, 0.322794, 0.895113, 0.885169, 0.130899, 0.446476, -0.233530, 0.417911, 0.877960, -0.529006, -0.842498, -0.101730, 0.640094, 0.394975, 0.658995, -0.132620, 0.989785, 0.052324, 0.048589, 0.972047, 0.229705, 0.028784, -0.320235, 0.946901, 0.913282, -0.105658, 0.393386, -0.044933, 0.891352, 0.451079, 0.195244, -0.915289, 0.352314, -0.539758, -0.003430, 0.841813, -0.631090, -0.249166, 0.734603, 0.800203, 0.241348, -0.549023, -0.807408, -0.441295, 0.391601, -0.735371, -0.675289, -0.056699, -0.881365, -0.003309, 0.472424, -0.426414, -0.239027, 0.872374, 0.733400, 0.006601, -0.679766, -0.304295, 0.621580, 0.721833, 0.651975, -0.515406, 0.556134, -0.023625, 0.982328, -0.185671, -0.885071, -0.461200, -0.062802, -0.929565, 0.343076, 0.134935, 0.468355, -0.472691, 0.746463, 0.799747, 0.367603, 0.474630, -0.233683, 0.930277, 0.282802, 0.602509, -0.032711, 0.797442, 0.929518, -0.184207, -0.319475, -0.674852, 0.457682, 0.578880, -0.444396, -0.824456, 0.350406, -0.044840, 0.578578, 0.814393, -0.800686, 0.232723, 0.552034, -0.782899, -0.596042, 0.178334, -0.651681, -0.473489, 0.592554, 0.305963, -0.943133, 0.129949, 0.881505, -0.466458, 0.073251, 0.407722, -0.907784, -0.098442, 0.150257, 0.749266, 0.644998, 0.807635, -0.321434, 0.494375, 0.440150, 0.813081, 0.381008, 0.981546, 0.027285, 0.189268, -0.826116, 0.426945, 0.367765, 0.207372, 0.877320, 0.432789, -0.304350, 0.806148, 0.507441, 0.981497, 0.191470, -0.001448, -0.629400, 0.231272, 0.741869, 0.256024, -0.400767, 0.879680, -0.644463, -0.656899, 0.391346, 0.735525, 0.156655, 0.659137, -0.913139, -0.373537, 0.163240, -0.986876, 0.159616, -0.024460, -0.929119, -0.189294, 0.317658, 0.928279, 0.281951, 0.242491, 0.011740, -0.551648, 0.833994, -0.028423, -0.888772, 0.457467, 0.390973, 0.697578, 0.600438, 0.986828, 0.000707, -0.161769, -0.540006, 0.831811, -0.128391, -0.483380, 0.810671, 0.330390, 0.444708, -0.223821, 0.867259, -0.132384, 0.198867, 0.971044, -0.011355, -0.742711, 0.669516, 0.243879, -0.619294, 0.746323, -0.243503, -0.646015, 0.723444, 0.440244, 0.497772, 0.747267, 0.800426, -0.506835, 0.320057, 0.307352, 0.933234, 0.186033, 0.929260, -0.285748, 0.234145, 0.631369, -0.689233, 0.355430, 0.426731, -0.827033, 0.365947, 0.255663, 0.810383, -0.527177, 0.640000, 0.710556, 0.292419, 0.455053, -0.677070, 0.578363, 0.529190, 0.225993, 0.817854, -0.468016, -0.668007, 0.578557, 0.149988, 0.988639, -0.009806, 0.614906, 0.597720, 0.514414, -0.383886, -0.918609, 0.093752, 0.384146, 0.043964, 0.922225, 0.048768, 0.371686, 0.927077, -0.023321, -0.037563, 0.999022, 0.150242, 0.137329, 0.979065, -0.507264, 0.653045, 0.562330, -0.602266, -0.783868, 0.151086, -0.800790, 0.580296, 0.148298, -0.483271, 0.447123, 0.752681, -0.799700, -0.524212, -0.292715, 0.644745, -0.289168, 0.707592, -0.674906, 0.640322, 0.366727, 0.454710, 0.471385, -0.755668, 0.207467, 0.558469, 0.803163, -0.097724, 0.754212, 0.649319, -0.733601, 0.671043, -0.107377, -0.305685, 0.011640, 0.952061, 0.783103, -0.087535, 0.615701, -0.629560, 0.767849, 0.118588, -0.214620, -0.934867, 0.282774, 0.221465, -0.792451, 0.568308, -0.407521, 0.232212, 0.883179, -0.221096, -0.444229, 0.868203, -0.194909, -0.212365, 0.957555, 0.214941, -0.140584, 0.966456}; static float ps104 [312] = { 0.430465, 0.723375, 0.539840, -0.061692, -0.885862, 0.459829, 0.655255, -0.701076, 0.281307, -0.028043, 0.722434, 0.690871, 0.392440, 0.553661, 0.734473, -0.665191, -0.734729, 0.133023, -0.902448, -0.149218, 0.404131, 0.570577, 0.363340, 0.736495, 0.019347, -0.973906, 0.226127, -0.924884, -0.314105, 0.214306, -0.236831, -0.938990, 0.249416, -0.500865, -0.808534, 0.308881, -0.720798, 0.502844, 0.477072, -0.640321, -0.141941, 0.754878, 0.758614, 0.377968, 0.530702, -0.267767, 0.664985, 0.697205, 0.533328, -0.672458, 0.513187, 0.870474, -0.291182, 0.396848, -0.368105, -0.552447, 0.747865, 0.085602, 0.329483, 0.940273, -0.980179, -0.019286, 0.197172, -0.223324, -0.395212, 0.891029, -0.352808, -0.194518, 0.915253, -0.811215, 0.001605, 0.584746, 0.523267, -0.291339, 0.800821, 0.775340, 0.624075, 0.096841, -0.914821, 0.134882, 0.380671, 0.259102, 0.117704, 0.958651, 0.057956, -0.758889, 0.648636, -0.524199, 0.577202, 0.626142, -0.808066, -0.425317, 0.407596, 0.153195, 0.550954, 0.820354, 0.164892, -0.574496, 0.801726, -0.204298, -0.728764, 0.653579, 0.907203, 0.417834, 0.048959, -0.429140, -0.899276, 0.084502, 0.592236, 0.800235, 0.094240, -0.084245, -0.581895, 0.808889, -0.355496, 0.464597, 0.811032, -0.761601, -0.265779, 0.591038, 0.290269, -0.342719, 0.893469, -0.344447, 0.937124, 0.056172, -0.150976, 0.951524, 0.267972, 0.743607, -0.506885, 0.436024, 0.158909, -0.130816, 0.978588, -0.244578, 0.052071, 0.968230, -0.600458, 0.366304, 0.710824, 0.337011, 0.347518, 0.875017, -0.821817, -0.545414, 0.164745, -0.392794, 0.873092, 0.288832, -0.097827, -0.162963, 0.981770, 0.425958, -0.831759, 0.356000, 0.835847, -0.509012, 0.205590, 0.356565, 0.921117, 0.156223, -0.091945, 0.995532, 0.021517, 0.006970, 0.087643, 0.996128, 0.040299, -0.372569, 0.927129, 0.716531, 0.159897, 0.678982, -0.788536, 0.271713, 0.551709, 0.606729, 0.561023, 0.563146, -0.887246, 0.459326, 0.042602, -0.481376, -0.675535, 0.558506, 0.504496, 0.141300, 0.851773, -0.607869, 0.703741, 0.367755, -0.660364, 0.128522, 0.739866, -0.871633, 0.381604, 0.307627, 0.532662, 0.781669, 0.324445, -0.096269, 0.518284, 0.849773, 0.955999, 0.184857, 0.227802, 0.640710, -0.066781, 0.764873, 0.406255, -0.092278, 0.909088, 0.827887, -0.052452, 0.558437, 0.946598, -0.285425, 0.149951, -0.507308, -0.349150, 0.787866, 0.860095, 0.414640, 0.297170, 0.713832, 0.612377, 0.339762, -0.182850, 0.845981, 0.500882, 0.097153, 0.969107, 0.226700, -0.483622, 0.003622, 0.875270, 0.396554, -0.537494, 0.744207, -0.521030, 0.845843, -0.114358, 0.286445, 0.874041, 0.392429, 0.738229, -0.268459, 0.618828, -0.583948, 0.801542, 0.128592, -0.309527, -0.831806, 0.460751, -0.872359, -0.171337, -0.457857, 0.606279, -0.471538, 0.640373, 0.944300, -0.060980, 0.323387, 0.207535, 0.740539, 0.639165, 0.996016, -0.053020, 0.071697, -0.426311, 0.241447, 0.871758, 0.052513, 0.880455, 0.471213, -0.628012, -0.480927, 0.611809, -0.172776, 0.294284, 0.939971, 0.270368, -0.945056, 0.183765, 0.769411, -0.602506, -0.212115, -0.410876, 0.757936, 0.506669, -0.734123, 0.678053, -0.036163, -0.982540, -0.185570, 0.013380, 0.186531, -0.883903, 0.428861, -0.673324, -0.631863, 0.383906, 0.305611, -0.735957, 0.604127, -0.965955, 0.228545, 0.121236, 0.166078, 0.985983, -0.015971}; static float ps105 [315] = { -0.660053, 0.282320, 0.696151, 0.228505, 0.152326, 0.961552, 0.443662, 0.795300, 0.413112, -0.888348, -0.107785, 0.446341, -0.173847, 0.933987, 0.312162, 0.088304, -0.434199, 0.896478, 0.668816, -0.665909, 0.330530, -0.209140, 0.628920, 0.748813, -0.741690, -0.179777, 0.646201, 0.468896, -0.830915, 0.299528, 0.695031, -0.275391, 0.664148, 0.608804, -0.042373, 0.792188, -0.447356, 0.461154, 0.766296, -0.251971, 0.187220, 0.949452, -0.195148, 0.979178, 0.055919, -0.790035, -0.370868, 0.488162, -0.440060, -0.027983, 0.897532, 0.531100, -0.503684, 0.681348, -0.415833, -0.897380, 0.147620, 0.666822, 0.195458, 0.719127, 0.060911, -0.639173, 0.766647, -0.982651, 0.171235, 0.071244, 0.672035, 0.420277, 0.609702, -0.588754, 0.701759, 0.401128, -0.980093, -0.047725, 0.192717, 0.767205, 0.639479, -0.049627, -0.614678, -0.437908, 0.656054, -0.926402, 0.138063, 0.350310, 0.605516, 0.760926, 0.233113, 0.594519, 0.804021, -0.009868, -0.402315, -0.494725, 0.770318, -0.200999, -0.839426, 0.504939, -0.978478, -0.206261, 0.006122, -0.219562, -0.975580, -0.005981, 0.232102, -0.948230, 0.216770, 0.788489, -0.035805, 0.614005, 0.007030, 0.323228, 0.946295, 0.787360, 0.537899, -0.301211, 0.829767, 0.196524, 0.522365, 0.267997, -0.849910, 0.453686, -0.623231, -0.738138, 0.258330, 0.035977, 0.983717, 0.176086, 0.250317, 0.787397, 0.563336, 0.903436, -0.361105, -0.231100, -0.472787, 0.227035, 0.851427, 0.478702, 0.424966, 0.768276, -0.019359, 0.085332, 0.996165, 0.287744, -0.700820, 0.652728, -0.818404, -0.414687, -0.397805, -0.186511, -0.684940, 0.704323, 0.463349, 0.194653, 0.864533, -0.629688, 0.509368, 0.586546, 0.408648, 0.901459, 0.142753, 0.844367, -0.446451, 0.296185, 0.391647, -0.046709, 0.918929, 0.950106, -0.227608, 0.213292, -0.225810, 0.419753, 0.879100, -0.422345, 0.665319, 0.615610, -0.789928, 0.602638, -0.113318, -0.762360, 0.535136, 0.363917, 0.623525, -0.777233, 0.084405, -0.499318, 0.693798, -0.518966, 0.041413, -0.807893, 0.587873, 0.917315, -0.397240, 0.027082, 0.550350, 0.241053, -0.799380, -0.325787, -0.287908, 0.900540, -0.940042, -0.189712, -0.283427, 0.280815, -0.280884, 0.917740, 0.001647, -0.994166, 0.107846, 0.262999, 0.605298, 0.751296, 0.317859, -0.507979, 0.800577, 0.133255, -0.101889, 0.985831, 0.707724, -0.489663, 0.509271, -0.413968, 0.890731, 0.187693, -0.993101, 0.004183, -0.117187, 0.024244, 0.542975, 0.839399, 0.894764, 0.437719, -0.088311, -0.806202, 0.084775, 0.585536, 0.503409, -0.282360, 0.816610, 0.921103, -0.030969, 0.388085, 0.474986, 0.629361, 0.615056, 0.254023, 0.390463, 0.884879, -0.641864, 0.025712, 0.766387, 0.236192, 0.919254, 0.314939, -0.417682, -0.678246, 0.604587, 0.625405, -0.763001, -0.163395, -0.379984, 0.824666, 0.418972, -0.426196, -0.814755, 0.393104, 0.033660, 0.734446, 0.677832, 0.778449, 0.595673, 0.197968, -0.655263, -0.613722, -0.440428, -0.062937, -0.258043, 0.964081, 0.623813, 0.614690, -0.482714, -0.798311, 0.588261, 0.129029, -0.181697, 0.805357, 0.564257, -0.205071, -0.941390, 0.267827, 0.025037, -0.929344, 0.368364, -0.419100, 0.906258, -0.055246, -0.905690, -0.394711, -0.154689, -0.810122, 0.323294, 0.489064, 0.033242, 0.890975, 0.452834, 0.846794, -0.257586, 0.465391, -0.161658, -0.488147, 0.857659, -0.211941, -0.067897, 0.974921, -0.916804, -0.286190, 0.278505}; static float ps106 [318] = { 0.008146, -0.774933, 0.631991, -0.760255, 0.503664, 0.410287, -0.866262, -0.369114, -0.336666, -0.833553, 0.233310, 0.500755, 0.806285, -0.587363, 0.070070, 0.391804, 0.753060, 0.528573, -0.337652, 0.752343, 0.565660, 0.258827, 0.043355, 0.964950, 0.310822, -0.742526, 0.593333, 0.707807, 0.690422, 0.149419, -0.368652, 0.177911, 0.912383, -0.480601, -0.715685, 0.506772, -0.131621, 0.203582, 0.970170, -0.916530, -0.370584, 0.150464, -0.286942, -0.419053, 0.861429, 0.615717, -0.120877, 0.778640, 0.495195, 0.085087, 0.864605, 0.404319, 0.546452, 0.733427, -0.264465, -0.039946, 0.963568, -0.515002, 0.844294, -0.148121, 0.210034, 0.707383, 0.674903, 0.000000, 0.000000, 1.000000, -0.061801, 0.429630, 0.900888, 0.845908, -0.293453, 0.445337, -0.799896, -0.589996, 0.109870, -0.410926, 0.841555, 0.350608, 0.734544, 0.569395, 0.369101, 0.566008, 0.351456, 0.745730, -0.763826, -0.302901, 0.569931, -0.235343, 0.621164, 0.747509, -0.309926, -0.881278, 0.356784, 0.947176, 0.148470, 0.284280, 0.792289, -0.087570, 0.603829, 0.688829, 0.133925, 0.712445, 0.677897, -0.689112, 0.256087, -0.474592, 0.537709, 0.696872, -0.982819, 0.150150, 0.107340, -0.310461, 0.411557, 0.856875, -0.151264, -0.975015, 0.162678, -0.158651, 0.896268, 0.414166, -0.808087, 0.560970, 0.179747, 0.010967, 0.627129, 0.778838, 0.027728, -0.999334, -0.023709, 0.924748, -0.379827, -0.023927, 0.346624, -0.883602, 0.314800, 0.907263, 0.201203, -0.369312, -0.681017, 0.402790, 0.611536, -0.523494, -0.806479, 0.274854, -0.545954, 0.295245, 0.784069, -0.550392, -0.378713, 0.744073, -0.982677, -0.113845, 0.146239, -0.959715, -0.272323, -0.069194, -0.690252, -0.642984, 0.331849, -0.133634, -0.240828, 0.961324, -0.863072, 0.440058, -0.247901, 0.499120, -0.354260, 0.790809, -0.532581, 0.014017, 0.846263, 0.386907, -0.161178, 0.907923, 0.159992, -0.872085, 0.462462, -0.388159, -0.917038, 0.091504, -0.709411, 0.125899, 0.693460, 0.367213, 0.293527, 0.882608, 0.097161, -0.969041, 0.226980, -0.285692, 0.956147, -0.064524, -0.403611, -0.582434, 0.705598, 0.843535, 0.150589, 0.515530, -0.008694, -0.440406, 0.897756, -0.245442, -0.770569, 0.588203, 0.315008, 0.892960, 0.321547, 0.226088, 0.969385, 0.095794, -0.568239, 0.651539, 0.502595, 0.512161, -0.740262, 0.435549, -0.424247, -0.213459, 0.880028, -0.902272, 0.328064, 0.279785, -0.937776, 0.062032, 0.341654, -0.220107, 0.957859, 0.184550, 0.123192, 0.249363, 0.960542, -0.630731, -0.773494, 0.062338, 0.996119, 0.006144, 0.087801, 0.247101, -0.392459, 0.885955, -0.630116, 0.724630, 0.279043, -0.150212, -0.616628, 0.772791, 0.860877, 0.495684, 0.114840, -0.831844, -0.041194, 0.553479, 0.485009, 0.864166, 0.134104, 0.924099, -0.073913, 0.374937, 0.724477, -0.530201, 0.440476, -0.080271, -0.906086, 0.415409, -0.666255, -0.148712, 0.730746, -0.458728, 0.881560, 0.111444, 0.130438, 0.863969, 0.486358, 0.555881, 0.754258, 0.349416, 0.693550, -0.337114, 0.636665, 0.736204, 0.373880, 0.564107, 0.128769, -0.201585, 0.970970, 0.556716, -0.563767, 0.610109, 0.582796, 0.579959, 0.569207, 0.043318, 0.961468, 0.271482, 0.358585, -0.561484, 0.745757, 0.121685, -0.620043, 0.775074, -0.818746, -0.442216, 0.366197, -0.071696, 0.788694, 0.610591, 0.200733, 0.478006, 0.855112, 0.959404, -0.222272, 0.173607, -0.639155, -0.526279, 0.560813, 0.659828, -0.750659, -0.033736}; static float ps107 [321] = { 0.567828, -0.311393, 0.761975, -0.587614, -0.806896, -0.060233, -0.727714, -0.673344, 0.130542, 0.145223, -0.634488, 0.759168, 0.603371, 0.725247, 0.331601, 0.490557, -0.744278, 0.453216, -0.628589, 0.740597, 0.237472, -0.213097, 0.870355, 0.443927, 0.245060, 0.421384, 0.873144, -0.433351, 0.828663, 0.354294, 0.871667, 0.448463, 0.197681, -0.298308, 0.360910, 0.883604, -0.708717, 0.216449, 0.671468, 0.922006, 0.028756, 0.386106, -0.442601, 0.529550, 0.723658, 0.727559, -0.359905, 0.584061, 0.497237, 0.404278, 0.767668, 0.025290, 0.866909, 0.497824, -0.076153, -0.517385, 0.852358, -0.452808, -0.786915, 0.419200, 0.400381, 0.214565, 0.890874, 0.810694, 0.487831, -0.323722, -0.485663, -0.628704, 0.607340, 0.693257, 0.362729, 0.622753, 0.897960, -0.393938, -0.196163, 0.854892, -0.387023, 0.345503, 0.090780, -0.960324, 0.263698, -0.848867, 0.167105, -0.501498, 0.950987, -0.189970, 0.243999, -0.488644, -0.426204, 0.761299, 0.000000, 0.000000, 1.000000, -0.291980, -0.911374, 0.290078, 0.796902, 0.100449, 0.595699, -0.336545, 0.721371, 0.605278, -0.702462, 0.563935, -0.434193, 0.083420, 0.598912, 0.796458, -0.600402, 0.024277, 0.799330, 0.457741, -0.870504, 0.180820, 0.129059, 0.218395, 0.967289, -0.196822, 0.568435, 0.798839, -0.290999, -0.358210, 0.887133, 0.843254, 0.301052, 0.445297, -0.648237, -0.248718, 0.719673, -0.239879, -0.084593, 0.967110, -0.924119, -0.291888, 0.246587, 0.374130, -0.250935, 0.892781, 0.416091, 0.762400, 0.495596, 0.329006, -0.709603, 0.623072, -0.521878, 0.296488, 0.799836, 0.251910, -0.948008, -0.194479, -0.075670, -0.275455, 0.958331, 0.194430, 0.972339, 0.129434, 0.547047, -0.550999, 0.630190, 0.151623, -0.186406, 0.970702, 0.634462, -0.727644, 0.260751, -0.771605, -0.063569, 0.632918, 0.944997, 0.221419, 0.240737, -0.674959, -0.470421, 0.568450, -0.391752, 0.105591, 0.913992, -0.263562, 0.961333, -0.079840, 0.993607, 0.017199, 0.111575, 0.124174, -0.831872, 0.540897, -0.869398, -0.490283, 0.061396, 0.512757, -0.043564, 0.857428, -0.557685, 0.661954, 0.500803, 0.196007, 0.753946, 0.627014, 0.916715, 0.086939, -0.389969, 0.916421, -0.393680, 0.072027, 0.370187, -0.493053, 0.787312, 0.745103, 0.532323, 0.401812, -0.150775, 0.184520, 0.971195, -0.536134, -0.822842, 0.188391, 0.651992, -0.758073, 0.015244, -0.855386, 0.123274, 0.503109, 0.988111, 0.053865, -0.143999, -0.802138, 0.589946, 0.092405, -0.652200, 0.456151, 0.605443, -0.981676, 0.187996, 0.031147, -0.060605, -0.730842, 0.679851, 0.153241, -0.420746, 0.894142, 0.571241, 0.584818, 0.575909, -0.946713, 0.163179, 0.277680, -0.458255, -0.167053, 0.872981, -0.283197, -0.596259, 0.751182, -0.963608, -0.267317, 0.000713, 0.295975, -0.879771, 0.372023, 0.050621, -0.998377, -0.026104, -0.126049, -0.982572, 0.136618, 0.800028, -0.575310, 0.170215, -0.460654, 0.883312, 0.086939, -0.745704, 0.563926, 0.354842, -0.029857, 0.406398, 0.913208, 0.354335, 0.598480, 0.718518, -0.816372, -0.286315, 0.501558, -0.088567, 0.738433, 0.668485, 0.369589, 0.928571, -0.034053, -0.751400, -0.645539, -0.136667, -0.082464, -0.900401, 0.427174, 0.284573, 0.015513, 0.958529, -0.259165, -0.785148, 0.562474, -0.821944, 0.356138, 0.444493, -0.652527, -0.654494, 0.381898, 0.622090, 0.160859, 0.766243, 0.425476, 0.875481, 0.229136, 0.702801, -0.103760, 0.703778, -0.012580, 0.961802, 0.273456, 0.236703, 0.894876, 0.378377}; static float ps108 [324] = { 0.845597, 0.479498, 0.234623, -0.988546, -0.007665, -0.150722, -0.140823, -0.466127, 0.873438, 0.372367, 0.771573, 0.515769, -0.567468, 0.821768, -0.051751, 0.116797, 0.239394, 0.963872, -0.697794, -0.681242, -0.221344, -0.925848, 0.213979, -0.311478, -0.843060, -0.044533, 0.535972, -0.098726, 0.803662, 0.586839, 0.707402, -0.588584, -0.391346, 0.666066, -0.691740, 0.279021, 0.837134, -0.370947, -0.402001, 0.920882, 0.036858, 0.388094, -0.479067, -0.060023, 0.875724, -0.246452, -0.033095, 0.968590, 0.664253, -0.335397, 0.668040, -0.340946, 0.939091, -0.043167, -0.158688, -0.983950, 0.081613, 0.238832, 0.441767, 0.864755, -0.136908, 0.209042, 0.968276, -0.000000, 0.000000, 1.000000, -0.750011, -0.478952, 0.456167, -0.168256, -0.670313, 0.722752, -0.569341, -0.820896, -0.044503, 0.857307, 0.263159, -0.442462, 0.592117, 0.147565, 0.792226, 0.485892, -0.719412, 0.496342, -0.179961, 0.972058, 0.150726, 0.856173, 0.274385, 0.437815, -0.014020, 0.446976, 0.894436, -0.206705, -0.930138, 0.303507, -0.075657, 0.993150, -0.089044, 0.261061, -0.836985, 0.480940, -0.366663, -0.500956, 0.783965, 0.808182, -0.357930, 0.467684, -0.141324, 0.630791, 0.762974, -0.601218, -0.670345, 0.434942, 0.742101, 0.494344, 0.452669, -0.045565, 0.800415, -0.597713, 0.312632, -0.477078, 0.821375, 0.550027, 0.551089, 0.627511, 0.508307, -0.530124, 0.678669, -0.832254, 0.486740, -0.265402, -0.823905, 0.536312, 0.183165, 0.946061, 0.249609, 0.206552, 0.689065, 0.332515, 0.643913, 0.245498, -0.231240, 0.941413, 0.659677, -0.097172, 0.745241, -0.190533, -0.827593, 0.528003, -0.754687, 0.654112, -0.050831, -0.437838, 0.881874, 0.174915, 0.614646, 0.763199, -0.199342, -0.369809, 0.570167, 0.733588, -0.921533, 0.133632, 0.364580, 0.764190, 0.644970, -0.005300, 0.019871, -0.929408, 0.368519, 0.094589, -0.415532, 0.904647, -0.269663, 0.888987, 0.370113, -0.044864, -0.228663, 0.972471, 0.468737, 0.839670, 0.274300, -0.709422, -0.292453, 0.641242, -0.900872, -0.434054, -0.005160, -0.614901, 0.158009, 0.772612, -0.512491, 0.768061, 0.383972, 0.585019, 0.686961, 0.431090, -0.023105, 0.925160, 0.378874, -0.520062, -0.294585, 0.801720, -0.464139, 0.840633, -0.279126, 0.954183, 0.101541, -0.281467, -0.096973, -0.646977, -0.756318, 0.474969, 0.386695, 0.790488, -0.786614, 0.181207, 0.590256, -0.892587, 0.449037, -0.040675, -0.297508, -0.270501, 0.915597, 0.068192, 0.986008, 0.152111, -0.552099, 0.600616, 0.578314, 0.072420, -0.626229, 0.776268, 0.292205, -0.681187, 0.671268, -0.389199, 0.176319, 0.904122, -0.325172, -0.940109, -0.102261, 0.992364, -0.064819, -0.104938, 0.331601, 0.621303, 0.709946, 0.236032, -0.935729, 0.262106, 0.672913, -0.556929, 0.486845, 0.457617, -0.051838, 0.887637, -0.683048, -0.067973, 0.727203, -0.260797, 0.400959, 0.878190, 0.231719, 0.001977, 0.972781, -0.969171, 0.232479, -0.081613, 0.781745, 0.102709, 0.615082, -0.334290, 0.752663, 0.567228, 0.228568, 0.910573, 0.344403, -0.396699, -0.691055, 0.604212, 0.981319, 0.188610, -0.037940, -0.905947, -0.359528, 0.223607, 0.476931, -0.291719, 0.829118, 0.823328, -0.130846, 0.552277, 0.783171, 0.575738, -0.234880, 0.418775, 0.823829, -0.382013, 0.140942, 0.809731, 0.569623, -0.408921, -0.902348, 0.136206, -0.655973, 0.734335, 0.174502, -0.687641, 0.399876, 0.606011, -0.572378, -0.508766, 0.643071, 0.936384, -0.303995, -0.175422, -0.507932, 0.373552, 0.776186, 0.366238, 0.202420, 0.908238}; static float ps109 [327] = { 0.610026, -0.233011, 0.757346, 0.731705, 0.574946, 0.366122, -0.008585, 0.044474, 0.998974, -0.105568, 0.938088, 0.329919, -0.029742, -0.903237, 0.428110, -0.371585, -0.662425, 0.650475, 0.077914, 0.877016, 0.474102, 0.215616, 0.943187, -0.252803, -0.727064, 0.127484, 0.674630, 0.150699, 0.957837, 0.244617, 0.460917, 0.413076, 0.785445, -0.778696, 0.517881, 0.354162, -0.009458, 0.984039, -0.177701, -0.193713, -0.583244, 0.788861, -0.904694, 0.302605, 0.299931, 0.463362, 0.187468, 0.866113, 0.595572, 0.767030, 0.238661, 0.906877, -0.059250, 0.417209, -0.362540, 0.848445, 0.385625, 0.454558, -0.890716, -0.001114, -0.607300, 0.314958, 0.729375, -0.782908, 0.332914, 0.525569, -0.605596, -0.511622, 0.609506, -0.776550, 0.523142, -0.351130, 0.210343, -0.086800, 0.973767, -0.400634, -0.903335, -0.153228, 0.715899, -0.399026, 0.572947, -0.011234, -0.465862, 0.884786, 0.006121, 0.529310, 0.848407, -0.269233, -0.827376, 0.492912, -0.730226, 0.664681, 0.158017, 0.007173, 0.295157, 0.955422, 0.235493, -0.967528, 0.091834, -0.535472, -0.699099, 0.473847, 0.881414, 0.389322, -0.267466, -0.209150, 0.644668, 0.735296, 0.262932, 0.766005, 0.586603, 0.784889, 0.607035, 0.124330, 0.023091, 0.730384, 0.682647, 0.870019, -0.299867, 0.391340, -0.876313, 0.099638, 0.471325, -0.648234, 0.759384, -0.055935, -0.444783, -0.208271, 0.871086, -0.174113, 0.817985, 0.548256, 0.163971, -0.315119, 0.934780, 0.780856, -0.153529, 0.605551, -0.970673, -0.194577, 0.141186, -0.624989, -0.056532, 0.778584, 0.643526, 0.491435, 0.586827, -0.972648, 0.117826, -0.200184, -0.428687, -0.451346, 0.782633, 0.804635, -0.583664, 0.109078, 0.163355, -0.808080, 0.565970, -0.414448, 0.296274, 0.860497, 0.444110, -0.050794, 0.894531, -0.428041, 0.517089, 0.741215, -0.794624, -0.113345, 0.596427, -0.911959, -0.152467, 0.380900, 0.656949, 0.269158, 0.704253, 0.233636, 0.149604, 0.960746, -0.237129, -0.345888, 0.907817, -0.283890, 0.944115, 0.167493, 0.805510, 0.107759, 0.582702, 0.806305, 0.341775, 0.482765, -0.464623, 0.070697, 0.882682, 0.227686, 0.591803, 0.773258, -0.735197, -0.559290, 0.382988, -0.635103, -0.295033, 0.713862, -0.219185, 0.174167, 0.960012, -0.042973, 0.995710, 0.081951, -0.915236, -0.402915, 0.001524, -0.624532, 0.522689, 0.580307, 0.197724, 0.980255, -0.002328, 0.401130, -0.289186, 0.869175, 0.410351, -0.787854, 0.459236, 0.923661, 0.163297, 0.346675, 0.800004, 0.587082, -0.123811, -0.999865, 0.014452, 0.007843, -0.210206, 0.428355, 0.878821, -0.413150, 0.702815, 0.579101, -0.538356, 0.815993, 0.210543, 0.631532, -0.715356, 0.299054, -0.967147, 0.060205, 0.246987, 0.881673, 0.402261, 0.246655, 0.515106, -0.470042, 0.716747, 0.531046, 0.712562, 0.458525, 0.090781, -0.652837, 0.752039, 0.442101, 0.612880, 0.654924, 0.355594, -0.664709, 0.657050, 0.647258, 0.019856, 0.762012, -0.975313, -0.183368, -0.123051, -0.092754, -0.761754, 0.641192, 0.589300, -0.615291, 0.523587, 0.441451, -0.865652, 0.236150, 0.272952, -0.504702, 0.819007, -0.635439, -0.736610, 0.231566, 0.343859, 0.859048, 0.379206, 0.209447, -0.916189, 0.341656, -0.431239, -0.846234, 0.312922, 0.238483, 0.379724, 0.893832, -0.915893, 0.369008, -0.158027, -0.431515, -0.898494, 0.080646, -0.632172, -0.774809, -0.005381, -0.050035, -0.199852, 0.978548, -0.261095, -0.070861, 0.962709, -0.874816, 0.472996, 0.104749, 0.788310, 0.347915, -0.507467, -0.966270, 0.251969, 0.053231, -0.598588, 0.690880, 0.405434}; static float ps110 [330] = { 0.098197, -0.720142, 0.686843, 0.676501, 0.724281, 0.133282, -0.546768, 0.741721, 0.388452, -0.226819, 0.616965, 0.753597, -0.893995, 0.378121, 0.240410, 0.713458, 0.497591, 0.493336, -0.439062, 0.254572, 0.861637, 0.037663, -0.493429, 0.868970, 0.761574, 0.263801, 0.591959, -0.422529, -0.016964, 0.906191, 0.225525, 0.117554, 0.967119, 0.642823, -0.136393, 0.753774, -0.247430, 0.380401, 0.891108, -0.609915, 0.563644, 0.557054, 0.168797, 0.566335, 0.806705, -0.714497, -0.690841, 0.110601, 0.368177, -0.703182, 0.608260, 0.938196, 0.318093, -0.136400, -0.395107, -0.289964, 0.871672, -0.440631, 0.495782, 0.748361, 0.630646, 0.126672, 0.765663, 0.238424, -0.121670, 0.963509, -0.788697, 0.189565, 0.584827, 0.000000, 0.000000, 1.000000, 0.204172, -0.846961, 0.490888, -0.128203, 0.989060, -0.072974, 0.796331, 0.551168, 0.249138, -0.106743, -0.986930, 0.120726, -0.200238, -0.906126, 0.372612, -0.230650, 0.125265, 0.964940, -0.649793, 0.745791, 0.146850, -0.913132, 0.169357, 0.370820, 0.378985, 0.803161, 0.459676, -0.568589, -0.411039, 0.712568, -0.041436, 0.485172, 0.873437, -0.322342, 0.863397, 0.388125, -0.752151, -0.266326, 0.602776, -0.720105, -0.477841, 0.503107, 0.452457, -0.004005, 0.891777, 0.394844, 0.486812, 0.779174, 0.460038, -0.793793, 0.397816, -0.057122, 0.927627, 0.369114, -0.607100, 0.113747, 0.786443, 0.516177, 0.616838, 0.594200, -0.648694, -0.662206, 0.375072, -0.360895, 0.932302, -0.023838, 0.247577, -0.355595, 0.901253, 0.511941, 0.858950, 0.011015, 0.455493, 0.856539, 0.242625, 0.788098, -0.010118, 0.615466, 0.609900, 0.698415, 0.374483, 0.254457, -0.570435, 0.780933, 0.203654, 0.350301, 0.914229, 0.658534, -0.366403, 0.657329, 0.663751, -0.674280, 0.323697, -0.526341, 0.836846, -0.150511, -0.183232, -0.398537, 0.898663, 0.034139, 0.990590, 0.132539, 0.848643, 0.528952, 0.003844, -0.935014, 0.354226, -0.016508, -0.333773, -0.927084, 0.170617, -0.291482, 0.918719, -0.266446, 0.468050, -0.477289, 0.743723, -0.416340, -0.800974, 0.430234, 0.000806, 0.707966, 0.706246, 0.768876, -0.469462, 0.434091, -0.745043, -0.033709, 0.666164, -0.055020, -0.834935, 0.547591, -0.701293, 0.708790, -0.076188, 0.594840, 0.385576, 0.705334, -0.820852, -0.509865, 0.257373, -0.277151, -0.740465, 0.612290, 0.995189, 0.096005, -0.019523, 0.110927, 0.841773, 0.528311, 0.925884, -0.099970, 0.364341, -0.631257, 0.351403, 0.691398, -0.740641, 0.588735, 0.323794, 0.905373, -0.322356, 0.276380, 0.969552, 0.113825, 0.216825, -0.017932, 0.248702, 0.968414, -0.985030, 0.127262, -0.116276, -0.512568, -0.623983, 0.589847, 0.460016, -0.253124, 0.851066, 0.867998, 0.348255, 0.353975, 0.204174, 0.926866, 0.315013, -0.538403, -0.812240, 0.224472, -0.398001, 0.702790, 0.589645, -0.123840, -0.636495, 0.761274, -0.964224, -0.078814, 0.253102, 0.015906, -0.250917, 0.967878, -0.825920, 0.557369, 0.084831, -0.354492, -0.533863, 0.767676, -0.935508, -0.334193, -0.114631, 0.887516, 0.124044, 0.443766, 0.433471, 0.246932, 0.866676, 0.278856, 0.957152, 0.078098, -0.786608, 0.400325, 0.470094, -0.875886, -0.297216, 0.380113, -0.211426, -0.138826, 0.967485, -0.043858, 0.945522, -0.322589, 0.584243, -0.597399, 0.549340, -0.879610, -0.058220, 0.472120, -0.211546, 0.960778, 0.179316, -0.979793, 0.149452, 0.132930, 0.814215, -0.240018, 0.528626, -0.585827, -0.168086, 0.792814, 0.282379, 0.704763, 0.650823, -0.165971, 0.807846, 0.565543, -0.829343, 0.528678, -0.180803, -0.460752, 0.869919, 0.175923}; static float ps111 [333] = { 0.504365, 0.022619, 0.863194, 0.392879, -0.918347, 0.047789, 0.875803, -0.482644, 0.004820, 0.796504, 0.217017, 0.564344, 0.050794, 0.887623, 0.457760, -0.939385, 0.097776, 0.328627, -0.697691, 0.384488, 0.604480, -0.290807, -0.941080, 0.172626, 0.259798, 0.004237, 0.965654, 0.579708, -0.813041, -0.053871, -0.000000, 0.000000, 1.000000, 0.723288, 0.517021, -0.457760, 0.682011, -0.642330, 0.349675, -0.965557, -0.123855, 0.228824, -0.214359, -0.429011, 0.877496, -0.410993, 0.882454, 0.228824, -0.391889, 0.786721, 0.476962, 0.376407, -0.207433, 0.902934, -0.555447, 0.606668, 0.568711, 0.469873, -0.752513, 0.461458, -0.113525, -0.217167, 0.969511, -0.276115, 0.431892, 0.858621, -0.512604, 0.002761, 0.858621, 0.135176, -0.221902, 0.965654, 0.779808, -0.429742, 0.455215, -0.168502, 0.793377, 0.584945, 0.308638, 0.626748, 0.715493, -0.268732, -0.913322, -0.305984, -0.272614, -0.765381, 0.582986, -0.852037, 0.469547, 0.231426, 0.098882, -0.908743, 0.405472, 0.907301, -0.233519, 0.349675, 0.580983, -0.576670, 0.574378, 0.721937, 0.022057, 0.691607, 0.293259, 0.797779, 0.526828, 0.996985, -0.055854, -0.053871, 0.733873, -0.670911, 0.106348, -0.723716, -0.035363, 0.689191, -0.599452, -0.216792, 0.770493, 0.335004, -0.886453, 0.319334, -0.501708, 0.423893, 0.754058, -0.194355, 0.910365, 0.365324, 0.240876, 0.968596, 0.061643, -0.149802, 0.214786, 0.965104, 0.887150, 0.004674, 0.461458, 0.665668, 0.618461, 0.417603, -0.517831, -0.674020, 0.526828, -0.839987, -0.542575, 0.005950, -0.261594, 0.011929, 0.965104, -0.809554, 0.145567, 0.568711, 0.241941, -0.789291, 0.564344, -0.365023, -0.595674, 0.715493, 0.959163, -0.262100, 0.106348, 0.385956, 0.221498, 0.895531, 0.473376, 0.439646, 0.763300, -0.058865, -0.973041, 0.222995, -0.760735, -0.281286, 0.584945, -0.210622, 0.970322, 0.118798, -0.735043, 0.661570, 0.148447, -0.402437, 0.221778, 0.888177, 0.918574, 0.364446, 0.152974, 0.027132, 0.970350, 0.240177, 0.932825, 0.340183, -0.118798, -0.029476, 0.406863, 0.913013, 0.248207, 0.410358, 0.877496, -0.599732, -0.466330, 0.650276, 0.850977, -0.468963, 0.236456, 0.018879, -0.444598, 0.895531, 0.611671, 0.233672, 0.755815, -0.010069, -0.999932, -0.005950, 0.874419, 0.088875, -0.476962, 0.663626, -0.365716, 0.652574, 0.797832, -0.183178, 0.574378, -0.690221, -0.720968, 0.061643, 0.821085, 0.401762, 0.405472, -0.854027, 0.315901, 0.413333, 0.485352, 0.793945, 0.366175, -0.012367, -0.796443, 0.604587, -0.439540, -0.389486, 0.809386, -0.873448, -0.321912, 0.365324, 0.791190, 0.569466, 0.222995, 0.928352, 0.190234, 0.319334, -0.628613, -0.714996, 0.305984, 0.073930, 0.756092, 0.650276, -0.504266, -0.855413, 0.118256, 0.453857, 0.883193, 0.118256, 0.366938, -0.622122, 0.691607, 0.976682, -0.033353, 0.212083, -0.136886, 0.622578, 0.770493, -0.359715, -0.192385, 0.913013, 0.501468, 0.639263, 0.582986, 0.468678, -0.413025, 0.780866, 0.549842, -0.807895, 0.212083, -0.666725, -0.435834, -0.604587, 0.122964, 0.211965, 0.969511, 0.723205, -0.553291, -0.413333, -0.626330, 0.197754, 0.754058, -0.167328, -0.893089, 0.417603, 0.986228, 0.158339, 0.047789, 0.129141, -0.641924, 0.755815, 0.951892, -0.268078, -0.148447, 0.250258, -0.438482, 0.863194, 0.805864, 0.541201, -0.240177, -0.411993, -0.834373, 0.366175, 0.094523, 0.579621, 0.809386, -0.584386, 0.741955, 0.328627, -0.182499, 0.971233, -0.152974, 0.599501, -0.175635, 0.780866, 0.640291, 0.748484, 0.172626, -0.356639, 0.630733, 0.689191, -0.118857, -0.635017, 0.763300}; static float ps112 [336] = { -0.709460, 0.012066, 0.704643, 0.135896, -0.620790, 0.772109, 0.825207, 0.533834, 0.184540, -0.795102, -0.176393, 0.580257, -0.950507, 0.273572, 0.147293, -0.262830, 0.751240, 0.605442, 0.257674, -0.011975, 0.966158, 0.510212, -0.712197, 0.482140, -0.724884, 0.672759, 0.148116, 0.912894, 0.315280, 0.259275, 0.514605, 0.381285, 0.767986, 0.727951, -0.521997, 0.444529, -0.997048, 0.076726, 0.002714, 0.449620, -0.851201, 0.270737, -0.217741, 0.946721, -0.237292, -0.417842, 0.811115, 0.409268, -0.242571, -0.036221, 0.969457, -0.336031, 0.177487, 0.924977, -0.583067, -0.725193, 0.366235, 0.900095, 0.142227, 0.411825, -0.807746, -0.392492, 0.439883, -0.866316, 0.049072, 0.497080, -0.879356, 0.274817, 0.388856, -0.884042, 0.466810, 0.023645, -0.674494, -0.390662, 0.626452, 0.689375, -0.103706, 0.716943, 0.094874, 0.913710, 0.395136, -0.170032, 0.884720, 0.434004, 0.757929, -0.647064, 0.082770, 0.031531, -0.913632, 0.405317, -0.309707, 0.927253, 0.210436, 0.559081, -0.303127, 0.771714, 0.319817, 0.860955, 0.395569, 0.611298, 0.532161, 0.585764, -0.194679, 0.425594, 0.883725, 0.653011, -0.698581, 0.292509, 0.785318, 0.096932, 0.611457, 0.101024, -0.213382, 0.971732, -0.439881, -0.867503, 0.232259, 0.738127, -0.320752, 0.593537, -0.818498, -0.570611, 0.066813, 0.359483, -0.237471, 0.902430, 0.335557, -0.687062, 0.644475, -0.213954, -0.916537, 0.337910, -0.354999, -0.646926, 0.674880, -0.032945, -0.984213, 0.173895, -0.686507, -0.718889, -0.109117, 0.200190, -0.415161, 0.887449, 0.391924, 0.191931, 0.899754, -0.981789, -0.149744, 0.116904, 0.679802, 0.638024, 0.361656, 0.285601, 0.418395, 0.862193, -0.584277, 0.809504, -0.057657, 0.150958, 0.215303, 0.964809, 0.387818, 0.591977, 0.706513, -0.584267, 0.195603, 0.787636, 0.933704, 0.357394, 0.021584, -0.032436, -0.459797, 0.887431, 0.522246, 0.811248, 0.262936, -0.900664, -0.377421, 0.215309, -0.378849, 0.924945, -0.030832, -0.487103, -0.015283, 0.873211, -0.381823, -0.244865, 0.891208, -0.983076, -0.120570, -0.137928, 0.797384, 0.423718, 0.429700, -0.299483, -0.937578, -0.176797, -0.348567, 0.576802, 0.738783, -0.425544, 0.370335, 0.825690, -0.511918, 0.643037, 0.569599, 0.875714, -0.301378, 0.377222, -0.382666, -0.788062, 0.482208, -0.832926, 0.486609, 0.263525, 0.843321, -0.484542, 0.232443, 0.962956, -0.057594, -0.263435, 0.957836, -0.073358, 0.277792, -0.263828, -0.468205, 0.843314, -0.734941, 0.476868, 0.482140, -0.068544, 0.969301, 0.236131, 0.480552, 0.716700, 0.505381, 0.496258, -0.047006, 0.866902, 0.088225, -0.788417, 0.608781, -0.651134, -0.747779, 0.129810, -0.099395, 0.216294, 0.971256, -0.597272, 0.437778, 0.672024, 0.917144, 0.168286, -0.361285, 0.000000, 0.000000, 1.000000, 0.719231, 0.316362, 0.618564, -0.638906, 0.674764, 0.369449, 0.607840, 0.148753, 0.780002, -0.004759, 0.796211, 0.605000, 0.143661, 0.620832, 0.770668, -0.580778, -0.594138, 0.556503, 0.855121, -0.105425, 0.507596, 0.043473, 0.433634, 0.900040, -0.140245, -0.252043, 0.957500, -0.602597, -0.205050, 0.771253, -0.271874, -0.958399, 0.086923, 0.393309, -0.490606, 0.777569, -0.098398, 0.631087, 0.769446, 0.097330, 0.992072, 0.079495, -0.481928, -0.442770, 0.756109, -0.755658, 0.248923, 0.605821, 0.575063, -0.523828, 0.628417, -0.148006, 0.988986, -0.000279, 0.488766, 0.872162, 0.020993, 0.281287, -0.843873, 0.456899, -0.113878, -0.658130, 0.744242, -0.531089, 0.827237, 0.183368, 0.952682, -0.275387, 0.128681, -0.154783, -0.812497, 0.562042, 0.233712, 0.766269, 0.598506, -0.754443, -0.577340, 0.312240}; static float ps113 [339] = { 0.271998, 0.595449, 0.755948, -0.964973, 0.260717, 0.029227, -0.666514, 0.565136, 0.486191, -0.135317, 0.473109, 0.870550, 0.611103, -0.206851, 0.764046, -0.258454, -0.886484, 0.383859, -0.530809, 0.754344, 0.386272, -0.138988, 0.921773, 0.361964, -0.936040, 0.217374, 0.276726, -0.727504, 0.631469, 0.268299, 0.898124, 0.393519, 0.196255, -0.357144, 0.486170, 0.797551, 0.256111, 0.957190, 0.134884, -0.260713, -0.955833, 0.135689, 0.836090, -0.299628, 0.459540, 0.840017, 0.121763, 0.528721, 0.184273, -0.901763, 0.390983, 0.474230, -0.428318, 0.769187, -0.502703, -0.380199, 0.776362, 0.573362, 0.556648, -0.601165, -0.214685, 0.672771, 0.708018, -0.368511, 0.893189, 0.257705, -0.800010, -0.598247, -0.045656, -0.931619, -0.021257, 0.362815, -0.822197, 0.394097, 0.410706, -0.574482, 0.805650, 0.144565, -0.090256, 0.243916, 0.965587, 0.784964, -0.123227, 0.607163, -0.605783, -0.147378, 0.781861, -0.055156, 0.814225, 0.577924, -0.462894, -0.844781, 0.268466, 0.334178, 0.389840, 0.858108, -0.640599, -0.759683, 0.111865, -0.746753, 0.664302, 0.032598, 0.113129, -0.233211, 0.965823, 0.710555, 0.313604, 0.629892, -0.420598, -0.746828, 0.515116, -0.678481, 0.090677, 0.729000, 0.918393, -0.070346, 0.389365, -0.039138, -0.977403, -0.207728, 0.943053, -0.253349, 0.215559, -0.443013, 0.661663, 0.604932, -0.385314, -0.188250, 0.903380, 0.989424, -0.034976, 0.140771, 0.690086, 0.062903, 0.720989, 0.438502, 0.680451, 0.587114, 0.347895, -0.781367, 0.518108, -0.644078, -0.752358, -0.138277, 0.098843, 0.442201, 0.891453, 0.393404, -0.919365, 0.000525, 0.140516, 0.210155, 0.967518, 0.550861, -0.745125, 0.375952, -0.186131, 0.971760, -0.145047, -0.471353, 0.042292, 0.880930, 0.877138, -0.477485, 0.051347, -0.843009, 0.457858, -0.282317, -0.745364, -0.488253, 0.453918, -0.274112, -0.409366, 0.870219, 0.023151, 0.646971, 0.762163, -0.036287, -0.872195, 0.487810, -0.137384, -0.610431, 0.780064, -0.369296, -0.592944, 0.715568, -0.243377, 0.027602, 0.969539, 0.247079, -0.038876, 0.968215, -0.184668, 0.976977, 0.106833, -0.963511, -0.187714, 0.190813, -0.761535, -0.577318, -0.294565, -0.876640, -0.392088, 0.278873, 0.523729, -0.608539, 0.596144, 0.701653, -0.553004, 0.449299, 0.389938, -0.883034, 0.261150, 0.317319, -0.624202, 0.713919, -0.789704, -0.077974, 0.608513, -0.038814, -0.963438, 0.265106, 0.120149, 0.904171, 0.409926, -0.700234, -0.324412, 0.635947, 0.677066, -0.387846, 0.625426, -0.722875, 0.309966, 0.617554, -0.191599, -0.763015, 0.617331, 0.829256, 0.362007, 0.425777, 0.662659, 0.536013, 0.523042, 0.340488, 0.840252, 0.421953, 0.938854, 0.164229, 0.302626, 0.365864, 0.160933, 0.916648, 0.381672, -0.232540, 0.894568, 0.551630, 0.251087, 0.795399, -0.449437, -0.864922, -0.223422, 0.239394, -0.428493, 0.871254, 0.513498, 0.482789, 0.709391, 0.506369, -0.019796, 0.862090, 0.188620, 0.768839, 0.610990, 0.090177, -0.606074, 0.790280, -0.145211, -0.204272, 0.968084, -0.912600, -0.406465, 0.044130, -0.993533, 0.034934, 0.108038, -0.857893, -0.238446, 0.455151, 0.112652, -0.769934, 0.628101, -0.458412, -0.888560, 0.017884, -0.848476, 0.143974, 0.509274, -0.000000, 0.000000, 1.000000, -0.777124, -0.594814, 0.205608, 0.576362, 0.720475, 0.385646, -0.042384, -0.998689, 0.028698, -0.563356, 0.471171, 0.678695, -0.618558, -0.689887, 0.376088, -0.299969, 0.813839, 0.497680, -0.872596, 0.452268, 0.184472, 0.723981, -0.656131, 0.212938, 0.576257, -0.809690, 0.111038, -0.316946, 0.263845, 0.911006, -0.529810, 0.268956, 0.804341, -0.027867, -0.418289, 0.907887, 0.980449, 0.188553, 0.056282}; static float ps114 [342] = { -0.712121, 0.364658, 0.599923, -0.499167, -0.300794, 0.812622, -0.315110, -0.686014, 0.655813, 0.219962, 0.192997, 0.956226, -0.353049, 0.669347, 0.653705, -0.461401, 0.133972, 0.877018, -0.082413, -0.976536, 0.198963, 0.534392, -0.740339, 0.407827, -0.515086, 0.342274, 0.785834, 0.927795, -0.356741, 0.109232, 0.498229, -0.145108, 0.854817, -0.630822, -0.773134, 0.065786, -0.383145, -0.080889, 0.920140, 0.330786, -0.325713, 0.885715, -0.074662, 0.475961, 0.876291, -0.300541, -0.505831, 0.808585, -0.079394, -0.611185, 0.787496, -0.684476, 0.574834, 0.448395, 0.950833, -0.164458, 0.262432, 0.324302, 0.922222, 0.210559, -0.882470, -0.458462, -0.105161, 0.352437, -0.550280, 0.756954, -0.070660, -0.400817, 0.913429, 0.113101, -0.244191, 0.963109, -0.990446, -0.029119, -0.134791, 0.447355, -0.889380, -0.094218, -0.788716, -0.606380, 0.101149, 0.059942, -0.998141, 0.010985, 0.143831, -0.490720, 0.859364, -0.523670, -0.685054, 0.506429, 0.702115, -0.563426, 0.435414, -0.512664, -0.512236, 0.689050, -0.091151, -0.902010, 0.421983, -0.202861, 0.078305, 0.976072, 0.854452, -0.350386, 0.383590, -0.738358, -0.659253, -0.142171, -0.823227, -0.453530, 0.341479, 0.550180, 0.815248, 0.180754, 0.170535, 0.421760, 0.890526, -0.317129, 0.494836, 0.809053, 0.922768, 0.059125, 0.380792, 0.492939, -0.730481, -0.472661, 0.542577, -0.574625, 0.612712, 0.343806, -0.870015, 0.353370, 0.539003, -0.369526, 0.756919, 0.692631, 0.486851, 0.532201, 0.985209, -0.170427, -0.017811, 0.689603, 0.491027, -0.532297, -0.320735, -0.826065, 0.463407, 0.021151, 0.810170, 0.585813, 0.772658, -0.591752, -0.229849, -0.286960, 0.953938, -0.087506, -0.436542, -0.899275, 0.027103, 0.082372, -0.923206, -0.375374, 0.667151, 0.273553, 0.692877, 0.138148, -0.847936, 0.511782, -0.513594, -0.810547, 0.281486, 0.225630, -0.819821, -0.526294, -0.833210, -0.255479, 0.490399, 0.535024, 0.460541, 0.708273, 0.849425, -0.146588, 0.506941, 0.816318, -0.577602, -0.001097, -0.684135, -0.285209, 0.671278, -0.066400, -0.977162, -0.201856, 0.351252, -0.736691, 0.577848, 0.638036, 0.675357, 0.369869, 0.438819, 0.103292, 0.892619, -0.545741, 0.532519, 0.646986, 0.263609, 0.754145, 0.601477, -0.905979, -0.404419, 0.125091, 0.491786, 0.656825, 0.571601, 0.281448, -0.071958, 0.956875, -0.023027, 0.258142, 0.965832, 0.360233, -0.873188, -0.328292, -0.113943, -0.146613, 0.982610, 0.717577, -0.371386, 0.589198, -0.088308, -0.779089, 0.620663, -0.839266, 0.389226, 0.379651, -0.781035, -0.048278, 0.622618, 0.593652, -0.761053, -0.261486, 0.628128, 0.063458, 0.775518, 0.420378, 0.812909, 0.403065, -0.602122, -0.071077, 0.795234, 0.101927, 0.635956, 0.764965, -0.272344, 0.294839, 0.915914, -0.308938, -0.920521, 0.239163, 0.211268, -0.963075, -0.166891, 0.055130, 0.020550, 0.998268, -0.837148, 0.176155, 0.517834, -0.285514, -0.294798, 0.911908, 0.492823, -0.856022, 0.156050, 0.326828, 0.563825, 0.758476, 0.652239, -0.757358, -0.031523, 0.809859, 0.486990, 0.327060, 0.208786, 0.977949, 0.004855, -0.672980, 0.154631, 0.723317, -0.989149, -0.025749, 0.144641, -0.974770, -0.222991, -0.009924, 0.797634, 0.071442, 0.598896, -0.913701, -0.022548, 0.405761, 0.142647, -0.692796, 0.706884, 0.413460, 0.326936, 0.849802, 0.695356, -0.159054, 0.700844, 0.910344, -0.389335, -0.140330, 0.827992, 0.283416, 0.483843, -0.937189, -0.220477, 0.270309, -0.943019, 0.185412, 0.276291, -0.128038, 0.671096, 0.730231, 0.818357, -0.527077, 0.229087, -0.176190, -0.893944, -0.412093, -0.686848, -0.652858, 0.319400, 0.136437, -0.949899, 0.281204, 0.930116, 0.264533, 0.254766, -0.672570, 0.710596, -0.206649}; static float ps115 [345] = { 0.609985, 0.369208, 0.701144, 0.756728, -0.245878, 0.605728, 0.219885, -0.130739, 0.966725, -0.245924, -0.763118, 0.597639, 0.649097, 0.739264, 0.179337, 0.594527, -0.374241, 0.711675, -0.011158, -0.245463, 0.969342, -0.490605, -0.871359, -0.006252, -0.566700, 0.582990, -0.582215, 0.425137, -0.252778, 0.869116, -0.727134, 0.676537, -0.116509, -0.791251, 0.186297, 0.582422, 0.951636, -0.281658, 0.122710, -0.578415, 0.815607, 0.014866, -0.230861, 0.383306, 0.894304, 0.360145, -0.681372, 0.637203, -0.904747, 0.221516, 0.363818, -0.811180, -0.252102, 0.527666, -0.676421, -0.734495, 0.054522, 0.921022, 0.374787, 0.106085, -0.067546, -0.674201, 0.735453, -0.821010, -0.570144, -0.029638, -0.471304, -0.438309, 0.765348, -0.959195, 0.253890, 0.124436, -0.461685, -0.638366, 0.615902, -0.424034, -0.226081, 0.876974, 0.768862, 0.021052, 0.639068, 0.037345, 0.700269, 0.712902, -0.407579, -0.805571, 0.430041, -0.658019, -0.477985, 0.581844, 0.215799, 0.342500, 0.914398, -0.236040, -0.360315, 0.902474, 0.135602, -0.751911, 0.645169, -0.183418, 0.611895, 0.769378, 0.213438, 0.927007, 0.308385, -0.194933, -0.911617, 0.361877, -0.116737, 0.808554, 0.576726, 0.998825, -0.046918, 0.012110, -0.410697, 0.886471, 0.213300, -0.033036, -0.476161, 0.878737, -0.619136, 0.377355, 0.688675, -0.568391, 0.582152, 0.581405, 0.617122, -0.125083, 0.776862, 0.436295, -0.007315, 0.899774, 0.520097, 0.600099, 0.607766, -0.438772, 0.277333, 0.854731, -0.187636, 0.966807, 0.173429, 0.299752, 0.695869, 0.652621, -0.045062, -0.991282, -0.123811, 0.444776, 0.861732, 0.244113, -0.979371, -0.189926, 0.069003, 0.597309, 0.692761, 0.404110, 0.617606, 0.133443, 0.775084, -0.761800, -0.605349, 0.230680, -0.626772, 0.154477, 0.763737, 0.715586, 0.487401, 0.500376, -0.860665, 0.440522, 0.255337, -0.924922, -0.222300, 0.308385, -0.114991, -0.985542, 0.124436, 0.869234, 0.352400, 0.346766, 0.457591, -0.774913, 0.436027, 0.229085, -0.858683, 0.458458, 0.430802, 0.239657, 0.870043, 0.053749, -0.951343, 0.303411, 0.126312, -0.989588, 0.069003, -0.707199, 0.595766, 0.380699, -0.027866, 0.931053, 0.363818, 0.195027, 0.555325, 0.808442, 0.202894, -0.362397, 0.909671, 0.412446, 0.469130, 0.780900, -0.033322, -0.854283, 0.518739, 0.174121, -0.574339, 0.799886, 0.382344, 0.800186, 0.462077, 0.974484, -0.016339, -0.223859, -0.409652, 0.506268, 0.758867, 0.882614, -0.470097, 0.000559, -0.899374, -0.411012, 0.148981, -0.266015, 0.873650, 0.407396, 0.965708, -0.074947, 0.248579, 0.901752, 0.128849, 0.412603, 0.830351, -0.502940, 0.239934, -0.000000, -0.000000, 1.000000, 0.783322, 0.559488, 0.270888, 0.304148, -0.919985, 0.247228, -0.411899, 0.040850, 0.910313, -0.770001, 0.403139, 0.494548, 0.881974, -0.306215, 0.358264, -0.000168, 0.246883, 0.969045, -0.274146, -0.568892, 0.775375, -0.481910, 0.758227, 0.439152, -0.624579, -0.653874, 0.427026, -0.015246, 0.476301, 0.879150, -0.663553, 0.657233, -0.357412, -0.608663, 0.756041, 0.240689, -0.363260, 0.931470, -0.020142, -0.894394, -0.015175, 0.447022, -0.552592, -0.796644, 0.244950, 0.397934, -0.483387, 0.779735, 0.766409, -0.630972, -0.120381, 0.528484, -0.821265, 0.215008, -0.275182, -0.959047, -0.067110, -0.338753, 0.708455, 0.619143, -0.971565, -0.156741, -0.177466, 0.877624, -0.098489, 0.469124, 0.743776, -0.458682, 0.486218, 0.135137, 0.839035, 0.527028, 0.762336, 0.045974, -0.645547, -0.347531, -0.919553, 0.183426, 0.224296, 0.108398, 0.968474, -0.587654, -0.073921, 0.805728, -0.219982, -0.111048, 0.969163, -0.808408, -0.441745, 0.389022, -0.212961, 0.147369, 0.965883, 0.776308, 0.256960, 0.575602, -0.646549, -0.280587, 0.709398}; static float ps116 [348] = { 0.062688, -0.684546, 0.726270, -0.008877, -0.837344, 0.546604, 0.550973, 0.572054, 0.607605, -0.778273, -0.053162, 0.625671, -0.316153, 0.911886, 0.261747, -0.087479, -0.950560, 0.297966, -0.066940, 0.827807, 0.557005, 0.543815, -0.497510, 0.675833, 0.361620, 0.869010, 0.337717, -0.302434, 0.822746, 0.481272, 0.398456, -0.833739, 0.382246, 0.569101, 0.717933, 0.400869, -0.088821, 0.932022, 0.351349, 0.153827, 0.873978, 0.460977, 0.945440, 0.325648, -0.009884, 0.380769, 0.745260, 0.547359, 0.533225, -0.021244, 0.845706, 0.586817, -0.273532, 0.762119, 0.832140, -0.402491, 0.381503, -0.311783, 0.949620, 0.031828, 0.727165, 0.649706, 0.221615, -0.051814, -0.317930, 0.946697, -0.501201, -0.363270, 0.785387, -0.599092, 0.457069, 0.657401, 0.130198, 0.962452, 0.238191, 0.691567, 0.369162, 0.620850, 0.280172, -0.020585, 0.959729, 0.363426, -0.428842, 0.827052, 0.778999, -0.585537, 0.224292, -0.503275, 0.854475, -0.128793, -0.391850, 0.498731, 0.773124, 0.115349, 0.537363, 0.835425, 0.264661, 0.369301, 0.890826, 0.731223, -0.342227, 0.590079, 0.846320, 0.309216, 0.433737, 0.829716, -0.557221, -0.032810, -0.408585, -0.711456, 0.571742, 0.785859, 0.130722, 0.604431, 0.141617, 0.167556, 0.975638, -0.607737, 0.730732, -0.310944, 0.041244, -0.072629, 0.996506, 0.292686, -0.935053, 0.200026, -0.680706, 0.226037, 0.696812, 0.089651, -0.988750, -0.119730, 0.478388, -0.687208, 0.546708, 0.173773, 0.733446, 0.657161, 0.306570, -0.624901, 0.717993, -0.159560, 0.508440, 0.846185, 0.823673, -0.494477, -0.277589, -0.772003, -0.593948, 0.226353, -0.689866, -0.723937, -0.000085, -0.769935, 0.393498, 0.502355, 0.402401, 0.180546, 0.897483, 0.137952, -0.915708, 0.377422, -0.574445, -0.526311, 0.626905, -0.109588, 0.120932, 0.986593, -0.229534, -0.855253, 0.464603, 0.618726, 0.182265, 0.764171, -0.626296, -0.158395, 0.763325, -0.181479, -0.714904, 0.675261, -0.482948, 0.284813, 0.828035, 0.482989, 0.873599, -0.059548, -0.958839, -0.167844, 0.229032, -0.115169, -0.535894, 0.836393, -0.915823, -0.005845, 0.401539, -0.280839, -0.352330, 0.892744, 0.978273, 0.000845, 0.207318, -0.421443, -0.146103, 0.895008, 0.078022, -0.989200, 0.124081, 0.905200, -0.260006, -0.336168, 0.729587, 0.527463, 0.435299, 0.236680, -0.790552, 0.564809, -0.667751, 0.603014, 0.436444, 0.608554, 0.762124, -0.220972, -0.003496, 0.347226, 0.937775, 0.862257, 0.453728, 0.225041, 0.683682, -0.728179, 0.048324, 0.491891, 0.390901, 0.777971, 0.906079, 0.065028, 0.418081, 0.125516, -0.492969, 0.860946, -0.763774, -0.470484, 0.441922, -0.826476, 0.157999, 0.540346, -0.521429, 0.845027, 0.118496, -0.041052, 0.678116, 0.733808, 0.845697, -0.145999, 0.513304, 0.843548, 0.537049, -0.002422, 0.996106, 0.087624, -0.009745, 0.401168, -0.209195, 0.891797, 0.543082, 0.820463, 0.178612, -0.611077, -0.660826, 0.435768, -0.931432, 0.346194, 0.112179, -0.888586, -0.390281, 0.241029, -0.483476, 0.658763, 0.576439, 0.947394, 0.235489, 0.216768, -0.354871, 0.083043, 0.931220, -0.693989, 0.691280, 0.201273, 0.714212, -0.077757, 0.695597, 0.178594, -0.269755, 0.946222, -0.713746, -0.321414, 0.622302, 0.342217, 0.575818, 0.742510, -0.428725, -0.832944, 0.349856, -0.350655, -0.554413, 0.754763, -0.129994, -0.991369, 0.016979, 0.677912, -0.563698, 0.471891, -0.859476, -0.234793, 0.454062, -0.258045, 0.305163, 0.916672, -0.196034, -0.116018, 0.973710, 0.292411, 0.938332, -0.184470, 0.329114, 0.938583, 0.103666, 0.983404, -0.175694, 0.045257, -0.269773, 0.685391, 0.676359, -0.513320, 0.780850, 0.356056, 0.577407, -0.056771, -0.814480, 0.908048, -0.395877, 0.136858, -0.979114, 0.089367, 0.182617, 0.931014, -0.207048, 0.300574}; static float ps117 [351] = { -0.779124, 0.079168, 0.621850, -0.633129, 0.683542, 0.363206, 0.598839, -0.694510, 0.398807, 0.129440, -0.799176, 0.586994, 0.564760, -0.220557, 0.795236, -0.460851, -0.498849, 0.734007, -0.129343, 0.235834, 0.963147, -0.517758, -0.836603, -0.178949, 0.816471, 0.512401, 0.266121, -0.164689, 0.954632, 0.248105, 0.280992, -0.949048, 0.142660, -0.916948, 0.012598, 0.398807, -0.456785, 0.724586, 0.516064, -0.986896, 0.160352, -0.017983, -0.934836, -0.297690, -0.193552, 0.475363, -0.021876, 0.879518, -0.372435, -0.927593, 0.029370, -0.988831, -0.042466, 0.142865, -0.113215, -0.772233, 0.625171, 0.963110, 0.263728, -0.053537, -0.744250, 0.490187, 0.453661, 0.026379, 0.771176, 0.636076, -0.070324, 0.888048, 0.454340, -0.036343, -0.901974, 0.430258, 0.348437, -0.243062, 0.905269, 0.234567, 0.403753, 0.884286, -0.140554, -0.990044, 0.007617, -0.045461, -0.437350, 0.898141, -0.340426, 0.934947, 0.099919, 0.706539, 0.308703, 0.636792, 0.877750, 0.477712, 0.036704, 0.265758, 0.749383, 0.606464, -0.933626, -0.102049, -0.343407, 0.500423, -0.617992, 0.606352, 0.769506, 0.628777, -0.111803, 0.066565, 0.971253, 0.228553, -0.822694, -0.150654, 0.548159, 0.503176, -0.862836, 0.048244, 0.920571, -0.385582, -0.062258, -0.502046, 0.831439, 0.238032, 0.037224, -0.977315, 0.208494, -0.114421, -0.213569, 0.970204, -0.421175, -0.869846, 0.256865, 0.349878, 0.177580, 0.919810, -0.486229, -0.007131, 0.873802, 0.847366, 0.318229, 0.425088, 0.187818, -0.459030, 0.868341, -0.356457, -0.686478, 0.633787, 0.602332, 0.154463, 0.783159, -0.323094, 0.862264, 0.390014, -0.814154, 0.579374, -0.038468, -0.667390, -0.096003, 0.738495, 0.168420, 0.885566, 0.432907, -0.811172, -0.369832, 0.453017, 0.789604, -0.549266, 0.273555, 0.467473, 0.346328, 0.813342, 0.237211, -0.027118, 0.971080, 0.710349, 0.516942, 0.477677, 0.722697, 0.680766, 0.119446, -0.494967, -0.677922, -0.543535, -0.008060, 0.433431, 0.901151, -0.224276, 0.765208, 0.603454, -0.875390, 0.387034, 0.289650, 0.112524, 0.210497, 0.971097, -0.379496, 0.215353, 0.899781, 0.754483, -0.253941, 0.605203, -0.493062, 0.389625, 0.777871, 0.604800, -0.418578, 0.677502, 0.785219, -0.584827, -0.203488, -0.698909, 0.329659, 0.634705, 0.703888, -0.042805, 0.709020, 0.859235, -0.325875, 0.394361, -0.662175, 0.744467, 0.085401, -0.916204, 0.363657, -0.168298, 0.407136, -0.451032, 0.794236, -0.238707, 0.027849, 0.970692, 0.877760, 0.429288, -0.212717, -0.361407, 0.595045, 0.717848, -0.194948, -0.597299, 0.777964, 0.812729, 0.116070, 0.570964, 0.365001, -0.781703, 0.505682, -0.615568, -0.548634, 0.565753, -0.199246, -0.950308, 0.239198, 0.294812, 0.934474, 0.199609, 0.046109, -0.639699, 0.767241, 0.117373, -0.240956, 0.963412, -0.287350, -0.401665, 0.869538, 0.280100, -0.646615, 0.709530, 0.207854, -0.904564, 0.372236, -0.257359, 0.427422, 0.866647, 0.503271, 0.729836, -0.462664, -0.399928, -0.828086, -0.392851, 0.714885, -0.499669, 0.489152, -0.661457, 0.730597, -0.169422, 0.449506, -0.846000, 0.286754, 0.991928, 0.070585, 0.105340, -0.927774, -0.209952, 0.308472, -0.123117, 0.618279, 0.776256, 0.585469, 0.809588, -0.042348, -0.276905, -0.845832, 0.455951, 0.618928, 0.740468, -0.261983, 0.630238, 0.697250, 0.341531, 0.565539, 0.490942, 0.662677, 0.352980, 0.569605, 0.742264, -0.339867, -0.180050, 0.923078, 0.957696, -0.132154, 0.255642, -0.099359, 0.994841, 0.020468, 0.000000, -0.000000, 1.000000, -0.736624, -0.570130, 0.363780, -0.519413, -0.276580, 0.808526, 0.680829, 0.336406, -0.650617, 0.122050, 0.608393, 0.784195, -0.576344, 0.545659, 0.608345, 0.871594, -0.092148, 0.481491, -0.851818, 0.237844, 0.466730, -0.606522, 0.165860, 0.777574, -0.958412, 0.175780, 0.224830}; static float ps118 [354] = { 0.138204, -0.151299, 0.978779, 0.076798, -0.762167, 0.642809, -0.994415, -0.032019, 0.100563, 0.207528, -0.918396, -0.336870, 0.093478, -0.593739, 0.799210, -0.301947, -0.131003, 0.944281, 0.801561, 0.465258, 0.375546, -0.059443, -0.028434, 0.997827, 0.905349, -0.392073, 0.163162, -0.522171, -0.749866, 0.406249, 0.795329, 0.560424, -0.231033, 0.809280, 0.022866, 0.586978, 0.324264, -0.282806, 0.902703, -0.423838, 0.813704, 0.397803, -0.740073, 0.625514, 0.247033, 0.315930, 0.900864, 0.297713, -0.540240, -0.371732, 0.754954, -0.817406, 0.041635, 0.574555, -0.843972, -0.383290, 0.375235, -0.702443, -0.167608, 0.691724, -0.122696, -0.486736, 0.864890, -0.863764, 0.421485, 0.276156, -0.748892, 0.466343, 0.470834, -0.075715, 0.239656, 0.967901, 0.920597, 0.035585, 0.388890, 0.685014, 0.233345, 0.690149, -0.686537, -0.581414, 0.436607, 0.055343, -0.890362, 0.451877, -0.157518, -0.832254, 0.531546, 0.319345, -0.504560, 0.802146, -0.932839, -0.006880, 0.360229, 0.655411, 0.005370, 0.755253, -0.257367, -0.958805, 0.120232, 0.604601, -0.760861, 0.235688, 0.649212, 0.733686, -0.200569, 0.536577, 0.798728, 0.272249, -0.264700, 0.963359, -0.043284, -0.675826, 0.603283, -0.423448, -0.255928, 0.094643, 0.962052, -0.946101, -0.216371, 0.240991, 0.985801, -0.160439, 0.049558, -0.868147, 0.235798, 0.436715, 0.482802, 0.585401, 0.651312, -0.906761, -0.409574, 0.100170, -0.606942, 0.661128, 0.441056, 0.879119, 0.454340, 0.143962, 0.109580, 0.372532, 0.921527, -0.959549, 0.177062, 0.218895, 0.499465, 0.139638, 0.855006, -0.470840, 0.081540, 0.878442, 0.316792, 0.263165, 0.911256, -0.924641, -0.260523, -0.277788, 0.777486, -0.595454, 0.202364, 0.279965, -0.838743, 0.467044, -0.189086, 0.644234, 0.741087, 0.694636, -0.422403, 0.582286, 0.840625, -0.202055, 0.502518, -0.136869, 0.458411, 0.878138, -0.239478, 0.791652, 0.562083, -0.827477, 0.411092, -0.382473, -0.169471, -0.980840, -0.096084, -0.103364, -0.950065, 0.294437, 0.574025, -0.791709, -0.209024, -0.430257, 0.666722, 0.608573, -0.660249, 0.064776, 0.748248, 0.985608, 0.042348, 0.163654, -0.933063, 0.353499, 0.066572, -0.097254, -0.265756, 0.959122, 0.367775, -0.914589, -0.168133, 0.163758, -0.953346, 0.253602, 0.503757, -0.143673, 0.851814, 0.001128, -0.996897, 0.078708, 0.613389, 0.788748, 0.040374, -0.589798, 0.488754, 0.642851, 0.425501, 0.761515, 0.488922, -0.140977, -0.679310, 0.720183, 0.521287, -0.375691, 0.766235, -0.034051, 0.873026, 0.486484, 0.202209, 0.840933, 0.501939, -0.331202, -0.349314, 0.876519, 0.489301, -0.742928, 0.456774, -0.539866, -0.572490, 0.617089, 0.829489, -0.557453, -0.034552, 0.103055, -0.985520, -0.134649, 0.627398, 0.637199, 0.447603, 0.675703, 0.446647, 0.586457, 0.304565, 0.494236, 0.814230, 0.071380, 0.951477, 0.299327, -0.713088, -0.385185, 0.585780, -0.326520, 0.307669, 0.893714, 0.019114, 0.744137, 0.667754, -0.359848, -0.727961, 0.583594, -0.939307, 0.186595, -0.287896, -0.847756, -0.185026, 0.497067, 0.134683, 0.116675, 0.983996, 0.509280, 0.375750, 0.774239, -0.325532, -0.873776, 0.361310, 0.306074, -0.691011, 0.654845, 0.067609, 0.576751, 0.814118, 0.514464, -0.578102, 0.633343, 0.262003, 0.686937, 0.677844, 0.782994, 0.622030, -0.000511, 0.682116, -0.731244, -0.000127, 0.726479, 0.648073, 0.228539, -0.727297, 0.274125, 0.629202, 0.396432, -0.881865, 0.255257, -0.544002, 0.296455, 0.784969, 0.330663, -0.009846, 0.943697, -0.345252, -0.552548, 0.758612, -0.469224, -0.867860, 0.163240, 0.693141, -0.215054, 0.687973, -0.493981, 0.868863, -0.032571, -0.380981, 0.502071, 0.776388, -0.971165, -0.236191, -0.032429, 0.107855, -0.389209, 0.914813, -0.518376, -0.151192, 0.841681, 0.828937, 0.255268, 0.497696, -0.409173, -0.909215, -0.076846}; static float ps119 [357] = { -0.236302, -0.397010, 0.886873, 0.663619, 0.619735, 0.418973, -0.683725, -0.354866, 0.637644, 0.683611, -0.579292, 0.443956, -0.046716, -0.978389, -0.201425, -0.860313, -0.508734, 0.032434, 0.907963, -0.190925, 0.373031, -0.156014, -0.741169, 0.652938, -0.214469, -0.856590, 0.469315, -0.996238, -0.014832, 0.085378, 0.803243, 0.436265, 0.405553, -0.243220, 0.867767, 0.433386, -0.579476, 0.561673, 0.590534, -0.356363, 0.608767, 0.708807, -0.296521, 0.944319, -0.142606, -0.560847, -0.555593, 0.613814, -0.579300, 0.220527, 0.784716, 0.384269, 0.230143, 0.894076, 0.138749, 0.227503, 0.963842, -0.848790, -0.274218, 0.452063, 0.145584, -0.182419, 0.972383, 0.810728, -0.540844, 0.224072, -0.403605, -0.729656, 0.552001, -0.875758, -0.407372, 0.259028, 0.020868, -0.883602, 0.467774, 0.465665, 0.769059, 0.437840, 0.076215, -0.752891, 0.653718, 0.268306, 0.783922, 0.559891, 0.446187, -0.849486, 0.281585, -0.513174, -0.857829, -0.027957, 0.256334, -0.382688, 0.887605, 0.313940, 0.618161, 0.720638, 0.481463, -0.380704, 0.789467, -0.753175, -0.616460, 0.229575, -0.911868, -0.375415, -0.166013, -0.736316, 0.676016, -0.028997, -0.950181, -0.149407, 0.273559, 0.391104, -0.179779, 0.902617, 0.528221, -0.569972, 0.629377, 0.777812, 0.238400, 0.581527, -0.758767, 0.491324, 0.427638, -0.094835, -0.994116, 0.052341, -0.609083, 0.778207, 0.153009, 0.889027, -0.388395, -0.242447, -0.572174, -0.206840, 0.793621, 0.675160, -0.387209, 0.627876, -0.857770, 0.264368, 0.440841, 0.417436, 0.874871, 0.245657, -0.464692, -0.405772, 0.787026, -0.582918, -0.791025, 0.185705, -0.455253, 0.010960, 0.890295, -0.000254, 0.424047, 0.905640, -0.892365, -0.005476, 0.451281, 0.467962, 0.429081, 0.772594, 0.336371, 0.590260, -0.733790, 0.264789, 0.958795, 0.102953, -0.954821, 0.128922, 0.267760, -0.597450, -0.690358, 0.407995, 0.981925, 0.151902, 0.112915, 0.050629, 0.781582, 0.621745, -0.190115, 0.953903, 0.232217, -0.955961, -0.283871, 0.074542, 0.952878, 0.022192, 0.302541, -0.923756, 0.337581, -0.180869, -0.126646, 0.606142, 0.785209, -0.360413, 0.226161, 0.904961, 0.508497, 0.612971, 0.604729, 0.119566, -0.579115, 0.806430, 0.346553, 0.930042, -0.122160, 0.245789, -0.881183, 0.403861, -0.695613, 0.358130, 0.622789, 0.661446, 0.435303, 0.610738, 0.773459, -0.600044, -0.204228, 0.216008, 0.904937, 0.366646, -0.876810, 0.480691, 0.011819, 0.623501, 0.749462, 0.222605, -0.438760, 0.847593, 0.298455, -0.008913, 0.902519, 0.430558, 0.293891, -0.750550, 0.591863, 0.855032, 0.025049, 0.517969, -0.410479, -0.848579, 0.333796, 0.333864, -0.576811, 0.745536, -0.353304, -0.200164, 0.913844, 0.127946, -0.991721, -0.010964, 0.784920, -0.187926, 0.590410, -0.964941, 0.254715, 0.063320, 0.079153, -0.967052, 0.241960, 0.228060, -0.016482, -0.973508, -0.742270, -0.498101, 0.448253, -0.478502, 0.422483, 0.769769, -0.158384, -0.949211, 0.271871, -0.541455, 0.838343, -0.063298, -0.778659, 0.132971, 0.613196, 0.609982, -0.183159, 0.770957, 0.705476, 0.026519, 0.708238, 0.647975, -0.718348, 0.253188, 0.273008, 0.024590, 0.961697, -0.792099, -0.576422, -0.200793, -0.181079, 0.762105, 0.621616, 0.508364, 0.026410, 0.860737, -0.377437, 0.922257, 0.083566, 0.900837, 0.236443, 0.364126, -0.651673, 0.004938, 0.758484, 0.817053, -0.391990, 0.422811, 0.986362, -0.114263, 0.118461, 0.713360, 0.700798, 0.000310, -0.116683, 0.227591, 0.966741, 0.019746, 0.021156, 0.999581, 0.620406, -0.686456, -0.379308, 0.428079, -0.738154, -0.521418, 0.099642, 0.615857, 0.781532, -0.109705, -0.190898, 0.975460, -0.106922, -0.576801, 0.809857, -0.774221, -0.133194, 0.618742, -0.250016, 0.425502, 0.869736, 0.242823, 0.427647, 0.870721, 0.013248, -0.385738, 0.922513, 0.490730, -0.734215, 0.469162, 0.603005, 0.235329, 0.762237}; static float ps120 [360] = { 0.535275, -0.120662, 0.836015, -0.968000, 0.228788, 0.103117, 0.081375, 0.944102, 0.319452, 0.809120, -0.577430, 0.109087, 0.315658, -0.476320, 0.820658, 0.846069, 0.505203, 0.170109, -0.121051, -0.820173, 0.559162, -0.717055, -0.524466, 0.459095, -0.071812, -0.449370, 0.890455, 0.322178, -0.815621, 0.480588, -0.991206, -0.008725, 0.132042, 0.321829, -0.231948, 0.917947, 0.107783, 0.361110, 0.926273, 0.497697, -0.341559, 0.797267, -0.449224, 0.687995, 0.569965, 0.640053, 0.596064, 0.484810, -0.013123, 0.856803, 0.515478, 0.861140, 0.399683, -0.314152, 0.844946, 0.199476, 0.496262, 0.941588, 0.331077, 0.061645, 0.714426, 0.141262, 0.685304, 0.706480, 0.656998, 0.263134, -0.470899, -0.466779, 0.748580, -0.663905, 0.328394, 0.671854, 0.107207, 0.132300, 0.985395, 0.866498, 0.490146, -0.094541, -0.362476, -0.810655, 0.459836, 0.822309, -0.274757, 0.498314, -0.919337, -0.269455, -0.286729, -0.924648, -0.144591, 0.352306, -0.341420, 0.925633, 0.163206, 0.328144, 0.222398, 0.918074, 0.573289, 0.730513, -0.371065, -0.083719, -0.672376, 0.735460, -0.301259, -0.322638, 0.897300, -0.879008, 0.466778, 0.097277, -0.416915, 0.828563, 0.373717, -0.957388, -0.246425, 0.150606, -0.211730, -0.967743, 0.136540, 0.106071, 0.570639, 0.814322, -0.834158, -0.046443, 0.549567, -0.522456, -0.000810, 0.852666, 0.987687, -0.118477, 0.102169, -0.654800, -0.385430, 0.650139, 0.577462, 0.808240, 0.115266, 0.705859, 0.370994, 0.603429, -0.189826, -0.974912, -0.116242, 0.540612, 0.316668, 0.779397, -0.510628, -0.238764, 0.825985, 0.118495, -0.581494, 0.804875, 0.838792, -0.444936, 0.313784, -0.319375, 0.381169, 0.867589, 0.153658, 0.758189, 0.633671, -0.612809, 0.709370, 0.348223, 0.704189, -0.505322, 0.498766, -0.289645, 0.602908, 0.743376, -0.780016, 0.400361, 0.480922, 0.424216, 0.723213, 0.544981, -0.927602, 0.356967, -0.110133, 0.677508, -0.320426, 0.662050, 0.283107, -0.919578, 0.272445, 0.406916, 0.879835, -0.245581, -0.070208, 0.696905, 0.713719, 0.334087, -0.665368, 0.667586, -0.110160, 0.024212, 0.993619, -0.098338, -0.217524, 0.971088, -0.642314, 0.760608, -0.094384, -0.691505, 0.653509, -0.307810, 0.534622, 0.100408, 0.839105, 0.257632, 0.857717, 0.444914, -0.109235, 0.489946, 0.864882, 0.630401, -0.559841, -0.537748, 0.121601, -0.761710, 0.636405, 0.314834, 0.621677, 0.717215, -0.164813, -0.919312, 0.357354, -0.008204, -0.999722, 0.022127, -0.490954, 0.481749, 0.725866, -0.320566, -0.093333, 0.942617, -0.321872, 0.144097, 0.935753, 0.125320, -0.347587, 0.929235, -0.827745, 0.181870, 0.530812, 0.044038, -0.969487, 0.241153, 0.528176, -0.532360, 0.661531, -0.101235, 0.979218, 0.175738, -0.535326, -0.618720, 0.574989, -0.742175, -0.624873, 0.242300, -0.241396, 0.784549, 0.571148, 0.715716, -0.090344, 0.692523, -0.111942, 0.264494, 0.957868, -0.990211, -0.109670, -0.086339, 0.406394, 0.913691, -0.003708, -0.732758, 0.671997, 0.107167, 0.927836, -0.205887, 0.311017, 0.524792, 0.521933, 0.672443, -0.193720, 0.908027, 0.371429, 0.088756, -0.889854, 0.447530, 0.363559, 0.900063, 0.240234, 0.596071, 0.792122, -0.131308, -0.552312, 0.821157, 0.143706, -0.446565, 0.892265, -0.066656, -0.263438, -0.535609, 0.802324, 0.521977, 0.777730, 0.350252, -0.227142, 0.972669, -0.048175, 0.529760, -0.692425, 0.489798, 0.948727, 0.033660, 0.314299, -0.897871, 0.323126, 0.299028, -0.692735, 0.091724, 0.715336, 0.109501, -0.106162, 0.988301, 0.330443, 0.431504, 0.839412, 0.500141, -0.815836, 0.290293, -0.511225, 0.240031, 0.825248, -0.936397, 0.092572, 0.338512, -0.808935, -0.284447, 0.514504, 0.802547, 0.443308, 0.399244, 0.745117, 0.666844, 0.010981, 0.327451, -0.002967, 0.944863, -0.690066, -0.149839, 0.708066, -0.777906, 0.551017, 0.302064, -0.323441, -0.691857, 0.645539, 0.855144, -0.037584, 0.517026}; static float ps121 [363] = { -0.600352, -0.319758, 0.733030, -0.846943, -0.445872, 0.289630, -0.738878, 0.439422, 0.510849, 0.781240, 0.519106, 0.346688, -0.771247, 0.564913, 0.293343, 0.717659, -0.420918, 0.554792, 0.085923, 0.991313, -0.099578, -0.170408, 0.436652, 0.883344, -0.422126, 0.805228, 0.416435, -0.499159, -0.864448, 0.059750, -0.102169, 0.062677, 0.992791, 0.994960, 0.011165, -0.099652, -0.060049, 0.952900, -0.297280, 0.890397, -0.447112, -0.085350, -0.937677, 0.146648, 0.315050, 0.619128, 0.750238, -0.231999, 0.365922, -0.687151, 0.627634, 0.445106, 0.797001, 0.408252, 0.060129, 0.988720, 0.137178, -0.348621, -0.656077, 0.669348, -0.494467, 0.850312, -0.180196, -0.948902, -0.263581, 0.173523, 0.289260, 0.953996, 0.078872, 0.639588, -0.268835, 0.720177, -0.025036, -0.856571, 0.515421, 0.720182, -0.046751, 0.692208, -0.272976, 0.223996, 0.935580, 0.878176, -0.363756, -0.310625, 0.762572, 0.179421, 0.621524, 0.484716, 0.855701, 0.181179, 0.204650, -0.347241, 0.915173, 0.260677, 0.917345, 0.300874, 0.716384, 0.432549, 0.547444, -0.226566, 0.765062, 0.602783, -0.652577, 0.289298, 0.700321, -0.174133, -0.553875, 0.814187, 0.867534, -0.351021, 0.352376, 0.979181, 0.195085, 0.056092, 0.421991, 0.324721, 0.846451, -0.749748, -0.174748, 0.638233, -0.421154, -0.848296, 0.320972, -0.969604, 0.226359, 0.092896, 0.372362, 0.693543, 0.616721, 0.201245, -0.851428, 0.484326, -0.719308, 0.070992, 0.691054, 0.580627, 0.112780, 0.806321, -0.019952, 0.277466, 0.960528, 0.908027, 0.363461, 0.208288, -0.505894, -0.522349, -0.686457, -0.357650, 0.004662, 0.933844, -0.169179, 0.968505, 0.182695, -0.101101, -0.722440, 0.684002, -0.618166, 0.636190, 0.461663, -0.352108, 0.935914, -0.009164, 0.370432, 0.102460, 0.923191, 0.515632, -0.479913, 0.709793, -0.736927, -0.410347, 0.537172, 0.575657, -0.615579, 0.538221, 0.991493, -0.059041, 0.115997, -0.008131, 0.818888, 0.573896, 0.667789, 0.743662, 0.032008, 0.209381, 0.309649, 0.927511, 0.952649, 0.118913, 0.279857, 0.805543, 0.579822, 0.122095, -0.303246, -0.941216, 0.148841, 0.606378, -0.720071, 0.337348, -0.082402, 0.647981, 0.757186, 0.703394, -0.698492, 0.131707, 0.282682, -0.925405, 0.252421, 0.066344, 0.497031, 0.865193, 0.517532, -0.102047, 0.849557, -0.247409, -0.355826, 0.901209, 0.215316, 0.831627, 0.511895, -0.823041, 0.226928, 0.520679, 0.293687, 0.523056, 0.800100, 0.063639, -0.558190, 0.827269, 0.815365, -0.204452, 0.541644, -0.605738, 0.753029, 0.256962, -0.423979, 0.368175, 0.827459, 0.935056, -0.129962, 0.329819, -0.864117, -0.256487, 0.433031, -0.395991, 0.893676, 0.211033, -0.902161, -0.430536, 0.027282, -0.780864, -0.609989, 0.134777, -0.699732, -0.597807, 0.391154, -0.586234, -0.074292, 0.806728, -0.426779, -0.216334, 0.878100, -0.417954, -0.461053, 0.782780, 0.859594, 0.281627, 0.426362, -0.434755, 0.670906, 0.600727, -0.569106, -0.542904, 0.617555, -0.310232, 0.567990, 0.762328, -0.515531, 0.152689, 0.843157, 0.946202, -0.296133, 0.130407, -0.201160, 0.893017, 0.402562, -0.571401, 0.819655, 0.040824, 0.141918, 0.082856, 0.986405, 0.061564, -0.141013, 0.988092, 0.596005, 0.633787, 0.493043, -0.509064, -0.714777, 0.479529, -0.555751, 0.490482, 0.671244, 0.413625, -0.804626, 0.426017, 0.139323, -0.722211, 0.677496, 0.424872, -0.316829, 0.847999, 0.147403, 0.687960, 0.710622, 0.295177, -0.121902, 0.947634, 0.849113, -0.510171, 0.136870, 0.757091, -0.549124, 0.353943, 0.027370, 0.931447, 0.362847, 0.294894, -0.534691, 0.791924, -0.170518, -0.925064, 0.339382, 0.757660, -0.647627, -0.080810, -0.021097, -0.360990, 0.932331, -0.946702, -0.081545, 0.311619, -0.134648, 0.989399, -0.054407, -0.273968, -0.810401, 0.517872, 0.613623, 0.322850, 0.720580, 0.870960, 0.027404, 0.490589, -0.858163, -0.006355, 0.513338, -0.179287, -0.149644, 0.972349, 0.648462, 0.710245, 0.273951}; static float ps122 [366] = { 0.350814, -0.500984, 0.791167, 0.765580, 0.634311, 0.107408, 0.172218, -0.390264, 0.904453, 0.741241, 0.196159, 0.641937, -0.934285, -0.338285, 0.112581, 0.958551, -0.280597, 0.049455, -0.783227, 0.618886, -0.059464, -0.142898, 0.886105, 0.440905, 0.211900, -0.140050, -0.967204, 0.447876, 0.608904, 0.654709, -0.524725, -0.818916, 0.232468, 0.096709, -0.790687, 0.604534, -0.608454, 0.306148, 0.732159, -0.746987, -0.098712, 0.657470, -0.190095, 0.580805, 0.791536, 0.988150, 0.110020, -0.107031, -0.584882, 0.760398, 0.282327, -0.117661, -0.941320, 0.316343, 0.561616, -0.397887, 0.725447, 0.059177, 0.834021, 0.548550, -0.962059, 0.034760, 0.270620, 0.457594, 0.756063, 0.467950, 0.895942, 0.431101, 0.106963, 0.257463, -0.937636, 0.233564, -0.528820, 0.693123, 0.489827, -0.532322, -0.712391, 0.457310, 0.620934, 0.444365, 0.645740, -0.609471, 0.080171, 0.788745, -0.406496, -0.913653, 0.000158, 0.255391, 0.874298, 0.412769, 0.874622, 0.118898, 0.470000, 0.457496, -0.843685, 0.280879, -0.278091, -0.556295, 0.783072, -0.420911, 0.250977, 0.871691, -0.013707, 0.995381, 0.095015, -0.339671, -0.839911, 0.423289, -0.374000, 0.662389, 0.649126, -0.583250, 0.512771, 0.629988, -0.626899, 0.777316, 0.052702, -0.176460, 0.761171, 0.624084, 0.240084, -0.970745, -0.003667, 0.220273, 0.571605, 0.790410, 0.134032, -0.611703, 0.779650, -0.884135, 0.205688, 0.419520, -0.831286, -0.544600, 0.111235, 0.451891, -0.890573, 0.051706, 0.742818, -0.587088, 0.321792, 0.000000, -0.000000, 1.000000, 0.945087, -0.197459, 0.260425, 0.257457, 0.739152, 0.622391, -0.199817, -0.102582, 0.974449, 0.420844, -0.888259, -0.184081, 0.046790, -0.987146, 0.152819, -0.092008, -0.689556, 0.718365, 0.786859, 0.370946, 0.493205, 0.876363, -0.118542, 0.466837, -0.759281, 0.622552, 0.189529, -0.456042, -0.402550, 0.793712, 0.584363, 0.808058, 0.074585, -0.324050, -0.921970, 0.212046, 0.362363, -0.831425, -0.421220, 0.047825, 0.946842, 0.318123, 0.885498, -0.457900, -0.078870, -0.208478, 0.370469, 0.905146, -0.923281, -0.210215, 0.321499, -0.711929, 0.566923, 0.414434, 0.741857, -0.272576, 0.612658, -0.581606, -0.156973, 0.798182, -0.122770, -0.839433, 0.529414, 0.997553, -0.057691, 0.039494, 0.024707, 0.681951, 0.730981, 0.906042, 0.290037, 0.308166, 0.974132, 0.200850, 0.103566, -0.838415, -0.436175, 0.326821, 0.875093, -0.444887, 0.190496, 0.205094, -0.950313, -0.234182, -0.406619, 0.466263, 0.785659, 0.757409, -0.038487, 0.651805, 0.167352, 0.984384, -0.054596, -0.388756, -0.207380, 0.897698, 0.403547, 0.433359, 0.805823, -0.856798, 0.412410, 0.309541, 0.009454, 0.479447, 0.877520, 0.559229, -0.706468, 0.433781, 0.307402, -0.698925, 0.645761, 0.689563, -0.494226, 0.529380, -0.001404, 0.248369, 0.968664, 0.197846, -0.150083, 0.968676, 0.389558, -0.281581, 0.876902, -0.414854, 0.024112, 0.909568, -0.681090, -0.724694, 0.104572, -0.219447, -0.358751, 0.907271, 0.391974, 0.193347, 0.899429, -0.320842, -0.717211, 0.618602, -0.755984, 0.368554, 0.540978, 0.840240, -0.357874, 0.407337, 0.592248, 0.047142, 0.804375, 0.630907, 0.719788, 0.289587, -0.506753, -0.571867, 0.645112, 0.320760, -0.825716, 0.464011, 0.402924, -0.047319, 0.914009, -0.013143, -0.255376, 0.966753, -0.768741, 0.142826, 0.623408, -0.650330, -0.347730, 0.675393, 0.205872, 0.348960, 0.914245, 0.503213, -0.601009, 0.620938, 0.638177, -0.747257, 0.185302, 0.962836, 0.035272, 0.267775, 0.590624, -0.179237, 0.786789, 0.200243, 0.100133, 0.974616, -0.702541, -0.637581, 0.316112, 0.232839, 0.957290, 0.171412, 0.795874, 0.519250, 0.311391, 0.642596, 0.596158, 0.481318, -0.692554, -0.509351, 0.510814, -0.809107, -0.283331, 0.514849, 0.568899, 0.271502, 0.776300, 0.433996, 0.864829, 0.252425, -0.043210, -0.496190, 0.867138, 0.097624, -0.909721, 0.403581, -0.876260, -0.033880, 0.480645, -0.957339, 0.231658, 0.172731}; static float ps123 [369] = { -0.186370, -0.654884, 0.732389, 0.035850, -0.621385, 0.782685, -0.308443, 0.351821, 0.883790, 0.662907, 0.093127, 0.742888, 0.493791, -0.830124, 0.258969, -0.503014, -0.280078, 0.817639, -0.859233, -0.294409, -0.418381, -0.955228, 0.131718, 0.264933, -0.429761, 0.822780, 0.371938, -0.263423, -0.806010, 0.530053, -0.748601, -0.653551, 0.111658, 0.217305, 0.820375, 0.528927, -0.290361, -0.265741, 0.919278, 0.629643, -0.516542, 0.580288, 0.085474, 0.232989, 0.968716, -0.685030, 0.696849, -0.212451, -0.407230, -0.909635, 0.082018, -0.029999, -0.999345, 0.020236, -0.158306, 0.179331, 0.970968, 0.373084, 0.498751, 0.782340, 0.574918, -0.817896, 0.022690, -0.683886, -0.340988, 0.645002, -0.358312, -0.876123, 0.322523, -0.870238, 0.488093, 0.066721, -0.629583, -0.561087, 0.537408, 0.606612, 0.751801, 0.258490, 0.463395, 0.103426, 0.880095, 0.001600, 0.785043, 0.619440, -0.610736, 0.105631, 0.784757, -0.396955, 0.143783, 0.906506, -0.506234, -0.740171, 0.442577, -0.037992, -0.792019, 0.609314, -0.420670, 0.666972, -0.614967, -0.410507, 0.898643, 0.154678, 0.986561, 0.128761, 0.100584, -0.875160, -0.482942, -0.029359, -0.954700, -0.289549, 0.068624, 0.160219, 0.461860, 0.872362, 0.575498, -0.694260, 0.432209, -0.399861, -0.659725, 0.636297, 0.315898, 0.288291, 0.903934, -0.109584, -0.912310, 0.394565, 0.373899, -0.116634, 0.920107, 0.567014, 0.501032, 0.653806, -0.593848, -0.804452, -0.014196, 0.606553, -0.765916, -0.213229, 0.000000, -0.000000, 1.000000, 0.186897, -0.982037, -0.025946, 0.002416, 0.905926, 0.423429, 0.256845, -0.561779, 0.786407, 0.610021, -0.310146, 0.729167, 0.419941, 0.813178, 0.402979, 0.053422, -0.972647, 0.226061, -0.508308, -0.479854, 0.715097, 0.940390, -0.315465, 0.127080, -0.223240, -0.923173, -0.312915, 0.375086, -0.924218, 0.071640, -0.066506, -0.233162, 0.970161, 0.429535, 0.886450, 0.172356, -0.236420, -0.968549, -0.077575, -0.759168, 0.451944, 0.468412, 0.118795, -0.883028, 0.454036, -0.914702, -0.250165, 0.317392, 0.883431, -0.117260, 0.453652, -0.997162, 0.075242, -0.002571, 0.218546, 0.666766, 0.712503, -0.413002, 0.535346, 0.736773, 0.132614, -0.403663, 0.905246, -0.796792, -0.413714, 0.440412, 0.732806, 0.469690, 0.492328, 0.836234, -0.522809, 0.165481, 0.009197, 0.619531, 0.784919, -0.201680, 0.547914, 0.811859, 0.956457, -0.276572, -0.093267, -0.236882, -0.043403, 0.970568, -0.063581, 0.396315, 0.915910, -0.923372, -0.329756, -0.196585, -0.526207, 0.326639, 0.785120, 0.531755, 0.308639, 0.788656, 0.363317, -0.330557, 0.871053, 0.828326, 0.093650, 0.552364, 0.741314, -0.670684, -0.025242, -0.982254, -0.082168, 0.168601, -0.211287, 0.940648, 0.265591, -0.431330, 0.700296, 0.568806, 0.465897, -0.480661, 0.742903, -0.197334, -0.963812, 0.179235, 0.769904, -0.326769, 0.548152, -0.221321, 0.849831, 0.478334, -0.710992, 0.282233, 0.644076, -0.570351, -0.790848, 0.221943, 0.568666, -0.113939, 0.814639, 0.263575, -0.928097, 0.262992, -0.709141, -0.621386, 0.333164, 0.419946, 0.680578, 0.600383, -0.601376, 0.504694, 0.619380, -0.817734, -0.187521, 0.544193, 0.755243, -0.530506, 0.384930, -0.616296, 0.659177, 0.430887, -0.764307, 0.589967, 0.260335, -0.802981, -0.521903, -0.287816, 0.234013, 0.060972, 0.970320, 0.878764, -0.330259, 0.344533, 0.158833, -0.182665, 0.970261, -0.860597, -0.462499, 0.213229, -0.093089, -0.452021, 0.887137, -0.908877, -0.026957, 0.416191, 0.966616, -0.107956, 0.232376, -0.784195, 0.047655, 0.618681, 0.716403, 0.289310, 0.634875, -0.609084, -0.651647, -0.452076, -0.879559, 0.376286, 0.291178, 0.194766, -0.744666, 0.638388, 0.938568, 0.098353, 0.330782, -0.665500, -0.119554, 0.736760, -0.308893, -0.477046, 0.822808, 0.011507, 0.978386, 0.206467, -0.748135, -0.652619, -0.119928, -0.218375, 0.717066, 0.661912, 0.352034, -0.817863, 0.455162, -0.463449, -0.069563, 0.883389, -0.856165, 0.216428, 0.469192, 0.750044, -0.113551, 0.651567}; static float ps124 [372] = { -0.669303, -0.213104, 0.711772, 0.785895, 0.617771, 0.026979, 0.893998, -0.355829, -0.272311, 0.798230, 0.384216, 0.463905, -0.280080, 0.288247, -0.915680, 0.799712, -0.225256, 0.556525, 0.997948, -0.060912, 0.019750, -0.738404, 0.204694, 0.642542, 0.868162, -0.343409, 0.358281, -0.453668, 0.062882, 0.888950, 0.478092, -0.324262, 0.816261, -0.668865, -0.440811, 0.598586, -0.218450, 0.974042, -0.059352, 0.325255, -0.257847, -0.909793, -0.133599, 0.901369, 0.411930, 0.644572, -0.136068, 0.752338, -0.022588, -0.770511, 0.637027, 0.535466, 0.289211, 0.793494, 0.724563, 0.653633, -0.218568, 0.097764, 0.737447, 0.668292, 0.480193, 0.862932, 0.157366, 0.625882, 0.779511, -0.025196, 0.436220, 0.484533, 0.758248, -0.409871, 0.450683, 0.793026, 0.508448, 0.775722, 0.373813, 0.040891, 0.378449, 0.924718, 0.653553, -0.347648, 0.672316, 0.588610, -0.807917, 0.028439, 0.420879, -0.890754, 0.171515, 0.874564, 0.149844, 0.461178, -0.154454, -0.176668, 0.972076, 0.556996, 0.787267, -0.264512, 0.861202, -0.500885, -0.086286, 0.637421, 0.449161, 0.626059, -0.348123, 0.881455, 0.319136, 0.508255, 0.643143, 0.572752, -0.915038, -0.290778, -0.279559, -0.266504, -0.686942, 0.676081, -0.294266, -0.899936, -0.321751, -0.072051, -0.604142, 0.793613, 0.037304, -0.980733, 0.191758, -0.550563, 0.248795, 0.796858, -0.648574, 0.019077, 0.760913, 0.783759, 0.005612, 0.621040, 0.982508, 0.075849, -0.170076, 0.760369, -0.644479, 0.080533, 0.764021, -0.572783, 0.296970, -0.879333, 0.164647, 0.446839, -0.117742, 0.780111, 0.614462, 0.888720, -0.436026, 0.141624, -0.769211, 0.557895, 0.311556, -0.804168, -0.025671, 0.593847, 0.161318, -0.660807, 0.733015, -0.362110, -0.882763, 0.299343, -0.089942, -0.873242, -0.478915, 0.528817, -0.531861, 0.661420, -0.258967, 0.630773, 0.731479, -0.789425, 0.375716, 0.485434, -0.146497, -0.936231, 0.319392, 0.617842, -0.419148, -0.665271, -0.467874, 0.618961, 0.630858, 0.312983, 0.796571, 0.517220, -0.389604, 0.917905, 0.075225, 0.379873, -0.689040, 0.617187, -0.904694, -0.418605, -0.079365, 0.958921, -0.203015, 0.198128, 0.115192, -0.466590, 0.876940, 0.153011, 0.175665, 0.972486, 0.213138, -0.812478, 0.542634, -0.212621, -0.832391, 0.511779, 0.234438, -0.921094, 0.310845, -0.917424, -0.058284, 0.393620, 0.330626, -0.509659, 0.794314, -0.430586, -0.899854, 0.069702, -0.332560, 0.780560, 0.529273, -0.105832, 0.206481, 0.972710, -0.963905, 0.142400, 0.224964, -0.109825, -0.404377, 0.907975, -0.901019, -0.282181, 0.329453, 0.300768, 0.339426, 0.891251, 0.306536, 0.504636, -0.807080, -0.712786, 0.685611, 0.147898, -0.434139, -0.755545, 0.490586, -0.038814, 0.601194, 0.798160, 0.060454, 0.962008, 0.266244, -0.067241, 0.238837, -0.968729, -0.541015, 0.734306, 0.409996, -0.956859, 0.288397, 0.035323, 0.448928, -0.098529, 0.888119, 0.305833, 0.654720, 0.691237, 0.950508, 0.290719, -0.109622, 0.587588, -0.660082, 0.468008, -0.806474, -0.256220, 0.532871, 0.667814, 0.714431, 0.208836, 0.812297, 0.521912, 0.260350, 0.678460, 0.597790, 0.427013, -0.256506, 0.013924, 0.966442, 0.484720, 0.586910, -0.648524, 0.605284, 0.079179, 0.792062, 0.607778, -0.752332, 0.254170, -0.627770, -0.635466, 0.449542, 0.857790, 0.486922, -0.164631, 0.231830, -0.053291, 0.971295, 0.728083, -0.472771, 0.496370, -0.544985, 0.812167, 0.208269, 0.390570, 0.126148, 0.911889, 0.420390, -0.812091, 0.404698, -0.489322, -0.150792, 0.858968, -0.171582, 0.968157, 0.182297, -0.785991, -0.475766, 0.394797, 0.728848, 0.233330, 0.643690, 0.257497, 0.959783, 0.111855, -0.654042, 0.570232, 0.497056, 0.035266, -0.896410, 0.441821, 0.180071, 0.529045, 0.829269, 0.904746, -0.093243, 0.415622, 0.981869, 0.172752, 0.078044, -0.328407, -0.287644, 0.899672, 0.000000, 0.000000, 1.000000, 0.966266, 0.041636, 0.254158, -0.015441, -0.999068, -0.040300, -0.512210, -0.382769, 0.768849, -0.206613, -0.972855, 0.104230, -0.183237, 0.439024, 0.879592}; static float ps125 [375] = { -0.654707, 0.002136, 0.755879, 0.398473, 0.468800, 0.788319, 0.805669, -0.228269, 0.546618, -0.404532, -0.256016, 0.877958, 0.322539, -0.939628, 0.114311, 0.373323, -0.099230, 0.922379, 0.922817, -0.098706, 0.372379, 0.919198, 0.392623, -0.030374, 0.071260, -0.656356, 0.751079, 0.638481, 0.751608, 0.165612, 0.678676, 0.145176, 0.719947, 0.051577, 0.975464, 0.214030, -0.612734, 0.669885, -0.419300, 0.913173, 0.134733, 0.384657, -0.969535, 0.194491, -0.148913, -0.145443, 0.161209, 0.976145, -0.566779, 0.208926, 0.796939, 0.124467, 0.965120, -0.230327, -0.152841, -0.884368, 0.441058, -0.985465, -0.163264, 0.046933, 0.063989, 0.692635, 0.718444, 0.850280, -0.515296, -0.107207, 0.782624, 0.260283, 0.565467, 0.918688, 0.314449, -0.239028, 0.698406, 0.498272, 0.513764, 0.451088, 0.851326, 0.267889, -0.985771, -0.024759, -0.166258, -0.795906, -0.455353, 0.398983, 0.236427, 0.905918, 0.351304, -0.649849, 0.735321, -0.192355, 0.862852, -0.408268, -0.298000, 0.513306, 0.597462, 0.616081, -0.182518, -0.643040, 0.743765, -0.962611, -0.071024, 0.261411, 0.576527, 0.705545, 0.412095, 0.609314, 0.382828, 0.694391, 0.479909, 0.255062, 0.839423, 0.192411, -0.795340, 0.574815, -0.523979, -0.823061, 0.219125, -0.141588, 0.988774, 0.047736, -0.422654, -0.610839, 0.669507, -0.386333, 0.846844, 0.365517, 0.474525, -0.834236, 0.280850, -0.307975, 0.579962, 0.754185, -0.305501, -0.463660, 0.831678, -0.552516, 0.803428, 0.221879, 0.182007, -0.493578, 0.850444, -0.944057, 0.173453, 0.280482, -0.450111, 0.403617, 0.796551, 0.692263, -0.109876, 0.713231, -0.528703, -0.426930, 0.733623, 0.284527, -0.306029, 0.908510, -0.378065, 0.721829, 0.579681, 0.640012, -0.357332, 0.680219, 0.300461, 0.658760, 0.689752, -0.140763, 0.732232, 0.666350, -0.103938, 0.977688, -0.182544, -0.500943, -0.733870, 0.458793, -0.362119, 0.923268, 0.128245, -0.727559, 0.625817, 0.281091, -0.677432, -0.658959, 0.326893, 0.728448, -0.460349, 0.507388, 0.085219, 0.140166, 0.986454, -0.178584, 0.944999, 0.274017, 0.379072, 0.779780, 0.498244, 0.064955, -0.910520, 0.408332, -0.568359, 0.695044, 0.440321, -0.783807, -0.115783, 0.610115, -0.995538, 0.069959, 0.063320, 0.848119, 0.364941, 0.384072, -0.276846, 0.893337, -0.353986, -0.087758, 0.548365, 0.831622, 0.953584, 0.243932, 0.176563, -0.295328, -0.765397, 0.571795, 0.285329, 0.950369, 0.124037, -0.791300, -0.609655, -0.046523, -0.474532, -0.026574, 0.879837, 0.158765, 0.521137, 0.838576, -0.608333, -0.220632, 0.762399, -0.763518, 0.146101, 0.629043, -0.627608, -0.555914, 0.545039, 0.673712, 0.733593, -0.089180, 0.322767, 0.940253, -0.108378, -0.058956, -0.072076, 0.995655, -0.042705, -0.788200, 0.613936, -0.534262, 0.556870, 0.635972, -0.664727, 0.362963, 0.652990, 0.819132, 0.543746, -0.182655, 0.159246, -0.087915, 0.983317, -0.888255, 0.033018, 0.458163, -0.366258, 0.184622, 0.912014, -0.520945, 0.853092, -0.029161, -0.724393, -0.347988, 0.595113, 0.005541, 0.900597, 0.434620, -0.273189, -0.051581, 0.960576, 0.413508, -0.755323, 0.508427, 0.781737, -0.541623, 0.309083, 0.520145, -0.236276, 0.820745, 0.950583, -0.298957, -0.083772, 0.050768, -0.299369, 0.952786, -0.348310, -0.874350, 0.337923, 0.152828, 0.812590, 0.562442, 0.314009, -0.640321, 0.700991, -0.090707, -0.995832, 0.009520, -0.833578, 0.283261, 0.474248, -0.064444, -0.486388, 0.871363, 0.536816, -0.573891, 0.618447, -0.181766, -0.282030, 0.942030, -0.235634, 0.378434, 0.895134, 0.243647, 0.327705, 0.912823, 0.824361, 0.015673, 0.565847, 0.742517, 0.595824, 0.306043, 0.425574, -0.452289, 0.783787, -0.496790, -0.867515, -0.024850, 0.905731, -0.405173, 0.124446, 0.871600, 0.454897, 0.182711, -0.690494, 0.720180, 0.067518, -0.195347, 0.847593, 0.493381, 0.878608, -0.326984, 0.348037, -0.719206, 0.504043, 0.478209, -0.872811, -0.221319, 0.434992, -0.795388, 0.599097, -0.091877, 0.001765, 0.354384, 0.935098, 0.540715, 0.023936, 0.840865, 0.316265, 0.118622, 0.941225}; static float ps126 [378] = { -0.275059, -0.708536, 0.649861, 0.861162, 0.171625, 0.478481, 0.712368, 0.166471, 0.681777, -0.575421, -0.444855, 0.686291, 0.058834, 0.133742, 0.989268, -0.374730, -0.808194, 0.454312, 0.310382, 0.161036, 0.936873, -0.114791, 0.639237, 0.760394, 0.314992, -0.227658, 0.921386, -0.543214, 0.237716, 0.805239, 0.094409, -0.287922, 0.952989, -0.329634, 0.650156, 0.684572, 0.558257, -0.427153, 0.711258, -0.463341, -0.158333, 0.871921, -0.586182, -0.724101, 0.363412, 0.690992, 0.536301, -0.484676, -0.131580, 0.902134, 0.410902, -0.135830, -0.837544, 0.529216, 0.902205, -0.417051, 0.109973, 0.725908, -0.170058, -0.666437, -0.658256, -0.746937, -0.093725, -0.479860, -0.877314, -0.007441, 0.293907, 0.870412, 0.394970, 0.780379, -0.604980, 0.158137, -0.134913, -0.331243, 0.933850, 0.537702, -0.818572, -0.202032, 0.511020, -0.248929, 0.822735, 0.717396, -0.441037, 0.539286, 0.049844, -0.496679, 0.866502, 0.860265, -0.078663, -0.503743, -0.179209, 0.088788, 0.979796, -0.871595, -0.363689, -0.328714, -0.331779, 0.941778, 0.054557, 0.923691, -0.027698, 0.382137, -0.763743, -0.084092, 0.640019, 0.804512, -0.032050, 0.593072, 0.977463, -0.206821, 0.042316, -0.345219, 0.794042, 0.500321, -0.278804, -0.956844, 0.081966, 0.695232, -0.718099, -0.031416, 0.088909, 0.949112, 0.302128, 0.385376, 0.373876, 0.843625, -0.091660, 0.305914, 0.947637, -0.406149, 0.060241, 0.911819, 0.173090, -0.644531, 0.744728, 0.636543, 0.758694, -0.138553, 0.483124, -0.780428, 0.396893, 0.439607, -0.027945, 0.897755, 0.183572, -0.957747, 0.221411, -0.752172, -0.327968, 0.571554, 0.710740, -0.654192, -0.258615, 0.746859, 0.529076, 0.402841, -0.344201, 0.892989, 0.289994, 0.333843, -0.738984, 0.585193, 0.099365, -0.807652, 0.581227, -0.927452, 0.210974, 0.308742, -0.130078, 0.970690, 0.202090, 0.198896, -0.044960, 0.978989, -0.874439, -0.174729, 0.452578, 0.581939, 0.381401, 0.718248, -0.127848, 0.790437, 0.599053, 0.390982, -0.566106, 0.725712, -0.543035, 0.732725, 0.410154, -0.060857, -0.983670, 0.169383, 0.993681, -0.039259, -0.105151, 0.016576, 0.495908, 0.868217, -0.442783, -0.866398, 0.230862, 0.952813, 0.180245, 0.244252, -0.387094, -0.541001, 0.746643, -0.988991, 0.012445, -0.147454, 0.549939, -0.620887, 0.558629, -0.394707, 0.896431, -0.201537, -0.810997, 0.315606, 0.492623, 0.528861, 0.179586, 0.829491, 0.285131, -0.432231, 0.855498, 0.950400, 0.013760, -0.310726, 0.425319, 0.574530, 0.699299, -0.328940, 0.272676, 0.904127, -0.950822, -0.219824, 0.218209, 0.261989, -0.871043, 0.415506, -0.164626, -0.335972, -0.927373, -0.052723, -0.691813, 0.720149, 0.019120, -0.922537, 0.385434, -0.176245, -0.530868, 0.828925, 0.093366, 0.705291, 0.702743, -0.805709, -0.564281, -0.180057, 0.475605, 0.739590, 0.476243, -0.611612, 0.009638, 0.791099, -0.238093, 0.472091, 0.848788, -0.029496, -0.098546, 0.994695, 0.292786, 0.942650, 0.160271, -0.833775, 0.438073, -0.336022, 0.702138, -0.538906, -0.465385, 0.229909, 0.549551, 0.803204, 0.635388, -0.038045, 0.771255, 0.839551, -0.450848, -0.303136, -0.518679, 0.854763, -0.018768, 0.687001, -0.621052, 0.377259, -0.919811, -0.381132, -0.093202, 0.702328, -0.237180, 0.671179, 0.599708, 0.566924, 0.564754, 0.478567, 0.843356, 0.244387, -0.748916, -0.357900, -0.557703, -0.847034, -0.392657, 0.358266, -0.983926, -0.178572, 0.000901, 0.090024, 0.852093, 0.515590, -0.620446, -0.239363, 0.746828, -0.453259, 0.451643, 0.768489, 0.836113, -0.542605, -0.080590, -0.253703, -0.137845, 0.957410, -0.368180, -0.354231, 0.859630, 0.089163, 0.993505, 0.070690, 0.841887, -0.240256, 0.483221, 0.224214, 0.920531, -0.319922, 0.612053, -0.763212, 0.207121, -0.898529, -0.419987, 0.127501, -0.638809, -0.700629, -0.317872, -0.934496, 0.231267, -0.270617, 0.291828, 0.740056, 0.605932, -0.649770, 0.395074, 0.649396, 0.934690, -0.331690, -0.127809, -0.761836, -0.590455, 0.266401, -0.527748, 0.603430, 0.597791, 0.797028, 0.602659, -0.039348, -0.126343, 0.991803, -0.019079, -0.504023, -0.649234, 0.569611}; static float ps127 [381] = { -0.215903, -0.611411, 0.761290, -0.713941, 0.472645, 0.516618, -0.209880, -0.939078, -0.272182, 0.179240, -0.770564, 0.611640, -0.551908, 0.499856, 0.667489, -0.018775, 0.553810, 0.832431, -0.842142, -0.417740, 0.341014, -0.510498, -0.859651, 0.019828, -0.172029, 0.071741, 0.982476, -0.811534, 0.253677, 0.526365, 0.177020, 0.017140, 0.984058, -0.865946, 0.026610, 0.499429, -0.353892, -0.915534, 0.191203, 0.720778, -0.086452, -0.687754, -0.014822, -0.092611, 0.995592, 0.925587, -0.347473, -0.150172, 0.440068, 0.547061, 0.712085, -0.400144, -0.467179, 0.788434, -0.386416, -0.009741, 0.922273, 0.748688, 0.271401, 0.604820, 0.214190, 0.572017, 0.791782, 0.883546, 0.407172, 0.231424, 0.939607, -0.211319, 0.269227, 0.992697, -0.036792, 0.114889, -0.100126, 0.844152, 0.526670, 0.924298, -0.188864, -0.331667, -0.326549, 0.781108, 0.532200, -0.653165, 0.299446, 0.695491, 0.027962, 0.183822, 0.982562, 0.934910, 0.354651, 0.012924, -0.186472, -0.798532, 0.572341, 0.412144, -0.898614, -0.150433, 0.062964, 0.730213, 0.680312, 0.417317, -0.265985, 0.868964, -0.260124, 0.900916, 0.347399, 0.719973, 0.635941, -0.277882, 0.732438, 0.598945, 0.323729, 0.128067, 0.388895, 0.912337, 0.100207, -0.992588, 0.068756, 0.495914, 0.679225, 0.541038, 0.209595, -0.416266, 0.884756, -0.114059, 0.345112, 0.931605, -0.442235, 0.373703, 0.815337, 0.568544, 0.743165, 0.352794, 0.991400, 0.120355, -0.051383, -0.939334, -0.273147, 0.207464, 0.701287, -0.568957, 0.429516, 0.390817, -0.026796, 0.920078, -0.694992, 0.632011, 0.342853, 0.812239, 0.575343, 0.096168, 0.014006, -0.959342, 0.281898, 0.960125, -0.272062, 0.064361, 0.858907, -0.181675, 0.478825, -0.809883, 0.565578, 0.155601, -0.584096, -0.079152, 0.807816, 0.498187, 0.168374, 0.850565, 0.392063, -0.668090, 0.632410, -0.296804, -0.953752, -0.047580, -0.158383, 0.694466, 0.701877, -0.220628, -0.176807, 0.959199, -0.314263, 0.229785, 0.921107, -0.625553, 0.761519, 0.169623, -0.752856, -0.129939, 0.645232, -0.247493, 0.493020, 0.834073, 0.283669, 0.726094, 0.626354, 0.986893, -0.114278, -0.113943, -0.525926, 0.721226, -0.450816, -0.210954, -0.401192, 0.891371, -0.418722, -0.246766, 0.873944, 0.599494, -0.325089, 0.731386, -0.543664, 0.838438, -0.038096, -0.557912, -0.520126, 0.646686, 0.596040, 0.306538, -0.742140, -0.440304, -0.873804, -0.206394, 0.878997, -0.473807, 0.053595, -0.143106, -0.982790, 0.116807, 0.444132, -0.858920, 0.254956, 0.351179, 0.834806, 0.423995, -0.377405, -0.824484, 0.421653, 0.648078, 0.748078, 0.142741, 0.734075, -0.143406, 0.663753, -0.631892, 0.736491, -0.241442, 0.280773, 0.207251, 0.937130, -0.370212, 0.620369, 0.691438, -0.549343, -0.799106, 0.244235, 0.316429, -0.832121, 0.455463, 0.581325, 0.351130, 0.734009, -0.009530, -0.529623, 0.848180, -0.747501, -0.339103, 0.571184, -0.531181, 0.150348, 0.833812, 0.728267, -0.684975, 0.020891, 0.840213, -0.419538, -0.343556, 0.748843, -0.370093, 0.549786, -0.541681, 0.667494, 0.510915, 0.032745, -0.872632, 0.487280, 0.675836, 0.096309, 0.730733, -0.020797, -0.715264, 0.698545, -0.877375, -0.199206, 0.436498, -0.641772, -0.515468, -0.567822, 0.199802, -0.607789, 0.768552, -0.327388, 0.942880, -0.061590, -0.787595, 0.576112, -0.218606, 0.184513, -0.972305, -0.143446, -0.184879, -0.913081, 0.363461, 0.965312, 0.189011, 0.180130, 0.411214, -0.478924, 0.775587, 0.855245, -0.399010, 0.330675, -0.025397, 0.945559, 0.324459, 0.573466, -0.092225, 0.814021, 0.551453, 0.695768, -0.460224, 0.128355, 0.862368, 0.489741, 0.225926, -0.932340, 0.282311, -0.057543, -0.992650, -0.106461, 0.368198, 0.386577, 0.845570, -0.382823, -0.679179, 0.626229, 0.849803, 0.511969, -0.125389, 0.701522, 0.530706, -0.475624, -0.700616, -0.710102, 0.069947, -0.938265, -0.008419, -0.345816, 0.828982, 0.047301, 0.557271, 0.792041, 0.422728, 0.440423, 0.887897, 0.221368, 0.403280, 0.211535, -0.204171, 0.955807, -0.957935, -0.043490, 0.283670, -0.483043, 0.804663, 0.345235, -0.002843, -0.317772, 0.948163, 0.579728, -0.531037, 0.617993}; static float ps128 [384] = { 0.680572, 0.430595, 0.592798, -0.369574, -0.196648, 0.908155, -0.717697, -0.695887, -0.025539, -0.208498, 0.926839, 0.312248, 0.813695, 0.430095, 0.391048, -0.954180, 0.051360, 0.294793, -0.202543, -0.627574, 0.751750, -0.625803, 0.549378, 0.553674, 0.062421, 0.489628, -0.869694, 0.247721, 0.877274, -0.411127, 0.912471, 0.376545, 0.160032, 0.338715, 0.720555, 0.605039, -0.071143, 0.750842, 0.656639, -0.019123, 0.118879, 0.992725, 0.524454, 0.590472, 0.613426, -0.583159, 0.784487, -0.210962, 0.529833, -0.273453, 0.802808, -0.915542, -0.232294, -0.328362, -0.940251, -0.186441, 0.284900, 0.795706, 0.248099, 0.552539, 0.472566, 0.146590, 0.869019, 0.263397, -0.670869, 0.693222, 0.681861, -0.561698, 0.468575, -0.616910, 0.693781, 0.371603, 0.525604, 0.384741, 0.758759, -0.734033, 0.629134, -0.255707, 0.882684, 0.058417, 0.466321, 0.991184, -0.110551, 0.073023, -0.451282, 0.524873, 0.721702, 0.772414, 0.606499, -0.188506, 0.017165, 0.967040, 0.254047, -0.640781, -0.681813, 0.352888, 0.175655, 0.963381, -0.202591, 0.333106, -0.795409, 0.506325, -0.601535, 0.365282, 0.710439, -0.791113, -0.573901, -0.211609, 0.003979, -0.098336, 0.995145, 0.317228, -0.317101, 0.893764, -0.333633, -0.733596, 0.592053, -0.030191, -0.917793, 0.395911, 0.627048, 0.741689, 0.238135, -0.606944, 0.039290, -0.793773, -0.954982, -0.288682, 0.068353, -0.527178, -0.848796, -0.040354, -0.292444, -0.421367, 0.858444, 0.255943, 0.876374, 0.407998, -0.148291, -0.271309, 0.951000, -0.597134, -0.786054, 0.159841, 0.420903, -0.086303, 0.902991, -0.112042, -0.795511, 0.595491, -0.270808, 0.957094, -0.103120, 0.713192, -0.221118, 0.665180, 0.936626, -0.343297, 0.069854, 0.762574, 0.010710, 0.646812, 0.224246, 0.953248, 0.202565, -0.617331, 0.434827, -0.655613, -0.270596, 0.655515, 0.705037, 0.341112, 0.328527, 0.880746, 0.668486, 0.610090, 0.425343, -0.994254, -0.048290, 0.095533, -0.968921, 0.211637, 0.128074, -0.742441, -0.026887, 0.669372, 0.790561, -0.370423, 0.487647, 0.482375, 0.760003, 0.435557, -0.135845, 0.987667, 0.077848, -0.827873, -0.304387, 0.471141, 0.398743, 0.895103, -0.199484, 0.140518, 0.474415, 0.869014, -0.733702, 0.193367, 0.651376, -0.750004, -0.504733, 0.427479, -0.542773, -0.633672, 0.551233, 0.348531, 0.540102, 0.766039, 0.140821, 0.656711, 0.740878, -0.073006, 0.573515, 0.815935, -0.877387, -0.408459, 0.251700, 0.082236, -0.325695, 0.941892, -0.778807, 0.518443, 0.353094, 0.113182, -0.816239, 0.566519, -0.584789, 0.123165, 0.801780, 0.390551, -0.876209, 0.282360, -0.710150, -0.242419, 0.660999, -0.567219, 0.805197, 0.172976, -0.749869, 0.639254, 0.170443, -0.408482, 0.485241, -0.773100, 0.684170, -0.729047, 0.020033, -0.135517, -0.808686, -0.572417, -0.271312, 0.451202, 0.850181, -0.865263, 0.138739, 0.481738, -0.431830, 0.292560, 0.853189, -0.851333, 0.444939, -0.277959, 0.514445, 0.337784, -0.788193, -0.537805, 0.730107, -0.421556, 0.055372, -0.983741, 0.170841, 0.256297, 0.089453, 0.962450, 0.482429, -0.625386, 0.613315, -0.450480, 0.701835, 0.551811, -0.570078, -0.113018, 0.813780, 0.321847, 0.946791, 0.001522, -0.423381, 0.832822, 0.356588, -0.085848, -0.996220, -0.013243, 0.178746, -0.512357, 0.839965, 0.859230, -0.161831, 0.485319, 0.134262, 0.267120, 0.954264, 0.652121, 0.200881, 0.731017, -0.424988, -0.544568, 0.723071, 0.430432, 0.869577, 0.242000, -0.982618, -0.147763, -0.112372, -0.353841, 0.924567, 0.141322, -0.641860, -0.446805, 0.623202, -0.238193, 0.208160, 0.948648, -0.832223, 0.551727, -0.054787, 0.961865, -0.013127, 0.273209, 0.863888, 0.503458, -0.015056, 0.211682, -0.125492, 0.969249, 0.478825, -0.877195, 0.035442, -0.025000, 0.890822, 0.453664, 0.929556, -0.238003, 0.281568, 0.868590, 0.087872, -0.487677, -0.885296, 0.442664, 0.142478, -0.073772, 0.363454, 0.928687, -0.186877, 0.916613, -0.353410, -0.769714, 0.371480, 0.519175, -0.211412, -0.032449, 0.976858, -0.454821, -0.798266, 0.394854, -0.895252, 0.303884, 0.325852, -0.409280, 0.045477, 0.911275, -0.248460, 0.817522, 0.519544, 0.030867, -0.670979, 0.740833}; static float ps129 [387] = { -0.667184, -0.218186, 0.712222, 0.281627, 0.113713, 0.952762, -0.026093, -0.796221, 0.604443, 0.793408, -0.328088, 0.512700, -0.950696, -0.242747, 0.193003, -0.294903, -0.147566, 0.944064, -0.829220, 0.554163, 0.072784, -0.387689, -0.565681, 0.727807, 0.221423, 0.789965, 0.571775, -0.560354, 0.572586, 0.598456, 0.370265, 0.625746, 0.686546, 0.813755, -0.097384, 0.572992, -0.941026, 0.325068, 0.093817, 0.782414, 0.136256, 0.607670, -0.853940, -0.354592, 0.380857, 0.065375, 0.976883, 0.203532, 0.337925, -0.119855, 0.933510, 0.980758, -0.008495, 0.195041, 0.285900, 0.948829, 0.134108, 0.494366, 0.046604, 0.868003, 0.507070, 0.430392, 0.746755, -0.753262, 0.151337, 0.640073, -0.124946, -0.326376, 0.936946, -0.936276, 0.208896, 0.282399, -0.012033, -0.918040, 0.396304, -0.222926, -0.845719, 0.484833, -0.089678, 0.618988, 0.780264, 0.521247, -0.193817, 0.831105, 0.610452, 0.767763, 0.194650, 0.505878, -0.860778, 0.056122, -0.491822, -0.186695, 0.850445, 0.010752, 0.134734, 0.990824, -0.724271, 0.523579, 0.448661, 0.133117, -0.049738, 0.989852, 0.160390, 0.301141, 0.939994, -0.350303, 0.929794, 0.113006, -0.047620, 0.982835, -0.178233, -0.578206, -0.716567, 0.390140, -0.733090, -0.542374, 0.410377, 0.951774, 0.208360, 0.225193, 0.312560, -0.336565, 0.888274, 0.674683, -0.265509, 0.688700, -0.897283, 0.430505, -0.097719, -0.635259, -0.000215, 0.772299, -0.895794, -0.149704, 0.418500, -0.408989, 0.743394, 0.529239, 0.577341, 0.566754, 0.587765, 0.754259, 0.493900, 0.432616, 0.624948, -0.743813, 0.237028, 0.007963, 0.786631, 0.617372, 0.447237, -0.615613, 0.648845, -0.202982, 0.866062, 0.456875, -0.343399, -0.371919, 0.862411, 0.739630, -0.545810, 0.393749, 0.290721, -0.951314, 0.102388, -0.168296, -0.528075, 0.832354, -0.343484, -0.932591, 0.110875, -0.355628, 0.262945, 0.896877, 0.779717, -0.600878, 0.176034, -0.207178, 0.740948, 0.638806, 0.702087, 0.361125, 0.613728, -0.413828, -0.724978, 0.550593, -0.795344, -0.086228, 0.599993, 0.225200, -0.922360, 0.313906, -0.552820, -0.814394, 0.176500, 0.871002, -0.380421, 0.310861, 0.557835, -0.812038, -0.171505, -0.358243, 0.597709, 0.717221, 0.226555, -0.703367, 0.673756, -0.479659, 0.418068, 0.771457, 0.034988, 0.471117, 0.881377, -0.586071, -0.563308, 0.582413, -0.221884, 0.088076, 0.971087, -0.393720, 0.859694, 0.325440, 0.105244, -0.266721, 0.958010, 0.672256, -0.027104, 0.739822, -0.544071, -0.402581, 0.736149, -0.730106, -0.649393, 0.212681, 0.939438, 0.342134, 0.020020, 0.068022, -0.467514, 0.881365, 0.613498, 0.680844, 0.400090, -0.408210, -0.276369, -0.870049, 0.993101, 0.117237, -0.002312, -0.487501, -0.872069, -0.042876, -0.865246, -0.465372, 0.186491, -0.439169, 0.042175, 0.897414, -0.125477, -0.991736, 0.026742, 0.431392, 0.853114, 0.293423, -0.673946, 0.372347, 0.638087, -0.964564, 0.221149, -0.143911, -0.393847, -0.855024, 0.337371, -0.722498, 0.648862, 0.238695, 0.877915, 0.416894, 0.235510, 0.763301, 0.606490, 0.222581, 0.145507, 0.644211, 0.750880, -0.165508, 0.952797, 0.254529, -0.884790, 0.080046, 0.459064, -0.581035, 0.712256, 0.393815, 0.171655, -0.841721, 0.511899, 0.023099, -0.646172, 0.762842, -0.835829, -0.548732, -0.016817, -0.183496, -0.947863, 0.260547, 0.017019, 0.906084, 0.422756, -0.825348, 0.309102, 0.472501, -0.689992, -0.723769, 0.008301, 0.614607, 0.210072, 0.760347, -0.115700, 0.307231, 0.944575, -0.687446, 0.726235, 0.000883, 0.493143, -0.417080, 0.763449, 0.110456, -0.993051, -0.040620, 0.637800, -0.488348, 0.595590, -0.084220, -0.101178, 0.991297, -0.913877, 0.160914, -0.372741, 0.230944, 0.900178, 0.369248, -0.571969, 0.215106, 0.791569, -0.240818, 0.462954, 0.853042, 0.852985, 0.285469, 0.436948, 0.384180, -0.781834, 0.491061, -0.739389, -0.360608, 0.568565, -0.274840, 0.533018, -0.800222, -0.853534, 0.440311, 0.278579, -0.993273, 0.103751, 0.051431, -0.213901, -0.700400, 0.680945, 0.575306, -0.681226, 0.452718, 0.438597, -0.853435, 0.281570, 0.425822, 0.754128, 0.499966, -0.970255, -0.018338, 0.241390, 0.280395, 0.471936, 0.835856, 0.906805, 0.064202, 0.416632}; static float ps130 [390] = { 0.776960, 0.156761, 0.609721, -0.689703, -0.534667, 0.488304, 0.251783, 0.790779, 0.557919, -0.028613, 0.578419, 0.815238, 0.952520, 0.136821, 0.272004, -0.780406, 0.418162, 0.464873, 0.140386, -0.573782, 0.806887, 0.682564, -0.291601, 0.670131, -0.747007, -0.662685, 0.053189, -0.505280, -0.616725, 0.603608, -0.912390, 0.272626, 0.305318, -0.107395, 0.385920, 0.916260, 0.838974, -0.204691, 0.504207, 0.638897, 0.296906, 0.709688, 0.857430, 0.274017, 0.435578, 0.353900, -0.177517, 0.918282, -0.414429, 0.644795, 0.642252, 0.747890, -0.069688, 0.660155, 0.970961, 0.231452, 0.060528, 0.125939, -0.212152, 0.969088, -0.940017, 0.045091, 0.338136, -0.199074, -0.484159, 0.852032, -0.535160, 0.814775, 0.223039, -0.841397, 0.194038, 0.504381, -0.586170, 0.004538, 0.810175, 0.949148, -0.102942, 0.297524, 0.886632, -0.328356, 0.325679, -0.551677, 0.235572, 0.800099, -0.984320, 0.131740, 0.117296, -0.315573, -0.306368, 0.898083, -0.432856, -0.900713, 0.036757, -0.572090, 0.820029, -0.016284, -0.222621, -0.058008, 0.973178, 0.626661, 0.719344, 0.299734, -0.191759, 0.693992, 0.693977, -0.191172, 0.977835, -0.085394, -0.228583, -0.963383, 0.140154, 0.598808, 0.618585, 0.508705, -0.613026, 0.551071, 0.566144, -0.836155, -0.405775, 0.369040, 0.276784, 0.902963, 0.328708, -0.832830, 0.488017, 0.261215, -0.316056, 0.805724, 0.500916, -0.688601, 0.629772, 0.359466, -0.549616, -0.731774, 0.403025, 0.021998, -0.896986, 0.441511, 0.265003, -0.693593, 0.669852, 0.586421, -0.499388, 0.637748, 0.755448, -0.430664, 0.493788, -0.729802, 0.106052, 0.675382, -0.360263, -0.786424, 0.501745, 0.257245, -0.385126, 0.886286, -0.257815, -0.961472, -0.095405, 0.529548, 0.487270, 0.694368, 0.466782, 0.264429, 0.843915, 0.514020, -0.737083, -0.438740, -0.400605, -0.873447, 0.276778, 0.378390, -0.923459, -0.063591, 0.894624, 0.374483, 0.243741, 0.632207, -0.637163, 0.440837, -0.705744, -0.145776, 0.693308, -0.631768, -0.409718, 0.658028, 0.883431, 0.023830, 0.467955, -0.968093, 0.225533, -0.109231, 0.985929, 0.087524, -0.142421, 0.769034, 0.525767, 0.363533, 0.242972, -0.833003, 0.497061, 0.057869, 0.741393, 0.668571, 0.067298, 0.972480, 0.223054, 0.218074, -0.929106, 0.298674, 0.566745, -0.135109, 0.812739, -0.586269, -0.792338, 0.168785, 0.087889, 0.891474, 0.444465, 0.212752, 0.012680, 0.977024, -0.074117, -0.640574, 0.764311, -0.914322, -0.183567, 0.360997, 0.049753, 0.209251, 0.976596, 0.734149, -0.670741, 0.105510, 0.207747, 0.612908, 0.762355, -0.844203, -0.045247, 0.534110, -0.104735, -0.249175, 0.962779, -0.426914, -0.473261, 0.770564, 0.891050, 0.452185, 0.039494, -0.172246, 0.170294, 0.970222, -0.339041, 0.327617, 0.881883, 0.598681, -0.761071, 0.249702, -0.129561, 0.928885, 0.346968, -0.342851, 0.893081, 0.291307, -0.195445, -0.908743, 0.368764, 0.266075, 0.238123, 0.934078, 0.424161, 0.042683, 0.904580, -0.939969, -0.301153, 0.160513, -0.492610, 0.452194, 0.743543, -0.996568, -0.002719, -0.082733, -0.847710, -0.502160, 0.170951, -0.008008, -0.973805, 0.227244, 0.488138, -0.341126, 0.803340, -0.390406, 0.112189, 0.913782, 0.124799, 0.424134, 0.896959, -0.271737, 0.524077, 0.807157, -0.296378, -0.652665, 0.697272, 0.016400, -0.423408, 0.905791, -0.101651, 0.831696, 0.545847, 0.886201, -0.442896, 0.135982, -0.422735, -0.114155, 0.899035, 0.618247, 0.080435, 0.781857, 0.057445, -0.768604, 0.637140, -0.154667, -0.799722, 0.580106, 0.455146, 0.866641, 0.204392, 0.613752, 0.785997, 0.074287, 0.448426, 0.781212, 0.434306, -0.006221, -0.018435, 0.999811, 0.433222, -0.816678, 0.381255, 0.723401, 0.419981, 0.548003, -0.160093, 0.978124, 0.132828, 0.776998, 0.608469, 0.161365, 0.399862, 0.653911, 0.642270, 0.776832, -0.555179, 0.297168, 0.344653, 0.452009, 0.822741, -0.684219, 0.335525, 0.647508, 0.386490, -0.529360, 0.755251, 0.409058, -0.897532, 0.164646, -0.542780, -0.267279, 0.796211, -0.700793, 0.698941, 0.142726, -0.788665, -0.284902, 0.544828, -0.833546, 0.550228, 0.049497, 0.038127, 0.999268, -0.003096, -0.933749, 0.347444, 0.085997, -0.715084, -0.635697, 0.290765, 0.459418, -0.684522, 0.566008}; static float ps131 [393] = { -0.480577, -0.092817, 0.872027, 0.665642, 0.416231, 0.619413, -0.343972, -0.636355, 0.690460, 0.804387, -0.454237, -0.382924, 0.113393, 0.419368, 0.900707, -0.734984, 0.636884, 0.232760, 0.064044, 0.923713, 0.377693, 0.889469, 0.428182, 0.159703, 0.089989, -0.276293, 0.956851, 0.647022, 0.586655, 0.487030, 0.446565, -0.773800, 0.449237, -0.113666, -0.973340, 0.199222, 0.268310, -0.882134, 0.387104, 0.446510, -0.512880, 0.733200, 0.057026, -0.996665, 0.058366, -0.547541, 0.769104, 0.329663, -0.794662, -0.531042, 0.294121, 0.498175, -0.082374, 0.863155, -0.278281, 0.746942, 0.603852, 0.233158, -0.969501, -0.075530, 0.959405, -0.238414, 0.150669, -0.131070, -0.758652, 0.638175, -0.603390, -0.792488, -0.088789, 0.486452, 0.145659, 0.861480, -0.520592, -0.306920, 0.796734, 0.636394, -0.418674, 0.647854, 0.907583, -0.172770, 0.382680, 0.783016, -0.583477, 0.215499, 0.968264, -0.069988, -0.239929, -0.643448, -0.693448, 0.324199, -0.046906, -0.880436, 0.471839, 0.266552, -0.950832, 0.157698, 0.451957, 0.847275, 0.279035, 0.449015, -0.893306, 0.019748, 0.464781, -0.852513, 0.239164, -0.109668, 0.857699, 0.502320, 0.631551, -0.696980, 0.339651, -0.748453, 0.070512, 0.659429, -0.654774, 0.611010, 0.444901, 0.638955, -0.760204, 0.117586, 0.637260, 0.710729, 0.297935, -0.058734, 0.690743, -0.720711, -0.129249, -0.378780, 0.916417, 0.486496, 0.380149, 0.786644, 0.646258, 0.229663, 0.727740, 0.733745, -0.514594, 0.443634, -0.668737, 0.450420, 0.591534, -0.660361, -0.114215, 0.742212, 0.473638, 0.736965, 0.482234, 0.302141, 0.057575, 0.951523, 0.079837, -0.949774, 0.302581, 0.282298, -0.385940, 0.878270, -0.325398, 0.186446, 0.927013, 0.406646, 0.911345, 0.063946, 0.609548, -0.785456, -0.107282, 0.110710, 0.193030, 0.974927, -0.292765, -0.020465, 0.955965, -0.543427, -0.829510, 0.128843, 0.182226, 0.983067, 0.019299, 0.670304, 0.010703, 0.742010, -0.907924, -0.339084, 0.246368, 0.100257, -0.044116, 0.993983, -0.097788, 0.087342, 0.991367, -0.077461, 0.526309, 0.846758, -0.077748, 0.710074, 0.699822, -0.320476, -0.786671, 0.527678, 0.668103, -0.208147, 0.714362, -0.813045, -0.134947, 0.566346, 0.101200, 0.803144, 0.587127, 0.793479, -0.306097, 0.526018, -0.692355, -0.327404, 0.643001, 0.796368, 0.159465, 0.583412, -0.945461, -0.324733, 0.025526, -0.093584, 0.305425, 0.947606, 0.973538, -0.022293, 0.227435, 0.059263, -0.490668, 0.869329, -0.339981, -0.927843, 0.153364, -0.288008, 0.589835, 0.754418, -0.806762, 0.267990, 0.526608, 0.486382, 0.574017, 0.658739, -0.521329, -0.674580, 0.522645, -0.884755, 0.067829, 0.461094, -0.535562, -0.502564, 0.678677, -0.236612, -0.901108, 0.363344, 0.241372, 0.941758, 0.234163, 0.919123, 0.256910, 0.298681, -0.174162, 0.939128, 0.296153, -0.315375, -0.249809, 0.915497, -0.142310, -0.585127, 0.798357, 0.812833, 0.348210, 0.466961, 0.486943, -0.303174, 0.819129, -0.104016, -0.153789, 0.982614, 0.872154, -0.461975, -0.161018, 0.777729, -0.628500, -0.011210, 0.307392, 0.293996, 0.905028, 0.301204, -0.169700, 0.938338, 0.869543, -0.387898, 0.305663, -0.547138, 0.103500, 0.830619, 0.768194, 0.629022, 0.119202, 0.960495, -0.264846, -0.085477, -0.655927, 0.263980, 0.707159, -0.981777, -0.130795, 0.137861, 0.556746, -0.614246, 0.559228, 0.895038, -0.440607, 0.069088, -0.981350, -0.158465, -0.108820, -0.475771, 0.323338, 0.817982, 0.301294, 0.705714, 0.641241, 0.305209, 0.514861, 0.801103, -0.998387, 0.056683, 0.003183, 0.906140, 0.070495, 0.417063, 0.278195, 0.850420, 0.446535, -0.479977, 0.679042, 0.555449, 0.788050, 0.520045, 0.329439, -0.004506, -0.986418, -0.164190, -0.823254, -0.340206, 0.454437, 0.143655, -0.816939, 0.558547, -0.690349, -0.522322, 0.500597, -0.851425, -0.519606, 0.071302, -0.489902, 0.512363, 0.705323, -0.910438, 0.269317, 0.313960, 0.812955, -0.077868, 0.577097, -0.457624, -0.821699, 0.339692, 0.330471, -0.710023, 0.621817, 0.240944, -0.583904, 0.775244, -0.345929, 0.841520, 0.414943, 0.120071, 0.630174, 0.767114, -0.277355, 0.404524, 0.871456, 0.715688, 0.690393, -0.105583, -0.921928, -0.136671, 0.362449, 0.403666, -0.892603, -0.200785, -0.340447, -0.455559, 0.822534}; static float ps132 [396] = { -0.095450, -0.226704, 0.969275, 0.492696, -0.859472, 0.136228, -0.806069, -0.070207, 0.587642, -0.807236, -0.577833, 0.120329, -0.800708, 0.308696, 0.513394, -0.127387, 0.172737, 0.976696, 0.292944, -0.939365, 0.178259, 0.504156, 0.740376, 0.444601, 0.172478, 0.136439, 0.975518, 0.667320, 0.559298, 0.491802, -0.810418, 0.466847, 0.353945, -0.777356, 0.603650, 0.176988, 0.999948, -0.002223, 0.009914, -0.315757, -0.940110, -0.128413, 0.661031, -0.224285, 0.716055, 0.149054, -0.831770, 0.534734, 0.511574, -0.787082, 0.344666, -0.646810, -0.757650, -0.087198, 0.481768, -0.378095, 0.790534, 0.683998, -0.666404, 0.296736, -0.185822, -0.623644, 0.759301, 0.582885, -0.632608, 0.509953, 0.381108, -0.741891, 0.551683, -0.367571, 0.144602, 0.918685, 0.075359, -0.992835, 0.092736, -0.500468, 0.697996, 0.512185, -0.690491, -0.266263, 0.672552, -0.718229, -0.454802, 0.526595, 0.794593, 0.346931, 0.498259, 0.440980, 0.433175, 0.786064, -0.274968, -0.892239, 0.358193, 0.296383, 0.609094, 0.735637, 0.122921, -0.177697, 0.976378, 0.294171, -0.046986, 0.954597, -0.112335, 0.664265, 0.739008, 0.465722, 0.063812, 0.882628, 0.795745, -0.275792, 0.539192, 0.647897, 0.004296, 0.761715, 0.924413, -0.369404, 0.094878, 0.492649, 0.601825, 0.628572, 0.971248, -0.159819, 0.176452, 0.898599, -0.419121, -0.129838, 0.101470, -0.940938, 0.323017, -0.019556, -0.751174, 0.659814, 0.634548, -0.439369, 0.635849, -0.499737, 0.538357, 0.678554, 0.306488, -0.289254, 0.906861, 0.037985, -0.584970, 0.810165, 0.213991, -0.682901, 0.698466, 0.670389, 0.679648, 0.297754, 0.268051, -0.500086, 0.823446, 0.910864, 0.272436, 0.310008, 0.315626, 0.875985, 0.364734, -0.743408, 0.134966, 0.655079, -0.794197, -0.599486, -0.099335, -0.089385, 0.924544, 0.370445, 0.350209, 0.246699, 0.903600, 0.083729, -0.392067, 0.916118, -0.884287, 0.101990, 0.455668, -0.070360, 0.986271, 0.149395, 0.125381, 0.957833, 0.258524, -0.314459, 0.701062, 0.640022, 0.223448, 0.419762, 0.879699, -0.657441, 0.663998, 0.356200, -0.044404, -0.309855, -0.949746, -0.476660, -0.844442, 0.244362, -0.354984, -0.457861, 0.815077, -0.900496, -0.413928, -0.133309, 0.491243, -0.159053, 0.856378, 0.825231, -0.511306, 0.239915, -0.569796, 0.147343, 0.808469, -0.104302, 0.815584, 0.569161, -0.287845, 0.923501, 0.253558, 0.751231, -0.483214, 0.449619, 0.908083, -0.103054, 0.405913, -0.658487, -0.741413, 0.129236, -0.233665, -0.038993, 0.971535, -0.461714, 0.350600, 0.814800, 0.102123, 0.745369, 0.658783, -0.433509, -0.773479, 0.462384, -0.105043, -0.967506, 0.229995, 0.568874, 0.238392, 0.787116, 0.973993, 0.168831, -0.151105, 0.812686, -0.581619, 0.035503, -0.974710, 0.213733, 0.065253, -0.391022, -0.635676, 0.665596, -0.140826, -0.437066, 0.888336, -0.667293, 0.739500, -0.088660, -0.635471, 0.761233, 0.129236, -0.086574, 0.470402, 0.878195, 0.312304, 0.763285, 0.565564, -0.915837, 0.266146, 0.300681, -0.828994, -0.272958, 0.488122, -0.487876, 0.816644, 0.308333, 0.124224, 0.992098, 0.017619, -0.234873, -0.780962, 0.578735, -0.301842, 0.531161, 0.791682, 0.795858, -0.054238, 0.603050, -0.513386, -0.265006, 0.816215, 0.741576, 0.181210, 0.645932, -0.893287, -0.342378, 0.291231, 0.889633, -0.314235, 0.331376, 0.807160, 0.494409, 0.322571, 0.484530, 0.874673, -0.013347, -0.305815, 0.834597, 0.458176, 0.966656, 0.056228, 0.249829, 0.111744, 0.873341, 0.474119, -0.454266, -0.059580, 0.888872, 0.636234, 0.406810, 0.655524, -0.463178, 0.882460, 0.082037, 0.088982, 0.577764, 0.811339, -0.922542, -0.108289, 0.370390, -0.265669, 0.963425, 0.035096, 0.974631, 0.209673, 0.078308, -0.644937, 0.343142, 0.682869, -0.550973, -0.456704, 0.698463, 0.917233, 0.389814, -0.082026, 0.439773, -0.575647, 0.689370, -0.671677, 0.516012, 0.531584, -0.254164, 0.336456, 0.906751, -0.781377, -0.529422, 0.330396, -0.634405, -0.694862, 0.338669, -0.310947, -0.255063, 0.915563, 0.972484, -0.055356, -0.226299, 0.312796, -0.869573, 0.382100, -0.301900, -0.945532, 0.121759, 0.875257, 0.117787, 0.469096, -0.576268, -0.617966, 0.534821, -0.069179, -0.883944, 0.462447, 0.000000, -0.000000, 1.000000, -0.646236, -0.061119, 0.760686, 0.493887, 0.837653, 0.233266}; static float ps133 [399] = { -0.013833, -0.801492, 0.597846, -0.438776, -0.613095, 0.656955, 0.245728, -0.349300, 0.904216, -0.930602, -0.365851, -0.011508, -0.619187, -0.418317, 0.664544, -0.869659, -0.455680, 0.189865, -0.616318, -0.590665, 0.520833, -0.446550, 0.313484, 0.838046, -0.374945, -0.107657, 0.920775, 0.197254, -0.087492, 0.976440, -0.243913, -0.546616, 0.801073, 0.203163, 0.857873, -0.471994, -0.947713, -0.063155, 0.312812, -0.492359, -0.865761, -0.089671, 0.299073, 0.669573, 0.679873, -0.889164, -0.298553, 0.346776, 0.189636, 0.148141, 0.970614, -0.761752, -0.534701, 0.365826, 0.562364, 0.774975, 0.288376, 0.158621, 0.927309, 0.339024, 0.667628, 0.743278, 0.042543, 0.171620, 0.368581, 0.913616, -0.089979, -0.416354, 0.904739, 0.856160, -0.459066, 0.237168, 0.248305, -0.918386, 0.308079, 0.322308, -0.536251, 0.780098, -0.459248, 0.840302, 0.288068, -0.416750, -0.760517, 0.497929, 0.718804, -0.011490, 0.695118, -0.149502, -0.168031, 0.974379, 0.417631, -0.808389, 0.414839, -0.169001, -0.946554, 0.274725, 0.634752, 0.621720, 0.458862, 0.286683, -0.942327, -0.172723, 0.390663, 0.050938, 0.919124, 0.469788, -0.352882, 0.809181, 0.447638, 0.738902, 0.503631, -0.988870, 0.058120, -0.136958, 0.851728, 0.042846, 0.522229, -0.002135, 0.875346, 0.483492, 0.381923, -0.176907, 0.907105, 0.372733, 0.869354, 0.324492, 0.855616, 0.484017, 0.183436, -0.293349, -0.947929, -0.124001, 0.952217, -0.167786, -0.255208, 0.760424, -0.632265, 0.148312, -0.858865, 0.326496, 0.394654, -0.758358, 0.022810, 0.651439, 0.413076, -0.760554, -0.500926, -0.233587, -0.723550, 0.649548, 0.638153, -0.751173, -0.168820, 0.896484, -0.442546, 0.021669, 0.786522, -0.613090, -0.074185, 0.547474, 0.362573, 0.754197, -0.777650, 0.559309, 0.287115, -0.771703, -0.369366, 0.517730, -0.590081, -0.032880, 0.806674, 0.609566, -0.737028, 0.291923, 0.064987, -0.979604, 0.190136, 0.053408, -0.258382, 0.964565, 0.921095, 0.291621, 0.257957, -0.526510, -0.241613, 0.815114, 0.945120, -0.265137, 0.190919, 0.569958, 0.142061, 0.809300, 0.457165, -0.868429, 0.191914, 0.234641, 0.819843, 0.522303, 0.945192, 0.084459, 0.315403, 0.164339, -0.691043, 0.703883, 0.686373, 0.427463, 0.588360, -0.707806, -0.201726, 0.676991, 0.130103, 0.572870, 0.809255, 0.701558, -0.429008, 0.569007, 0.616827, -0.689354, -0.379889, -0.252216, 0.482743, 0.838657, -0.348836, -0.932168, 0.096834, 0.842851, -0.337369, 0.419267, -0.628292, 0.390771, 0.672716, 0.071062, 0.744921, 0.663357, 0.000000, 0.000000, 1.000000, -0.215141, 0.059901, 0.974744, -0.555319, 0.603604, 0.572087, -0.849480, -0.138985, 0.508986, -0.466549, 0.882784, 0.054994, -0.254125, 0.877694, 0.406294, -0.585013, -0.731620, 0.349989, -0.094278, 0.633374, 0.768081, 0.919409, -0.128348, 0.371772, -0.964166, -0.218863, 0.149946, -0.042317, 0.439112, 0.897435, -0.289233, 0.953879, -0.080363, 0.373070, -0.694380, 0.615350, -0.427609, 0.106403, 0.897680, -0.387549, -0.869131, 0.307274, 0.566585, -0.651638, 0.504331, 0.104179, -0.508489, 0.854743, 0.730449, -0.562191, 0.387795, 0.077065, 0.986498, 0.144512, 0.724810, 0.646143, 0.239060, -0.110219, 0.993321, 0.034130, 0.799693, -0.183204, 0.571776, 0.528246, -0.515267, 0.674874, 0.791119, 0.466065, 0.396124, -0.436720, -0.438399, 0.785546, -0.995695, 0.005229, 0.092547, 0.506834, 0.566848, 0.649464, 0.562470, -0.093330, 0.821533, -0.881501, 0.092396, 0.463053, -0.162386, 0.786560, 0.595780, -0.293284, -0.319208, 0.901161, 0.649232, -0.267907, 0.711845, 0.206709, -0.829645, 0.518614, 0.024075, -0.914801, 0.403186, -0.722970, -0.214547, -0.656722, -0.771644, 0.246611, 0.586301, -0.728270, 0.481224, 0.487900, 0.626820, -0.777199, 0.055296, 0.128009, 0.989513, -0.066915, -0.984425, -0.156364, -0.080356, -0.449416, 0.504878, 0.736969, 0.898230, -0.396061, -0.190576, 0.348232, 0.484047, 0.802766, 0.842650, 0.260598, 0.471200, -0.813341, -0.581726, 0.008434, 0.972861, -0.228593, -0.035868, 0.548861, 0.824187, -0.139524, -0.024370, 0.226494, 0.973708, -0.621869, 0.182041, 0.761669, -0.314173, 0.662752, 0.679747, 0.379345, 0.272966, 0.884074, -0.048736, -0.641802, 0.765320, -0.088973, 0.954041, 0.286164, -0.239616, 0.277898, 0.930245, -0.720241, -0.667980, 0.187231}; static float ps134 [402] = { 0.525053, -0.265196, 0.808697, 0.519761, -0.611767, -0.596314, 0.130884, 0.739045, 0.660819, 0.714835, 0.693771, 0.087710, -0.556259, -0.455018, 0.695367, 0.738033, -0.448285, 0.504328, 0.082141, -0.389038, 0.917552, -0.309743, 0.891864, -0.329603, 0.187040, -0.716672, 0.671861, 0.937505, -0.211744, 0.276132, 0.399529, -0.630131, 0.665817, -0.409394, -0.908484, 0.083986, 0.214994, -0.539443, 0.814113, -0.715928, 0.511211, 0.475511, -0.919134, -0.064221, 0.388674, -0.690920, 0.203655, 0.693653, -0.212922, -0.975505, 0.055262, 0.323735, 0.257956, 0.910305, -0.796655, 0.305565, 0.521508, -0.490128, -0.830528, 0.264571, -0.396320, 0.788284, 0.470679, 0.909757, 0.191001, 0.368593, -0.080613, -0.887964, 0.452793, -0.263236, 0.915964, 0.302848, -0.148487, 0.982360, 0.113672, 0.045863, 0.862090, 0.504676, 0.875186, -0.476257, -0.085028, -0.337515, -0.483599, 0.807599, 0.093978, -0.950808, 0.295181, 0.143926, -0.855052, 0.498168, 0.952609, -0.270367, -0.139420, -0.751051, 0.659680, 0.027293, -0.869152, -0.299649, 0.393429, 0.694431, 0.357858, 0.624262, -0.980063, 0.048239, 0.192740, -0.957670, -0.197171, 0.209744, -0.426575, 0.491147, 0.759479, 0.930729, -0.353305, 0.094439, -0.087177, -0.986800, -0.136476, 0.420125, 0.847745, 0.323765, -0.094606, 0.731356, 0.675403, 0.364523, -0.778171, 0.511441, 0.572580, -0.635851, 0.517538, -0.728410, -0.377792, 0.571569, 0.821426, -0.551107, 0.146767, 0.611592, -0.067386, 0.788299, -0.201878, -0.648339, 0.734099, -0.218371, 0.548751, 0.806962, -0.618781, -0.780286, 0.090910, 0.773022, 0.572307, 0.273682, -0.832191, 0.075406, 0.549338, -0.527881, -0.842065, -0.110758, 0.713377, -0.611049, 0.343091, -0.032376, -0.769418, 0.637924, -0.364000, 0.928542, 0.072902, -0.075522, 0.384793, 0.919908, -0.126707, -0.960799, 0.246597, 0.670195, 0.138297, 0.729186, 0.383517, 0.452997, 0.804803, -0.300919, -0.890656, 0.340852, 0.777662, -0.051309, 0.626586, 0.506109, 0.709225, 0.490769, -0.840664, 0.241099, -0.484927, -0.866147, 0.386417, 0.316973, -0.996791, -0.078126, 0.017454, -0.772838, -0.507518, 0.380982, 0.545414, 0.520831, 0.656703, 0.989006, -0.142037, 0.041144, 0.851398, 0.523177, 0.037518, 0.589960, -0.461012, 0.662884, -0.312887, 0.688503, 0.654267, 0.701842, -0.261223, 0.662707, -0.505687, 0.283759, 0.814715, -0.773790, 0.575381, 0.264926, -0.915365, 0.173693, 0.363233, -0.442723, -0.101989, 0.890839, 0.615891, 0.730347, 0.295418, 0.192776, 0.923459, 0.331753, 0.286043, 0.813551, 0.506276, -0.880038, -0.430483, 0.200545, -0.268483, -0.271866, 0.924124, 0.321512, 0.936440, 0.140390, -0.042720, 0.946336, 0.320348, -0.614866, -0.587524, 0.526076, -0.644170, 0.737808, 0.201704, -0.594987, 0.691806, 0.409140, 0.451318, -0.878337, 0.157593, -0.706770, -0.027572, 0.706906, -0.650318, -0.687813, 0.322488, 0.412994, -0.451978, 0.790665, 0.655698, -0.736533, 0.166067, -0.296232, 0.343575, 0.891181, -0.181032, 0.844862, 0.503424, -0.000000, -0.000000, 1.000000, -0.210771, -0.580805, -0.786283, -0.362948, 0.124780, 0.923417, -0.945040, -0.326275, 0.021064, -0.058898, -0.223752, 0.972865, 0.294182, -0.309803, 0.904146, -0.464340, 0.846732, 0.259679, 0.810859, 0.168913, 0.560336, -0.225681, -0.051538, 0.972837, -0.558517, 0.060703, 0.827269, 0.246917, 0.053767, 0.967544, -0.625688, 0.416476, 0.659593, 0.368480, 0.660082, 0.654610, -0.256950, -0.790687, 0.555689, 0.812456, 0.386599, 0.436414, -0.415243, -0.634020, 0.652374, 0.526498, -0.775666, 0.348054, 0.898919, -0.027521, 0.437250, -0.771007, -0.619432, 0.147828, 0.241650, -0.963712, 0.113421, -0.808544, -0.166434, 0.564408, 0.007918, -0.603710, 0.797164, 0.083121, 0.207628, 0.974670, 0.853393, -0.413663, 0.317180, 0.151868, 0.403214, 0.902416, -0.639618, -0.224670, 0.735127, -0.130574, -0.449698, 0.883585, -0.466905, -0.304360, 0.830280, -0.561375, 0.827271, 0.021922, 0.675562, 0.562071, 0.477172, 0.397033, -0.106025, 0.911660, -0.147862, 0.174204, 0.973545, 0.021756, -0.997176, 0.071875, 0.461969, 0.752437, -0.469492, 0.890442, 0.397266, 0.222021, -0.974927, 0.004503, -0.222480, 0.160045, -0.154584, 0.974930, -0.004403, 0.578617, 0.815587, 0.476591, 0.099535, 0.873472, 0.537740, 0.304863, 0.786062, 0.966165, 0.203994, 0.157835}; static float ps135 [405] = { -0.389809, 0.464682, 0.795059, -0.661547, -0.721572, 0.204180, -0.470425, 0.618695, 0.629220, -0.304422, -0.910847, 0.278722, 0.193945, 0.273429, 0.942137, 0.300776, 0.445329, 0.843336, -0.841034, 0.145692, 0.520996, 0.785554, -0.608232, 0.113836, 0.625635, -0.764418, 0.155713, 0.494394, 0.474461, 0.728328, -0.057783, 0.636436, 0.769162, -0.084790, -0.819786, 0.566358, 0.708260, -0.701682, -0.077528, -0.489538, -0.852838, 0.181713, -0.480152, -0.149222, 0.864400, 0.166546, -0.622556, 0.764648, 0.050659, 0.443919, 0.894634, 0.136802, -0.776265, 0.615385, 0.798089, 0.454271, 0.395843, 0.078692, 0.090925, 0.992744, -0.563060, -0.350192, 0.748551, -0.826420, 0.456919, 0.329021, 0.433627, 0.274015, 0.858419, 0.979552, -0.196770, 0.041940, -0.964417, -0.264386, -0.000903, -0.053973, -0.675063, 0.735783, 0.789737, 0.579573, 0.201025, 0.513901, 0.652701, 0.556675, 0.966275, 0.154324, 0.206150, -0.364643, 0.923963, 0.115445, 0.310398, 0.794356, 0.522161, -0.796834, -0.444500, 0.409237, 0.328489, 0.094411, 0.939777, 0.552044, -0.509437, 0.660092, 0.205865, -0.089753, 0.974456, 0.528877, -0.680281, 0.507451, 0.558346, 0.091699, 0.824525, -0.351261, 0.873691, 0.336571, -0.149447, -0.318653, 0.936016, 0.101363, -0.895880, 0.432580, 0.623563, 0.287956, 0.726809, -0.750064, -0.312393, 0.582936, 0.358391, -0.667894, 0.652284, 0.903696, 0.384141, 0.189130, 0.322399, -0.813286, 0.484380, 0.636757, -0.114052, 0.762583, -0.168419, 0.966315, 0.194601, 0.121262, 0.757166, 0.641869, 0.007906, -0.999438, -0.032565, -0.493839, 0.267795, 0.827290, 0.324223, -0.269065, 0.906909, 0.445558, -0.089502, 0.890768, -0.665006, -0.161537, 0.729159, -0.229665, -0.523312, 0.820609, -0.381035, 0.069536, 0.921942, -0.736052, 0.035995, 0.675967, 0.040358, 0.962801, 0.267179, -0.175278, 0.468352, 0.865982, 0.354127, 0.934649, -0.032016, 0.265996, 0.905198, 0.331455, -0.891262, -0.240233, 0.384631, -0.267971, 0.643786, 0.716750, 0.904021, -0.124977, 0.408810, -0.910620, -0.361285, 0.200610, 0.925662, -0.285138, 0.248688, 0.190082, -0.438401, 0.878450, -0.907214, 0.245811, 0.341378, 0.215651, -0.975219, 0.049431, -0.268503, -0.692865, 0.669211, 0.973058, -0.052346, 0.224541, 0.677350, -0.655297, 0.334339, -0.832776, -0.105911, 0.543385, -0.678316, 0.244009, 0.693070, 0.380122, -0.485702, 0.787147, -0.631336, -0.746653, -0.209582, -0.838264, 0.532502, 0.117282, 0.203850, 0.971762, 0.118847, -0.546611, 0.800833, 0.244709, 0.790339, -0.122653, 0.600267, 0.874642, 0.484703, -0.008042, 0.777197, 0.277764, 0.564634, -0.631780, -0.501458, 0.591096, 0.484276, -0.810730, 0.328927, 0.480553, 0.792067, 0.376429, -0.475928, -0.670075, 0.569642, -0.666477, 0.555677, 0.497023, -0.432812, -0.527279, 0.731198, 0.414362, -0.900591, 0.131299, -0.046306, -0.101087, 0.993799, -0.295620, -0.821596, 0.487431, -0.704916, 0.644221, 0.296771, -0.058537, 0.271568, 0.960638, 0.156069, 0.597899, 0.786231, 0.876365, 0.071154, 0.476363, 0.265947, -0.920208, 0.287211, 0.823647, -0.324426, 0.465138, 0.082446, 0.879870, 0.468008, -0.316880, 0.781084, 0.538047, -0.571587, 0.054100, 0.818756, 0.519989, -0.305367, 0.797723, -0.802510, -0.556855, 0.214222, 0.662211, 0.475636, 0.579005, -0.020707, -0.493174, 0.869684, -0.743648, -0.668571, -0.000216, 0.074252, -0.274903, 0.958601, 0.735978, 0.083936, 0.671782, -0.933341, 0.330985, 0.139006, -0.588974, 0.439353, 0.678291, -0.272927, -0.131753, 0.952970, -0.494760, -0.778950, 0.385292, -0.363349, -0.341516, 0.866801, 0.999397, 0.033589, 0.008846, 0.824592, -0.482401, 0.295528, -0.663217, -0.626246, 0.409828, -0.151459, -0.980577, 0.124612, -0.979675, 0.103866, 0.171607, 0.891594, 0.253671, 0.375115, 0.428594, 0.885799, 0.177956, 0.343155, 0.640616, 0.686918, -0.141220, 0.899551, 0.413357, -0.167372, 0.081936, 0.982483, -0.102035, 0.789299, 0.605472, 0.772161, -0.360849, -0.523025, 0.573667, 0.818955, 0.014811, 0.688388, -0.321942, 0.649981, -0.106320, -0.925715, 0.362969, 0.904354, -0.420576, 0.072518, -0.930088, 0.002161, 0.367330, 0.701797, -0.508654, 0.498750, -0.545028, 0.837835, 0.031263, -0.286433, 0.279742, 0.916352, -0.056943, 0.976387, -0.208390, 0.971819, 0.135479, -0.192906, 0.664320, 0.633215, 0.397137, -0.521803, 0.727643, 0.445261}; static float ps136 [408] = { 0.603118, -0.447541, 0.660270, 0.538612, -0.255123, 0.803000, -0.846727, -0.496518, 0.191109, -0.399120, -0.005889, 0.916880, 0.218033, -0.883957, 0.413621, -0.554135, -0.814231, 0.173094, 0.229960, -0.434865, 0.870638, 0.283124, 0.114775, 0.952191, -0.272992, 0.861457, 0.428214, 0.951634, -0.162950, 0.260461, 0.386513, -0.881211, 0.272168, -0.704745, -0.428964, 0.565088, -0.466637, -0.235774, 0.852444, 0.781507, -0.035322, 0.622895, 0.091744, -0.290195, 0.952560, -0.014229, -0.994882, 0.100040, 0.860082, -0.496287, 0.118148, 0.878332, -0.370312, 0.302328, -0.798684, 0.596969, 0.075705, 0.587039, -0.743368, 0.320606, -0.257196, 0.419388, 0.870611, -0.795790, -0.605305, -0.017977, 0.500824, 0.145669, 0.853203, 0.641210, 0.766740, 0.030985, 0.977722, 0.054896, 0.202598, -0.348931, 0.936558, -0.033251, -0.218849, -0.975751, 0.003860, -0.582365, -0.044904, 0.811686, -0.727359, -0.565362, 0.388993, -0.370553, 0.583290, 0.722816, -0.337207, 0.250773, -0.907416, 0.913147, 0.183365, 0.364061, 0.232847, 0.668845, 0.705995, -0.850279, -0.371939, 0.372408, 0.968299, -0.205026, -0.142695, 0.363660, 0.316129, 0.876250, -0.305293, 0.928620, 0.210860, -0.934109, 0.111816, 0.339024, -0.655278, 0.338047, 0.675526, 0.296581, 0.932760, 0.204935, -0.625033, 0.639280, 0.447945, 0.903864, -0.413049, -0.111443, 0.883490, -0.335614, -0.326816, -0.432609, 0.717016, 0.546568, -0.923491, -0.135259, 0.358984, -0.100246, 0.952710, 0.286870, -0.170392, -0.571766, 0.802527, -0.790723, 0.536772, 0.294334, 0.050840, 0.598770, 0.799306, 0.402956, 0.707516, 0.580558, 0.233180, -0.766181, 0.598827, 0.623148, -0.049027, 0.780565, 0.655639, -0.754205, -0.036220, 0.934678, 0.303286, 0.185457, -0.177145, -0.951408, 0.251876, 0.451841, 0.890971, 0.044831, -0.820575, 0.239450, 0.518960, -0.327374, -0.411069, 0.850793, 0.902031, -0.021877, 0.431117, -0.164321, 0.605060, 0.779038, 0.533044, -0.837352, 0.121265, 0.722993, -0.673743, 0.152813, 0.710478, -0.244390, 0.659920, -0.367229, -0.602015, 0.709028, -0.912791, -0.408427, 0.000643, -0.267211, -0.192019, 0.944313, 0.491340, -0.861695, -0.126752, -0.739603, -0.082066, 0.668021, -0.384363, -0.851584, 0.356469, 0.237081, -0.615324, 0.751777, -0.563936, 0.533108, 0.630692, 0.021483, -0.837846, 0.545484, 0.130299, 0.278388, 0.951589, 0.424262, -0.773159, 0.471409, 0.428180, -0.056195, 0.901944, 0.027462, -0.695395, 0.718103, -0.562300, -0.601677, 0.567277, -0.571852, -0.726255, 0.381497, 0.709920, 0.377780, 0.594387, 0.552518, 0.358554, 0.752438, 0.835804, 0.505464, 0.214333, -0.655515, 0.713130, 0.248486, -0.538224, 0.177328, 0.823935, 0.812207, 0.179064, 0.555208, 0.557812, 0.713260, 0.424390, -0.148790, 0.987435, 0.053239, -0.032793, 0.428462, 0.902965, 0.985191, 0.171274, 0.007955, 0.029863, -0.515499, 0.856369, 0.996621, -0.075328, 0.032742, 0.754519, -0.421863, 0.502726, 0.018575, -0.940301, 0.339836, -0.179983, -0.740792, 0.647173, 0.985030, 0.034088, -0.168978, 0.713567, 0.557883, 0.423779, -0.465718, 0.387259, 0.795700, 0.062645, 0.987710, 0.143192, 0.756451, -0.562570, 0.333611, 0.435696, -0.629832, 0.643024, -0.223639, 0.753612, 0.618106, -0.050812, 0.872630, 0.485731, -0.337842, 0.215563, 0.916185, 0.403342, 0.525470, 0.749131, -0.744295, 0.448550, 0.494800, -0.814018, -0.232856, 0.532120, 0.516414, 0.822596, 0.238020, 0.193982, -0.089102, 0.976950, -0.384996, -0.745886, 0.543537, -0.114395, 0.239354, 0.964170, 0.184596, 0.819174, 0.543027, 0.696336, 0.679915, 0.229851, 0.849208, -0.224849, 0.477796, -0.192454, 0.034329, 0.980705, 0.356312, 0.843717, 0.401477, -0.474815, 0.808874, 0.346803, -0.857062, 0.015534, 0.514979, -0.049875, -0.132971, 0.989864, -0.943181, -0.275582, 0.185643, 0.832384, 0.380026, 0.403381, -0.365817, -0.918251, 0.151638, 0.129788, 0.926143, 0.354138, -0.184356, -0.867254, 0.462475, 0.572135, 0.553937, 0.604826, -0.713893, 0.131695, 0.687760, -0.121926, -0.361205, 0.924481, -0.644246, -0.270209, 0.715496, 0.212670, 0.467883, 0.857821, 0.044476, 0.076448, 0.996081, 0.608938, -0.614092, 0.502081, -0.519637, -0.444685, 0.729543, 0.427031, -0.451714, 0.783326, 0.674271, 0.166497, 0.719471, -0.000146, 0.753625, 0.657304, -0.715637, -0.673140, 0.186402, 0.189336, -0.963768, 0.187893, 0.951922, -0.295670, 0.080154}; static float ps137 [411] = { 0.355304, -0.564163, 0.745305, 0.126109, -0.204864, 0.970632, -0.799464, -0.589124, 0.117432, 0.439636, 0.686103, 0.579640, -0.078776, -0.942545, 0.324659, -0.837657, -0.272157, 0.473562, 0.742146, -0.105901, 0.661819, -0.563647, 0.167314, 0.808893, -0.520776, -0.781564, 0.343439, 0.985058, 0.064126, 0.159837, 0.898186, -0.302546, 0.318949, -0.511862, 0.704953, 0.490957, -0.307538, 0.530331, 0.790044, 0.538635, 0.209147, 0.816168, -0.447475, 0.355080, 0.820783, 0.657819, -0.752669, 0.027635, -0.909193, -0.066347, 0.411055, 0.020688, 0.954223, 0.298380, 0.225388, 0.402301, 0.887330, 0.605038, 0.755999, 0.249791, -0.552552, 0.819050, 0.154417, -0.381443, -0.765849, 0.517665, -0.540809, 0.817747, -0.197018, 0.001751, -0.741264, 0.671212, -0.785459, 0.522807, 0.331251, -0.912812, -0.400305, 0.080809, 0.760164, -0.417069, 0.498201, -0.875157, 0.469535, 0.116780, 0.923669, 0.172493, 0.342173, 0.839227, -0.206774, 0.502935, 0.233953, 0.936364, 0.261705, -0.728647, -0.460872, 0.506627, -0.325472, 0.933649, 0.149560, -0.801255, -0.059030, 0.595404, -0.980597, -0.193943, 0.028539, 0.753615, 0.591995, 0.285666, 0.736576, 0.135405, 0.662662, -0.349137, 0.178048, 0.920001, -0.152734, -0.846515, 0.509985, 0.638126, -0.698804, -0.323215, 0.671059, -0.314830, 0.671240, -0.441580, 0.896879, -0.024792, 0.571369, -0.508577, 0.644118, -0.747091, 0.649520, 0.141347, -0.055003, 0.862974, 0.502245, -0.959546, 0.269861, 0.080294, -0.437479, -0.884668, 0.161165, 0.348000, -0.902446, 0.253942, -0.072905, 0.864383, -0.497521, 0.165511, 0.869547, 0.465290, -0.457786, -0.017947, 0.888881, -0.806753, 0.585953, -0.076213, -0.925098, -0.271091, 0.265899, 0.248004, -0.399001, 0.882776, -0.742086, 0.153302, 0.652539, 0.855898, 0.401085, 0.326449, 0.612399, 0.010976, 0.790473, 0.438952, -0.683109, 0.583680, 0.434484, 0.873604, 0.219178, 0.462509, -0.383302, 0.799478, 0.333091, 0.942250, 0.034866, -0.093543, 0.566563, 0.818692, -0.644403, 0.345838, 0.682012, -0.998075, 0.053866, 0.030731, 0.657329, 0.338574, 0.673265, -0.104597, 0.988343, 0.110621, 0.553534, 0.521471, 0.649360, -0.163719, 0.721036, 0.673278, -0.100427, -0.195307, 0.975587, 0.389729, 0.819581, 0.419999, 0.812816, -0.500780, 0.297573, -0.441175, -0.601351, 0.666140, 0.242097, 0.743248, 0.623676, 0.854790, 0.508399, 0.104235, -0.666183, 0.538922, 0.515522, 0.143952, -0.584557, 0.798481, -0.955097, 0.134907, 0.263797, -0.220476, 0.367195, 0.903636, -0.368618, 0.674157, 0.640026, -0.972928, 0.180778, -0.143984, -0.833615, -0.459733, 0.306157, 0.599002, 0.667262, 0.442672, 0.501918, -0.766755, 0.400206, -0.213047, -0.965915, 0.147037, -0.115572, 0.189424, 0.975070, 0.028614, -0.398921, 0.916539, -0.280536, 0.821095, 0.497094, -0.869655, 0.147457, 0.471122, -0.426985, 0.841295, 0.331521, 0.441133, 0.396064, 0.805317, -0.721712, -0.688953, -0.066903, 0.425734, 0.005968, 0.904829, 0.004100, 0.393457, 0.919334, 0.195267, -0.925844, -0.323548, -0.786694, 0.350619, 0.508113, 0.292535, -0.838272, 0.460135, 0.219865, 0.001785, 0.975529, 0.548845, -0.190803, 0.813857, -0.640635, -0.753040, 0.150058, -0.549192, -0.216828, 0.807077, 0.041882, 0.743082, 0.667888, 0.010408, -0.993725, 0.111362, -0.912223, 0.395706, -0.106139, 0.113438, 0.205246, 0.972114, -0.116353, -0.990371, -0.075019, 0.815325, 0.276143, 0.508910, -0.193742, -0.377838, 0.905374, -0.710702, -0.254862, 0.655704, -0.067976, -0.577195, 0.813772, -0.939018, 0.070489, -0.336566, -0.220182, -0.712140, 0.666616, 0.940705, 0.303831, 0.150865, 0.647865, -0.605164, 0.462653, 0.120813, 0.583542, 0.803046, -0.336071, -0.202790, 0.919746, 0.331042, 0.573050, 0.749683, -0.278121, -0.543283, 0.792144, -0.591205, -0.437281, 0.677689, -0.306124, -0.887849, 0.343530, -0.583223, -0.631961, 0.510369, 0.000000, -0.000000, 1.000000, 0.344140, -0.202282, 0.916869, -0.652548, -0.032658, 0.757043, 0.221637, -0.733799, 0.642196, 0.548399, 0.835680, 0.029971, -0.230502, 0.970342, -0.072833, 0.692555, -0.674220, 0.256506, 0.139625, -0.944853, 0.296239, -0.234041, -0.008023, 0.972194, -0.891064, 0.334621, 0.306650, -0.519479, 0.520942, 0.677319, 0.858954, 0.033313, 0.510968, 0.720717, 0.484817, 0.495499, -0.424703, -0.388931, 0.817533, 0.332581, 0.209792, 0.919444, -0.975913, -0.071483, 0.206117, -0.702088, -0.632272, 0.327573}; static float ps138 [414] = { 0.025243, 0.611025, 0.791209, -0.985741, -0.147452, 0.081069, 0.846665, -0.363624, 0.388506, 0.661409, 0.746442, 0.073234, 0.796044, 0.275655, 0.538821, 0.489356, -0.866225, 0.100925, 0.907901, 0.235456, 0.346809, -0.946762, -0.113975, 0.301083, -0.760809, 0.399582, 0.511375, -0.147147, 0.981430, 0.123058, -0.608348, 0.741758, 0.282325, -0.434906, -0.728077, 0.529870, -0.084275, -0.741766, 0.665343, -0.716202, -0.619942, 0.320509, 0.950619, 0.019430, 0.309752, -0.839293, 0.473862, 0.266537, -0.206609, 0.617268, 0.759140, 0.033683, -0.433079, 0.900726, 0.038443, 0.867066, 0.496707, 0.282973, -0.935540, 0.211405, -0.094450, 0.760916, 0.641939, -0.324795, 0.737856, 0.591673, 0.722976, 0.201753, -0.660759, -0.401521, -0.032146, 0.915285, -0.066830, -0.992062, -0.106517, -0.537732, 0.669149, 0.512917, 0.135282, -0.787480, 0.601310, 0.647269, 0.640039, 0.413996, -0.134741, -0.564190, 0.814576, 0.017423, -0.221299, 0.975050, -0.857822, -0.046054, 0.511880, 0.529037, 0.584369, 0.615331, 0.601379, -0.692226, 0.398957, 0.768759, -0.567434, 0.295004, 0.296237, -0.917864, -0.264140, -0.402771, 0.195392, 0.894202, 0.698489, 0.471966, 0.537924, 0.580793, 0.007531, 0.814016, 0.757359, 0.611641, 0.228695, -0.120285, -0.986766, 0.108739, -0.341980, -0.465023, 0.816581, 0.436610, 0.462390, 0.771730, -0.574616, 0.103812, 0.811813, -0.843158, -0.507172, 0.178497, 0.875104, -0.144006, 0.462013, 0.380541, -0.768125, 0.514949, -0.200181, 0.862826, 0.464176, 0.052837, -0.955434, 0.290436, 0.645005, -0.739397, 0.193029, -0.994959, 0.028035, -0.096280, 0.855517, 0.068759, 0.513189, -0.090873, 0.457681, 0.884461, -0.946177, 0.277802, 0.166057, -0.169876, -0.933211, 0.316639, 0.476146, 0.876352, 0.072749, 0.967867, -0.247151, 0.046376, -0.236298, -0.822090, 0.518007, 0.639815, -0.767737, -0.034883, -0.195934, -0.146122, 0.969669, 0.944800, -0.202048, 0.257934, -0.573183, -0.126034, 0.809677, -0.325444, 0.441249, 0.836293, 0.750796, -0.071423, 0.656662, 0.479847, -0.864119, -0.151805, 0.758527, -0.284945, 0.586040, 0.431823, -0.328622, 0.839962, 0.208618, -0.068529, 0.975593, -0.616918, -0.597247, 0.512550, -0.530574, -0.836825, 0.134965, 0.898005, 0.404766, 0.172485, 0.427593, -0.516973, 0.741555, 0.516478, 0.227440, 0.825543, 0.704195, 0.698980, -0.124646, -0.786579, 0.613048, -0.073932, -0.971964, -0.189743, -0.138863, 0.117867, 0.397249, 0.910110, -0.293767, -0.661565, 0.689951, 0.326203, -0.945234, -0.011123, 0.818206, 0.444918, 0.364124, -0.427385, 0.575434, 0.697293, -0.209371, 0.070182, 0.975314, 0.076586, -0.630465, 0.772430, 0.416715, -0.126852, 0.900143, 0.449435, -0.834578, 0.318573, -0.880299, 0.293670, 0.372601, -0.276450, -0.956855, -0.089468, 0.321122, 0.321242, 0.890889, -0.757988, 0.633742, 0.154356, -0.936374, 0.091773, 0.338794, 0.607808, -0.409895, 0.680114, 0.102089, -0.991036, 0.086175, -0.842747, -0.251741, 0.475820, 0.706712, -0.501688, 0.498865, 0.183933, 0.159480, 0.969915, -0.333458, -0.934232, 0.126554, -0.684120, -0.407716, 0.604771, -0.705255, 0.584263, 0.401562, 0.286994, -0.667402, 0.687174, -0.726379, 0.016115, 0.687105, -0.610146, 0.486579, 0.625271, -0.515674, 0.351476, 0.781374, 0.236576, 0.547513, 0.802659, 0.890559, -0.419528, 0.175784, 0.235895, -0.485901, 0.841578, -0.555821, -0.758977, 0.339142, -0.822038, 0.166861, 0.544437, 0.459982, 0.753497, 0.469744, 0.135020, 0.739728, 0.659221, -0.887983, 0.457722, 0.044454, -0.568368, -0.778932, -0.264994, -0.427730, 0.812944, 0.395183, -0.934082, -0.355458, 0.033772, -0.990343, 0.065511, 0.122185, 0.621280, 0.357036, 0.697521, -0.375671, -0.881008, -0.287570, 0.381739, 0.086856, 0.920180, -0.823721, -0.566236, -0.029336, 0.682815, -0.258350, -0.683388, -0.382632, -0.253042, 0.888573, -0.021682, -0.875646, 0.482467, 0.259362, 0.833223, 0.488334, 0.228108, -0.283446, 0.931464, 0.214186, -0.285446, -0.934155, 0.056134, -0.946943, -0.316461, 0.220914, -0.881280, 0.417784, -0.015052, 0.226992, 0.973780, 0.339622, 0.675274, 0.654723, -0.913308, -0.315906, 0.257043, -0.545271, -0.342806, 0.764960, -0.000000, -0.000000, 1.000000, 0.166196, 0.937701, 0.305116, -0.372655, -0.864808, 0.336505, 0.608857, -0.205634, 0.766164, 0.705782, 0.144238, 0.693590, -0.490741, -0.545242, 0.679621, -0.794505, -0.445508, 0.412656, 0.527162, -0.618320, 0.582907, -0.173620, -0.358330, 0.917309}; static float ps139 [417] = { 0.748102, -0.265722, 0.608059, -0.263203, 0.742514, 0.615952, 0.718025, -0.681562, -0.141113, -0.497436, -0.860565, 0.109478, -0.818075, -0.569096, 0.082960, -0.843272, 0.374655, 0.385391, -0.018611, -0.888802, 0.457914, 0.855607, -0.457294, 0.242528, 0.592142, 0.145886, 0.792518, -0.385815, -0.872379, 0.300169, 0.875478, 0.135921, 0.463750, 0.367502, 0.673346, 0.641519, -0.210833, -0.095891, 0.972807, 0.556598, -0.785726, 0.269878, -0.805756, 0.195364, 0.559097, -0.111298, 0.100758, 0.988666, 0.461189, -0.740625, -0.488650, 0.473366, -0.434359, 0.766327, 0.292833, -0.585072, 0.756267, 0.531192, 0.690333, 0.491198, 0.688408, -0.057372, 0.723051, -0.348834, 0.071945, 0.934419, -0.226256, 0.968260, -0.106209, 0.995290, 0.091516, -0.031991, -0.324704, -0.687489, 0.649558, 0.860747, -0.281798, 0.423915, 0.548429, -0.829134, -0.108456, -0.442405, 0.598876, 0.667552, 0.650360, 0.693262, 0.310514, 0.592970, -0.251882, 0.764815, 0.983341, -0.077318, -0.164508, -0.862722, -0.424093, 0.275420, -0.060671, -0.254006, 0.965298, -0.954766, -0.221677, 0.198197, 0.162216, 0.781631, 0.602278, -0.141992, -0.446009, 0.883693, -0.766237, -0.431398, 0.476210, 0.829790, -0.067657, 0.553959, 0.650130, 0.343147, 0.677924, -0.258932, -0.842834, 0.471789, -0.633144, -0.601780, 0.486816, 0.941301, -0.258215, 0.217434, 0.033758, 0.969290, 0.243594, -0.932433, 0.305334, 0.193234, 0.332077, 0.493308, 0.803973, 0.854250, 0.023125, -0.519347, 0.037257, -0.056423, 0.997712, -0.241508, 0.595274, 0.766370, 0.749659, 0.651288, 0.117621, 0.989823, -0.042874, 0.135693, 0.790625, 0.342150, 0.507785, -0.068022, 0.894348, 0.442170, 0.519134, 0.520705, 0.677766, -0.434756, -0.133727, 0.890564, -0.336541, -0.508829, 0.792359, 0.209333, -0.867843, 0.450587, 0.956586, 0.121281, 0.265015, 0.100499, 0.465641, 0.879249, -0.646912, -0.393992, 0.652898, -0.740775, -0.604079, 0.293839, 0.276846, -0.407498, 0.870231, 0.580672, 0.755635, -0.303045, -0.280939, -0.952764, 0.115382, -0.245504, 0.266890, 0.931932, -0.276022, 0.855733, 0.437645, -0.722806, 0.400133, 0.563422, 0.871589, 0.471212, 0.135248, -0.470768, 0.243086, 0.848108, 0.651826, -0.754892, 0.072538, 0.761869, -0.473510, 0.441977, 0.437647, -0.778784, 0.449399, -0.456570, 0.884951, -0.091677, -0.961248, -0.256121, -0.102005, -0.364503, 0.429258, 0.826363, 0.162601, 0.984335, 0.068155, -0.943823, -0.053459, 0.326099, -0.051688, 0.780096, 0.623521, 0.401473, -0.232813, 0.885786, 0.640475, -0.453151, 0.620037, -0.615685, 0.584879, 0.528062, 0.929463, -0.079555, 0.360235, -0.561072, 0.421381, 0.712486, 0.348718, 0.815095, 0.462617, 0.618787, -0.641519, 0.453383, 0.096817, -0.955332, 0.279226, -0.978338, 0.206999, -0.002625, 0.478168, 0.829844, 0.287602, -0.127445, 0.444682, 0.886575, 0.334520, -0.938626, -0.084134, 0.388675, 0.139758, 0.910714, -0.766591, -0.214442, 0.605271, 0.802578, -0.594374, 0.050866, -0.194186, 0.948331, 0.250920, 0.726708, -0.635423, 0.261022, -0.657250, 0.222935, 0.719946, 0.251616, 0.312599, 0.915954, 0.922072, 0.381739, -0.063709, 0.153810, 0.125135, 0.980145, 0.507657, -0.047074, 0.860273, -0.506402, -0.558605, 0.656900, 0.167273, -0.233047, 0.957971, -0.421905, 0.862433, 0.279653, -0.038852, -0.992637, 0.114730, -0.461419, -0.740843, 0.488103, 0.082018, -0.618930, 0.781152, -0.154736, -0.942543, 0.296089, 0.589355, 0.801774, 0.099090, -0.132587, -0.624189, 0.769941, -0.874559, -0.245433, 0.418221, 0.142815, 0.894244, 0.424183, 0.672207, 0.528403, 0.518583, 0.286287, -0.050181, 0.956829, -0.393984, -0.915788, -0.078165, 0.069077, -0.437911, 0.896361, 0.298597, -0.735778, 0.607841, -0.120241, -0.774290, 0.621303, -0.032965, 0.629797, 0.776060, -0.675976, -0.730326, 0.098390, -0.744653, 0.564992, 0.355353, -0.602037, 0.730520, 0.322322, 0.091169, -0.771350, 0.629848, 0.089501, -0.994204, -0.059567, -0.557119, 0.040213, 0.829458, 0.471644, 0.329740, 0.817816, 0.783712, 0.524254, 0.333095, -0.846722, 0.504503, 0.168933, -0.274674, -0.926482, -0.257263, 0.342385, -0.896834, 0.280111, 0.911653, -0.410050, 0.027362, 0.913649, -0.163585, -0.372136, -0.487235, -0.351206, 0.799535, -0.295107, -0.296863, 0.908176, 0.890373, 0.329462, 0.314150, 0.005008, 0.281008, 0.959692, -0.618972, -0.177584, 0.765074, 0.177330, 0.633786, 0.752907, 0.753637, 0.144278, 0.641261, 0.485204, -0.613019, 0.623526, -0.724918, 0.008326, 0.688785}; static float ps140 [420] = { 0.080095, -0.572887, 0.815711, 0.114949, -0.177343, 0.977413, 0.207564, -0.819906, 0.533546, -0.260627, -0.856956, 0.444635, 0.758050, 0.643824, 0.104171, 0.345938, -0.860973, 0.372896, -0.652071, -0.574575, 0.494638, -0.297334, 0.267242, 0.916610, -0.262774, -0.118674, 0.957531, 0.865353, -0.251323, 0.433592, -0.853992, 0.492899, 0.166577, -0.302617, -0.323999, 0.896352, -0.435007, 0.607244, 0.664849, -0.617339, 0.571559, 0.540567, -0.872458, 0.339547, 0.351459, 0.485936, 0.767876, 0.417411, -0.832877, 0.190332, 0.519701, -0.782757, -0.551066, 0.289168, -0.014041, 0.584416, 0.811333, 0.072833, 0.945391, 0.317696, 0.698529, -0.609848, 0.374357, -0.870750, 0.037016, -0.490330, -0.410445, 0.065679, 0.909517, -0.597324, 0.038778, 0.801062, 0.642289, -0.389257, 0.660260, 0.720991, -0.673370, -0.163538, 0.043967, -0.989582, 0.137090, -0.334260, 0.924379, 0.183831, 0.322458, 0.635857, 0.701218, 0.993781, 0.017402, 0.109981, -0.959911, -0.234608, -0.153395, 0.192613, -0.980940, -0.025623, -0.820309, 0.522213, -0.233209, -0.975061, 0.209517, -0.073206, 0.282541, -0.943984, 0.170485, 0.880822, 0.328861, 0.340593, -0.938226, -0.105595, -0.329519, -0.887210, -0.227012, 0.401652, 0.450012, 0.866324, 0.216730, -0.789253, -0.410375, 0.456807, 0.523912, 0.273762, 0.806580, 0.536135, -0.748866, 0.389562, -0.089660, -0.233217, 0.968282, -0.147067, -0.781971, 0.605716, -0.108427, -0.948767, 0.296791, 0.762345, 0.397616, 0.510619, 0.307421, -0.261036, 0.915070, -0.229158, 0.610897, 0.757821, 0.671500, -0.717782, 0.184056, 0.000000, -0.000000, 1.000000, 0.953041, -0.111560, 0.281544, -0.281912, 0.759034, 0.586850, -0.702266, -0.703173, 0.111219, -0.497481, -0.358171, 0.790080, 0.610729, 0.441396, 0.657404, 0.283868, 0.889011, 0.359275, -0.936170, -0.349511, 0.037783, 0.388898, 0.921261, 0.006012, -0.507312, -0.546821, 0.666049, -0.166515, -0.984046, 0.062661, 0.096620, -0.383169, 0.918611, -0.471305, 0.741473, 0.477586, 0.836306, 0.183093, 0.516788, -0.464903, -0.149844, 0.872589, 0.305783, 0.781897, 0.543262, -0.960569, -0.089425, 0.263267, 0.408988, -0.718314, 0.562809, 0.124136, 0.712837, 0.690256, -0.327007, -0.688234, 0.647611, -0.637846, -0.720376, -0.272417, 0.428341, -0.903617, 0.001152, -0.639642, -0.178444, 0.747673, 0.095689, 0.851799, 0.515055, -0.527087, -0.838083, 0.140700, -0.756269, 0.011392, 0.654161, -0.376626, 0.446837, 0.811474, 0.395118, 0.127658, 0.909717, -0.627984, 0.695154, 0.349853, -0.743286, 0.388407, 0.544670, -0.443947, -0.828964, 0.340190, -0.946423, 0.289179, 0.143732, 0.655050, 0.594899, 0.465838, 0.908403, -0.336560, 0.248056, 0.451210, -0.099138, 0.886894, -0.116677, 0.877324, 0.465498, -0.766290, 0.528533, 0.365312, 0.057999, -0.740650, 0.669383, 0.768575, -0.431853, 0.472013, 0.747863, 0.011927, 0.663746, 0.133784, -0.933756, 0.331967, -0.902052, -0.357786, 0.241435, -0.686050, 0.223317, 0.692434, -0.839394, -0.537723, 0.079197, 0.593357, -0.580189, 0.557950, 0.905621, -0.422426, 0.037505, -0.939627, 0.132380, 0.315558, 0.783542, 0.536952, 0.312640, -0.519627, 0.824702, 0.223282, 0.788508, -0.614221, 0.031411, -0.613170, 0.789780, 0.016462, -0.008710, -0.877905, 0.478756, -0.309391, -0.927547, 0.209602, -0.016891, -0.995144, -0.096971, -0.505332, 0.252182, 0.825253, 0.253887, -0.021666, 0.966991, -0.629628, -0.708252, 0.319293, 0.985943, 0.151980, -0.069415, 0.070293, 0.384931, 0.920265, 0.152821, 0.170047, 0.973514, -0.477643, -0.715741, 0.509482, -0.991966, 0.073893, 0.102679, 0.234820, 0.959657, 0.154652, -0.662914, -0.387253, 0.640765, -0.155924, 0.433827, 0.887402, -0.198089, 0.073798, 0.977402, -0.880902, -0.017385, 0.472980, -0.574292, 0.422973, 0.700915, -0.593950, -0.801718, -0.066877, 0.500029, 0.627785, 0.596537, -0.129565, -0.628237, 0.767158, 0.297222, 0.322300, 0.898767, -0.134892, 0.956223, 0.259694, 0.287927, -0.467794, 0.835624, 0.589652, 0.060679, 0.805374, -0.322502, -0.516136, 0.793471, 0.485720, -0.332165, 0.808543, -0.064910, 0.234391, 0.969973, 0.455455, -0.533622, 0.712606, 0.697981, 0.233056, 0.677132, -0.782194, -0.203880, 0.588732, -0.326289, 0.863362, 0.384892, 0.879311, 0.454313, 0.142871, 0.261640, -0.656550, 0.707451, 0.426342, 0.461375, 0.778053, 0.760920, -0.213250, 0.612801, 0.200819, 0.519961, 0.830248, 0.621903, -0.163941, 0.765741, -0.079500, 0.752988, 0.653214, 0.493865, -0.847052, 0.196469, -0.114699, -0.444700, 0.888305}; static float ps141 [423] = { -0.238685, 0.809396, 0.536571, 0.141187, 0.285999, 0.947771, 0.352335, -0.471245, 0.808572, 0.207844, 0.761711, 0.613675, -0.375049, 0.457864, 0.806039, -0.978509, -0.035145, 0.203189, 0.796490, -0.513705, 0.318922, 0.498482, -0.689520, 0.525430, -0.087598, -0.929786, 0.357525, 0.958959, 0.242369, 0.147154, 0.634645, -0.682235, 0.363017, -0.518126, 0.797798, 0.308324, -0.031237, 0.999389, 0.015680, -0.199669, -0.549318, 0.811408, 0.800373, 0.223405, 0.556321, -0.051412, -0.267455, 0.962198, -0.262785, 0.091169, 0.960537, -0.263556, -0.847014, 0.461634, 0.998916, 0.040084, 0.023647, -0.846326, 0.112384, 0.520675, -0.439728, -0.219727, 0.870838, 0.529834, -0.334963, 0.779151, 0.335309, -0.265916, 0.903801, -0.750191, -0.005870, 0.661195, 0.979306, -0.158520, 0.125821, 0.041978, 0.969693, 0.240692, 0.470672, -0.821398, 0.322139, -0.207847, -0.736017, 0.644265, 0.343787, 0.820381, 0.456930, 0.939871, -0.341263, -0.013498, -0.430717, -0.723017, 0.540119, -0.055240, 0.387136, 0.920366, 0.422706, -0.901867, 0.089195, -0.695647, 0.445778, 0.563345, -0.799021, -0.590786, 0.111969, -0.885334, -0.086914, 0.456759, -0.252045, 0.315495, 0.914842, -0.608127, 0.118514, 0.784943, 0.159290, -0.380562, 0.910933, 0.816623, -0.170147, 0.551522, -0.663654, -0.706737, 0.245125, 0.564268, 0.706720, 0.426788, 0.384594, -0.913002, -0.136070, 0.679302, -0.522703, 0.515102, 0.233625, -0.971559, 0.038621, -0.441634, 0.738004, 0.510205, 0.923446, -0.163638, 0.347088, -0.609344, -0.323731, 0.723808, 0.286867, -0.919237, 0.269649, -0.912220, 0.331462, 0.240806, 0.177650, -0.965991, -0.187889, 0.339902, -0.656739, 0.673172, -0.525877, 0.554555, 0.644920, -0.764948, -0.213501, 0.607678, 0.590675, -0.795636, 0.134409, -0.311450, -0.913646, 0.261247, 0.733906, 0.588142, 0.339810, 0.144195, 0.896978, 0.417898, -0.553381, -0.531963, 0.640924, -0.038989, -0.832143, 0.553189, -0.064691, 0.176166, 0.982232, -0.620074, -0.639336, 0.454707, -0.239965, -0.351077, 0.905075, -0.712609, -0.437784, 0.548209, -0.784793, 0.505919, 0.357974, -0.489895, -0.867960, -0.081538, -0.513918, -0.845711, 0.143740, -0.732638, 0.679413, 0.040498, -0.888807, -0.411321, 0.202084, 0.982410, -0.155348, -0.103625, 0.564348, -0.357466, -0.744130, 0.083139, -0.973794, 0.211693, -0.438676, 0.227216, 0.869446, 0.511821, 0.068619, 0.856348, 0.692001, -0.337101, 0.638356, 0.332596, 0.184581, 0.924830, -0.902583, -0.429880, -0.023405, 0.430150, 0.674128, 0.600435, 0.911250, -0.346452, 0.222698, 0.734841, -0.655561, 0.173923, -0.666331, -0.745451, 0.017518, 0.969466, 0.039194, 0.242072, 0.968828, 0.237355, -0.070953, 0.775680, 0.020433, 0.630796, 0.902520, 0.238413, 0.358631, 0.482248, 0.495402, 0.722505, -0.366914, -0.605983, 0.705804, 0.627398, 0.546949, 0.554273, 0.868393, 0.429898, 0.247148, -0.099642, 0.912853, 0.395944, -0.256923, -0.133544, 0.957161, -0.723175, 0.241863, 0.646931, -0.021535, -0.476123, 0.879115, 0.856543, -0.510040, 0.078698, -0.935250, 0.126238, 0.330713, 0.322024, -0.880721, -0.347319, 0.314292, 0.405621, 0.858308, -0.612267, -0.114615, 0.782299, 0.658099, 0.149203, 0.738001, 0.165153, -0.584858, 0.794145, -0.666510, 0.126582, -0.734671, -0.836658, 0.315559, 0.447689, -0.570221, 0.816458, 0.090800, 0.339791, 0.939513, -0.043094, 0.108909, 0.499296, 0.859559, -0.422333, -0.420297, 0.803110, -0.841032, -0.327732, 0.430414, 0.057247, 0.662718, 0.746677, 0.130858, 0.980245, -0.148309, 0.132188, 0.067431, 0.988928, 0.287178, 0.927619, 0.238855, 0.823886, -0.350260, 0.445566, 0.894195, 0.032928, 0.446466, 0.001660, 0.822444, 0.568843, -0.137117, 0.706010, 0.694801, 0.500521, 0.294306, 0.814164, -0.063427, -0.045677, 0.996941, -0.338160, 0.641547, 0.688524, 0.319985, -0.812516, 0.487265, 0.468586, 0.835813, 0.286083, -0.843062, 0.517437, 0.146646, 0.500055, -0.136922, 0.855101, -0.774593, -0.531975, 0.342066, -0.623742, 0.634824, 0.456009, 0.793025, 0.598413, 0.114073, -0.161110, 0.539965, 0.826124, -0.933493, -0.212680, 0.288718, 0.320293, -0.037545, 0.946574, 0.154449, -0.762380, 0.628428, 0.645565, 0.736627, 0.201558, -0.691525, 0.677604, 0.250291, 0.137931, -0.161736, 0.977147, -0.482576, -0.802196, 0.351570, -0.021404, -0.674317, 0.738131, 0.658655, 0.360091, 0.660687, 0.784395, 0.415413, 0.460604, 0.527386, -0.522494, 0.669973, -0.448048, 0.000345, 0.894009, 0.176783, 0.981527, 0.073165, -0.281873, -0.599450, -0.749138, 0.128371, -0.895784, 0.425549}; static float ps142 [426] = { -0.654083, 0.519868, 0.549466, 0.033724, 0.410635, 0.911176, -0.379102, -0.277866, 0.882651, -0.879756, -0.370819, 0.297527, 0.368395, -0.091178, 0.925187, 0.588742, 0.188570, 0.786018, 0.762464, -0.524738, 0.378549, -0.902048, 0.293330, 0.316650, 0.053115, -0.998588, -0.001185, -0.732851, 0.100294, 0.672956, -0.078811, -0.820842, 0.565692, -0.789032, 0.509202, 0.343718, -0.565392, -0.196803, 0.801000, 0.739504, -0.343548, 0.578885, -0.750202, 0.636850, 0.177816, 0.238391, 0.797257, 0.554573, 0.160947, -0.537035, 0.828064, -0.759668, -0.455276, 0.464358, -0.377977, 0.167582, 0.910521, 0.407605, 0.132748, 0.903458, 0.061852, -0.378322, 0.923605, 0.282007, -0.959380, -0.007903, -0.495067, 0.868789, 0.010689, 0.868609, 0.063293, 0.491439, -0.638694, 0.666445, 0.384606, 0.058019, -0.928754, -0.366128, -0.884388, 0.439730, 0.156511, 0.678756, -0.734364, 0.000400, -0.583023, 0.786670, 0.203064, 0.555313, -0.028551, 0.831151, -0.163179, 0.504163, 0.848052, 0.141776, -0.816119, 0.560223, 0.989641, 0.131114, 0.058479, 0.156120, -0.969140, 0.190773, 0.989622, 0.034964, -0.139373, 0.828432, -0.559752, 0.019431, -0.390676, 0.897287, 0.205544, 0.723425, 0.025713, 0.689924, 0.382210, 0.923295, 0.037969, 0.942011, 0.206762, 0.264320, 0.564978, -0.409228, 0.716472, -0.093042, 0.833272, 0.544979, -0.680219, 0.308666, 0.664851, 0.908370, -0.125395, 0.398924, 0.579763, -0.793248, 0.186098, 0.175371, -0.965849, -0.190736, -0.235876, -0.124681, 0.963752, -0.597183, -0.532006, 0.600285, 0.970588, -0.196004, -0.139792, -0.489961, 0.652711, 0.577846, -0.177072, -0.357735, 0.916881, 0.870622, -0.449231, 0.200522, 0.785096, 0.566875, -0.249554, 0.957764, 0.260689, -0.121368, 0.932933, 0.157353, -0.323846, -0.197087, -0.902352, 0.383298, -0.680701, -0.332558, 0.652726, -0.195527, 0.086795, 0.976850, 0.139407, 0.900849, 0.411140, 0.241414, -0.894705, 0.375796, -0.541339, 0.242576, 0.805052, -0.000000, -0.000000, 1.000000, -0.375692, -0.840970, -0.389390, -0.061738, -0.979299, -0.192775, 0.208822, 0.064346, 0.975835, 0.600557, 0.576282, 0.554284, 0.378127, -0.491937, 0.784231, 0.361937, -0.767175, 0.529569, 0.018829, 0.209701, 0.977584, 0.948883, -0.234428, 0.211338, -0.588060, 0.030035, 0.808259, 0.682455, 0.708062, 0.181393, 0.967951, 0.004198, 0.251106, 0.061188, 0.756648, 0.650953, 0.417017, 0.838913, -0.349745, 0.271660, 0.935609, 0.225470, -0.277249, -0.942915, 0.184509, 0.473773, 0.867903, -0.149274, 0.731090, 0.583975, 0.352818, 0.744926, 0.226429, 0.627547, -0.269397, 0.879549, 0.392198, -0.302259, 0.758285, 0.577619, 0.033826, -0.695602, 0.717630, -0.173904, -0.984741, -0.006507, 0.606434, 0.391417, 0.692120, 0.253764, 0.647766, 0.718334, -0.857395, -0.047929, 0.512422, 0.942489, -0.066736, -0.327507, -0.499723, -0.415255, 0.760158, 0.651476, -0.197098, 0.732620, -0.341686, 0.586328, 0.734486, -0.299540, -0.498043, 0.813774, 0.596282, 0.802724, 0.009029, -0.747058, -0.662531, 0.054375, -0.623828, -0.746593, 0.231165, 0.734599, -0.646343, 0.206410, 0.429425, 0.343620, 0.835176, -0.600553, 0.687271, -0.408650, 0.473395, -0.620315, 0.625385, -0.230288, -0.278443, -0.932436, -0.522294, 0.460722, 0.717596, 0.451411, -0.819075, 0.354039, 0.258889, -0.670835, 0.694951, -0.420202, -0.046080, 0.906260, -0.143526, 0.682977, 0.716200, -0.826908, -0.256884, 0.500233, -0.463384, 0.790070, 0.401329, -0.063504, -0.978443, 0.196509, 0.857011, 0.261804, 0.443835, -0.072020, -0.540243, 0.838422, -0.405273, -0.619066, 0.672689, 0.023847, -0.920644, 0.389675, -0.790199, 0.362493, 0.494150, 0.854943, -0.331942, 0.398607, -0.178865, 0.302663, 0.936164, -0.493499, -0.714784, 0.495523, -0.858497, -0.422267, -0.290986, 0.441063, 0.533185, 0.721926, -0.848206, 0.162956, 0.503975, 0.172921, -0.162333, 0.971466, -0.373985, 0.910430, -0.176786, -0.041269, -0.202715, 0.978368, 0.278967, -0.336728, 0.899328, 0.994189, -0.095211, 0.050230, 0.932742, 0.349002, 0.090504, 0.430438, 0.701070, 0.568528, -0.727492, -0.119013, 0.675716, 0.568414, 0.727188, 0.384840, 0.823905, 0.553602, 0.121265, 0.802485, -0.138478, 0.580380, -0.940818, 0.338240, -0.021359, 0.047200, 0.594907, 0.802408, -0.361932, 0.386654, 0.848236, 0.470657, -0.260542, 0.842971, 0.497034, 0.843028, 0.205575, 0.744888, 0.428537, 0.511369, 0.879103, 0.469471, -0.082315, 0.643177, -0.531312, 0.551390, -0.656501, -0.636841, 0.404277, -0.190888, -0.677228, 0.710580, -0.293729, -0.785150, 0.545218, 0.244501, 0.474823, 0.845436}; static float ps143 [429] = { 0.089966, -0.562737, 0.821726, -0.264487, 0.690007, 0.673748, -0.158967, 0.160674, 0.974122, 0.158457, 0.405658, 0.900185, 0.337815, -0.299853, 0.892171, -0.493448, -0.526557, 0.692276, 0.296687, 0.538242, 0.788843, 0.803188, -0.261253, 0.535385, -0.975115, 0.219921, 0.028018, -0.469507, 0.280857, 0.837068, 0.624056, 0.542636, 0.562227, -0.587452, -0.167005, 0.791839, -0.787331, -0.508623, 0.348444, -0.635774, -0.684775, 0.356194, 0.209275, 0.912185, 0.352311, -0.130606, 0.823294, 0.552385, 0.277031, -0.673103, 0.685701, 0.943407, 0.067827, 0.324627, 0.094382, 0.833359, 0.544615, 0.705499, 0.598256, 0.379949, -0.998201, -0.009361, 0.059214, 0.312907, 0.939665, 0.138273, -0.543161, 0.057649, 0.837647, 0.043336, 0.210209, 0.976696, -0.300878, -0.488920, 0.818798, -0.263654, -0.286839, 0.920983, 0.277342, -0.960302, -0.030036, 0.855229, -0.024408, 0.517676, 0.531294, -0.188947, 0.825848, -0.576105, -0.800595, 0.164776, 0.061156, 0.570615, 0.818938, -0.610805, 0.785580, -0.098900, -0.351798, 0.907663, 0.228879, -0.093350, -0.434185, 0.895974, -0.634033, -0.367831, 0.680222, -0.964476, 0.140928, 0.223441, 0.730715, -0.092204, 0.676427, 0.376613, -0.083409, 0.922608, 0.599325, -0.651056, 0.465764, -0.456352, -0.825809, 0.331334, 0.491218, -0.868598, -0.065125, 0.413680, -0.899682, 0.139430, -0.959952, -0.093432, 0.264128, -0.495619, -0.691821, 0.525115, -0.654970, -0.538841, 0.529778, 0.492553, -0.409067, 0.768150, 0.754119, -0.507621, 0.416683, -0.141648, -0.906519, 0.397693, -0.357552, 0.109315, 0.927473, 0.739582, 0.127132, 0.660951, -0.411409, -0.118175, 0.903758, 0.654333, -0.468390, 0.593683, -0.510271, -0.855263, -0.090273, -0.749193, 0.338889, 0.569091, -0.770175, 0.636470, -0.041667, -0.982403, -0.149632, -0.111779, 0.124624, -0.378353, 0.917234, -0.808083, 0.120799, 0.576549, 0.849568, 0.198834, 0.488569, -0.359153, 0.793337, 0.491554, -0.316218, -0.814557, 0.486316, -0.064441, 0.392328, 0.917565, -0.541129, 0.698109, 0.468852, 0.523474, -0.794890, 0.306799, -0.155255, -0.768293, 0.620985, -0.750054, -0.637402, 0.176457, 0.195614, 0.701338, 0.685464, -0.930548, -0.360481, -0.064300, -0.052547, -0.977057, 0.206396, -0.166249, 0.554338, 0.815519, 0.103357, -0.930690, 0.350903, -0.875029, 0.269442, 0.402150, -0.966567, -0.234101, 0.104615, -0.689874, 0.649518, 0.319688, -0.662030, 0.739550, 0.121584, 0.519621, 0.459322, 0.720429, -0.570635, 0.426231, 0.701928, -0.747142, -0.187343, 0.637716, 0.986311, -0.071331, 0.148669, 0.012485, -0.850867, 0.525232, -0.331118, -0.661059, 0.673322, 0.700264, -0.664601, 0.260645, 0.418782, -0.753100, 0.507406, -0.660175, 0.531309, 0.530923, -0.594755, -0.760404, -0.260868, 0.396460, 0.351493, 0.848099, -0.812040, 0.560915, 0.161137, -0.785300, -0.357898, 0.505187, -0.801040, 0.469113, 0.371844, 0.475067, -0.590045, 0.652808, -0.518066, 0.804843, 0.289544, 0.257054, 0.224116, 0.940051, 0.064344, -0.721627, 0.689286, 0.703561, 0.342334, 0.622743, -0.035408, 0.712102, 0.701183, -0.835777, -0.549061, -0.002780, -0.218031, 0.899578, 0.378446, 0.417935, 0.642926, 0.641854, -0.216299, -0.066826, 0.974037, -0.864923, -0.129826, 0.484824, 0.519357, 0.717198, 0.464646, -0.457077, -0.338103, 0.822659, 0.923928, -0.145010, 0.354019, 0.192538, -0.967486, 0.164011, 0.313334, 0.797060, 0.516253, -0.281968, -0.927006, 0.247293, 0.098371, 0.980726, 0.168820, -0.268672, 0.335665, 0.902854, -0.865695, 0.348125, -0.359697, -0.708989, 0.003177, 0.705212, -0.054062, -0.230996, 0.971452, -0.898705, 0.438550, -0.001571, -0.009875, -0.013440, 0.999861, -0.910727, 0.360066, 0.202307, 0.221249, -0.819510, 0.528632, 0.917389, 0.275999, 0.286744, -0.459806, 0.612937, 0.642563, 0.798171, 0.407995, 0.443241, 0.201393, 0.029833, 0.979056, -0.652327, 0.220488, 0.725158, -0.672759, -0.739837, -0.006106, -0.897309, -0.292915, 0.330207, -0.909869, 0.055356, 0.411186, -0.124788, 0.974241, 0.187836, 0.162465, -0.177647, 0.970591, -0.124963, -0.616758, 0.777170, -0.369279, 0.488879, 0.790336, -0.002669, 0.928086, 0.372355, 0.037862, -0.999234, 0.009887, 0.406116, 0.910114, -0.082226, -0.850228, -0.470288, -0.236522, 0.192664, 0.980463, -0.039660, 0.322359, -0.883833, 0.339004, 0.746830, 0.642443, 0.171791, 0.411262, 0.854856, 0.316362, 0.300360, -0.501894, 0.811102, 0.660945, -0.289516, 0.692338, 0.941738, -0.291257, 0.168223, 0.582622, 0.243265, 0.775483, 0.435970, 0.120009, 0.891924, -0.886210, -0.432370, 0.166394, 0.840684, -0.503016, 0.200564, 0.595542, 0.015152, 0.803181}; static float ps144 [432] = { -0.467369, 0.457170, 0.756678, -0.569659, -0.492344, 0.658093, 0.152156, -0.067096, 0.986076, 0.688051, -0.564129, 0.456447, -0.982174, -0.139234, 0.126286, -0.259035, -0.959295, -0.112493, 0.424431, -0.870432, 0.249412, 0.178838, -0.983749, 0.015975, -0.638325, 0.323059, 0.698694, 0.119636, 0.571446, 0.811873, -0.739109, -0.582195, 0.338772, 0.495905, 0.661637, 0.562418, -0.445090, 0.632058, 0.634347, -0.867854, -0.013075, 0.496648, -0.854398, -0.394446, 0.338254, -0.806210, 0.567833, 0.166104, -0.459197, 0.047070, 0.887087, -0.257242, 0.892231, 0.371147, -0.929414, -0.342732, 0.136836, -0.601580, -0.798638, -0.016687, -0.991552, 0.072122, 0.107813, -0.310184, -0.828305, 0.466579, -0.914151, 0.397712, 0.078442, -0.229673, -0.716861, 0.658301, 0.010232, -0.984512, 0.175017, -0.433171, -0.691955, 0.577548, -0.079167, 0.486108, 0.870305, 0.522155, -0.634693, 0.569666, -0.631334, 0.109547, 0.767734, 0.764756, 0.293386, 0.573650, -0.150333, -0.931034, 0.332529, 0.298550, 0.644503, 0.703906, 0.605724, -0.722148, 0.334066, -0.747792, -0.060972, 0.661127, -0.306436, -0.893005, -0.329605, 0.608921, 0.359843, 0.706914, -0.646973, -0.732226, -0.212769, -0.473216, 0.260106, 0.841672, -0.824732, -0.229408, 0.516903, -0.622291, 0.516437, 0.588257, 0.463878, 0.514313, 0.721318, 0.316280, -0.727205, 0.609212, -0.098179, -0.838519, 0.535953, -0.768815, 0.372618, 0.519691, 0.111846, 0.369405, 0.922513, -0.388925, 0.920068, -0.047031, -0.595692, -0.115175, 0.794912, -0.888420, -0.455382, -0.057770, -0.075540, 0.821825, 0.564710, 0.882816, -0.262463, 0.389549, 0.295858, 0.225463, 0.928243, -0.309670, -0.404625, 0.860455, -0.741570, 0.638294, -0.206532, -0.773107, 0.163156, 0.612933, 0.104586, 0.961311, 0.254838, -0.266666, 0.433371, -0.860859, 0.879917, -0.206030, -0.428132, 0.511489, 0.084822, 0.855093, -0.017252, -0.697334, 0.716538, -0.122030, 0.974309, 0.189289, -0.880940, -0.205895, -0.426088, -0.281749, 0.187622, 0.940965, 0.507127, -0.134744, 0.851273, -0.052540, 0.920384, -0.387469, -0.652070, -0.506827, -0.563854, -0.333814, 0.928829, 0.160765, 0.598292, -0.457712, 0.657683, -0.402663, -0.914678, 0.035034, -0.378605, -0.560192, 0.736779, 0.807263, 0.064346, 0.586673, 0.462745, 0.868735, 0.176540, -0.730454, 0.561451, 0.388857, -0.065481, 0.667211, 0.741985, -0.974118, 0.223362, -0.034706, 0.967130, 0.244753, 0.068957, 0.924180, 0.191499, -0.330482, 0.043180, 0.998234, 0.040807, -0.762401, -0.646314, -0.031983, -0.529458, -0.828146, 0.183979, -0.681052, -0.282910, 0.675374, -0.737804, -0.430877, 0.519606, -0.223715, -0.230960, 0.946894, 0.904587, 0.344561, 0.250998, 0.137055, 0.871298, 0.471228, -0.475542, 0.829865, 0.291863, 0.322019, 0.783411, 0.531573, 0.112038, -0.803526, 0.584630, -0.797718, -0.557202, -0.230593, -0.074120, 0.067432, 0.994967, -0.084461, 0.283540, 0.955234, 0.222260, -0.949133, 0.223041, -0.587160, 0.799690, -0.125454, -0.081016, -0.382338, 0.920464, -0.958999, -0.113263, -0.259792, 0.664197, 0.633218, 0.397338, -0.833541, -0.533159, 0.144743, 0.676079, -0.053202, 0.734906, 0.337718, 0.010824, 0.941185, -0.996604, -0.019999, -0.079880, -0.845717, 0.529402, -0.067060, 0.201800, 0.972967, -0.112306, -0.119229, 0.298508, -0.946931, 0.251952, -0.869185, 0.425485, -0.349247, -0.898402, 0.266272, 0.114648, 0.148941, 0.982177, -0.916313, 0.357055, -0.181333, 0.759958, -0.371518, 0.533327, -0.906564, 0.033647, -0.420726, -0.571669, 0.688445, 0.446360, 0.441165, -0.781372, 0.441398, -0.245292, 0.737685, 0.629009, 0.056658, -0.920227, -0.387262, 0.468014, -0.348254, 0.812208, -0.613524, -0.617396, 0.492352, 0.060332, -0.517743, 0.853406, -0.505506, -0.343571, 0.791468, -0.161279, -0.563832, 0.809989, 0.689690, 0.701426, -0.179802, 0.820017, -0.471730, 0.324102, 0.297678, 0.446788, 0.843664, -0.282524, 0.389202, 0.876756, 0.494729, 0.782495, 0.378080, 0.962988, -0.130972, 0.235585, -0.856304, 0.409953, 0.314137, -0.262650, -0.022587, 0.964627, 0.401427, -0.547815, 0.734000, -0.419115, -0.175559, 0.890798, 0.651692, -0.261181, 0.712097, 0.194229, -0.634373, 0.748228, -0.522523, -0.764420, 0.377666, -0.382809, 0.785828, 0.485728, 0.665643, 0.157900, 0.729375, 0.798782, 0.437871, 0.412573, 0.542926, -0.835457, -0.085105, -0.037913, -0.146923, 0.988421, 0.318557, -0.215874, 0.922995, 0.802163, -0.159361, 0.575447, -0.950551, 0.023166, 0.309704, -0.715919, 0.697995, 0.016222, 0.117874, 0.748080, 0.653055, -0.658348, 0.714720, 0.236121, 0.463156, 0.294999, 0.835741, -0.944688, 0.241865, 0.221508, -0.269773, 0.574368, 0.772867}; static float ps145 [435] = { 0.617253, 0.466325, -0.633671, -0.768211, 0.611547, 0.189375, 0.846862, 0.517204, 0.123790, -0.507863, -0.663926, 0.548888, 0.798558, 0.379506, 0.467205, 0.226831, -0.331363, 0.915831, -0.524935, -0.335280, 0.782324, 0.959816, -0.275098, 0.055443, 0.375658, -0.011654, 0.926685, -0.309610, -0.750733, 0.583560, 0.658867, 0.413900, 0.628157, -0.422115, 0.828494, 0.367990, 0.850779, -0.223011, 0.475859, -0.102744, -0.987144, -0.122435, 0.154796, -0.728035, 0.667834, 0.238874, 0.816736, 0.525244, -0.887896, 0.240678, 0.392066, -0.688549, -0.565311, 0.454228, 0.447376, 0.714862, 0.537426, 0.934192, -0.040915, 0.354416, 0.004480, -0.948544, 0.316615, -0.473180, 0.865165, 0.166103, 0.567428, -0.111034, 0.815903, 0.708634, 0.678123, 0.194904, 0.840073, -0.014802, 0.542271, -0.715877, 0.566192, 0.408590, -0.198538, -0.098159, 0.975165, -0.564165, -0.739950, 0.366322, 0.791465, 0.197229, 0.578518, -0.600220, -0.781920, 0.168338, 0.005726, -0.627124, 0.778898, 0.894362, 0.356832, 0.269792, -0.176439, -0.302423, 0.936702, -0.381813, -0.206257, 0.900931, -0.205238, 0.878441, 0.431531, 0.405018, -0.227689, 0.885505, 0.487157, 0.549603, 0.678686, -0.206148, 0.108604, 0.972475, 0.325296, 0.469604, 0.820765, -0.815163, -0.137712, 0.562622, -0.377357, -0.847728, -0.372771, 0.071696, -0.857384, 0.509659, -0.050416, 0.956824, 0.286263, -0.736470, -0.627782, 0.251995, 0.352811, -0.632160, 0.689853, 0.353361, -0.754819, -0.552616, 0.248528, 0.967257, -0.051450, -0.848684, 0.438635, 0.295525, 0.040701, -0.421762, 0.905792, -0.834487, -0.446854, 0.322416, -0.759341, -0.649731, 0.035356, -0.555046, 0.344921, 0.756937, -0.637449, 0.478790, 0.603671, 0.929108, -0.251551, 0.271073, 0.495134, 0.356110, 0.792482, -0.705249, 0.235754, 0.668613, 0.015147, -0.216278, 0.976214, 0.002787, 0.428992, 0.903304, -0.433641, -0.556102, 0.709018, -0.572295, 0.120292, 0.811177, -0.960895, 0.107249, 0.255300, -0.185579, 0.501823, 0.844828, -0.080530, -0.766604, 0.637050, 0.769605, 0.541279, 0.338710, -0.562631, -0.108124, 0.819607, -0.941557, -0.332326, -0.055036, -0.274094, 0.644256, 0.714008, -0.776702, 0.628120, -0.046900, -0.585822, -0.722778, -0.366613, -0.413923, -0.885017, 0.213103, 0.296971, 0.661776, 0.688375, -0.938401, -0.303127, 0.165886, -0.778899, 0.366540, 0.508886, 0.201557, -0.118609, 0.972269, -0.502473, 0.863196, -0.049129, 0.727848, -0.182970, 0.660877, -0.234553, -0.636850, 0.734444, -0.712882, -0.003151, 0.701276, 0.899615, 0.173279, 0.400832, -0.342210, -0.420110, 0.840476, 0.395979, -0.439721, 0.806131, 0.363157, -0.912368, 0.188949, -0.399938, 0.011160, 0.916474, 0.637414, 0.579766, 0.507518, -0.650342, 0.755847, 0.075829, -0.548895, 0.673852, 0.494608, 0.772719, 0.363192, -0.520574, 0.995030, -0.084929, -0.051989, -0.909306, -0.021617, 0.415567, 0.678347, -0.555944, 0.480387, -0.631090, 0.759083, -0.159744, -0.399603, 0.226801, 0.888188, -0.380300, 0.435842, 0.815729, 0.866932, 0.487351, -0.104487, -0.892966, -0.243681, 0.378459, -0.684895, -0.241736, 0.687373, -0.050545, 0.641103, 0.765788, 0.093614, 0.747580, 0.657541, 0.547659, -0.515289, 0.659202, 0.440786, -0.826251, 0.350737, -0.310604, 0.950219, 0.024690, 0.967185, 0.151622, 0.203870, 0.018792, 0.875156, 0.483475, 0.607135, -0.710925, 0.354928, -0.105492, 0.991783, 0.072374, -0.370433, -0.834525, 0.407857, -0.145448, -0.497737, 0.855046, 0.159344, -0.975934, 0.148867, 0.704242, 0.022467, 0.709605, 0.880679, -0.445848, 0.160076, -0.201479, 0.310606, 0.928940, 0.762179, -0.591829, 0.262339, -0.002338, 0.217476, 0.976063, 0.505621, 0.837404, 0.207610, -0.468107, 0.573702, 0.672118, 0.166593, 0.927323, 0.335140, -0.612477, 0.733949, 0.293582, -0.941390, 0.296878, 0.160151, 0.191172, 0.108639, 0.975526, 0.363616, 0.225991, 0.903721, 0.219099, -0.908056, 0.356973, 0.142080, 0.566158, 0.811960, 0.202647, -0.542343, 0.815351, 0.490108, -0.687857, 0.535394, 0.647677, 0.230211, 0.726304, 0.574503, -0.320524, 0.753134, 0.986058, -0.063392, 0.153857, 0.046044, 0.993732, -0.101862, 0.441999, 0.897003, -0.004676, 0.528341, 0.104359, 0.842594, 0.991714, 0.128405, -0.003885, 0.187272, 0.335743, 0.923150, -0.824907, 0.111893, 0.554084, -0.152962, -0.872852, 0.463392, 0.300176, -0.796312, 0.525150, -0.130878, 0.781012, 0.610648, -0.000000, -0.000000, 1.000000, -0.266786, 0.934854, 0.234251, 0.825168, -0.417341, 0.380689, -0.971189, -0.102636, 0.215078, 0.879449, -0.472267, -0.059441, 0.718851, -0.378293, 0.583221, -0.208629, -0.941223, 0.265656, -0.617811, -0.785382, -0.038531, 0.308252, 0.936005, 0.169929}; static float ps146 [438] = { -0.519152, 0.284120, 0.806075, -0.480134, 0.873235, 0.083264, -0.016287, -0.617812, 0.786157, -0.328461, -0.452560, 0.829037, 0.504740, -0.720432, 0.475620, 0.037913, -0.888072, -0.458138, 0.353677, 0.844974, 0.401164, -0.705503, -0.574626, 0.414814, 0.295690, -0.936546, 0.188280, -0.877781, 0.467818, -0.103187, 0.204109, -0.226657, 0.952348, -0.780033, 0.624665, 0.036641, -0.756142, -0.620985, 0.206462, -0.858011, -0.495855, -0.133959, -0.592501, -0.741103, 0.315768, -0.779267, -0.376571, 0.500937, 0.851080, -0.037754, 0.523678, -0.253120, 0.573423, 0.779177, 0.118771, 0.529459, 0.839980, 0.691866, -0.600865, 0.400353, -0.384534, -0.263125, 0.884816, 0.497751, 0.409033, 0.764811, 0.120253, -0.741083, 0.660557, 0.221053, -0.594028, 0.773477, 0.173436, -0.022443, 0.984589, 0.582266, -0.562075, 0.587400, -0.026908, -0.083642, 0.996132, 0.994077, 0.107837, -0.013520, -0.276196, 0.934736, 0.223574, 0.260668, -0.817877, 0.512961, 0.523197, 0.576063, 0.628025, -0.381143, 0.659714, 0.647694, -0.628580, -0.770438, 0.106359, 0.009939, 0.133584, 0.990988, -0.972725, -0.115638, -0.201084, 0.149197, 0.930533, 0.334438, 0.324524, 0.925687, 0.194390, -0.320210, 0.380342, 0.867644, 0.286260, 0.394208, 0.873301, 0.695832, 0.661230, 0.280344, 0.958181, -0.285501, 0.019458, -0.558936, -0.156855, 0.814240, -0.468319, 0.481613, 0.740761, -0.052831, -0.948945, 0.310987, -0.816963, 0.086280, 0.570200, -0.685304, 0.190468, 0.702908, 0.220601, 0.203248, 0.953953, -0.225708, -0.619712, 0.751674, -0.703531, -0.037771, 0.709660, -0.161779, 0.253721, 0.953653, -0.096649, 0.984476, -0.146510, 0.481063, 0.875787, 0.039696, 0.292588, -0.956059, -0.018505, -0.567404, 0.595051, 0.569181, -0.612055, 0.693632, 0.379821, 0.626433, -0.375862, 0.682869, -0.365862, 0.169021, 0.915192, 0.399736, -0.153112, 0.903752, 0.627471, 0.213009, 0.748937, -0.906718, -0.031953, 0.420525, -0.460048, 0.839838, 0.288146, 0.085560, -0.994274, -0.064022, -0.001284, 0.778068, 0.628179, 0.549687, 0.029874, 0.834836, 0.597405, -0.753241, 0.275201, -0.065428, 0.961333, 0.267505, -0.949756, -0.307407, -0.058867, 0.061978, 0.342469, 0.937483, -0.259938, -0.932289, 0.251536, 0.433403, -0.518657, 0.736992, -0.799612, 0.294553, 0.523315, -0.206670, 0.764424, 0.610691, -0.402943, -0.825843, 0.394486, 0.481407, -0.866721, 0.130541, 0.470394, -0.326543, 0.819817, -0.896882, -0.244251, 0.368706, 0.340149, 0.563574, 0.752784, 0.002432, -0.285167, 0.958475, 0.367221, 0.721920, 0.586499, 0.645086, -0.762545, 0.048875, 0.756599, -0.211669, 0.618671, -0.439151, -0.581095, 0.685182, 0.511172, 0.818890, 0.261001, -0.054807, 0.638331, 0.767808, 0.400083, -0.846921, 0.350225, 0.439391, 0.235228, 0.866950, 0.541415, 0.713410, 0.444876, -0.137686, -0.435607, 0.889544, 0.283893, -0.401682, 0.870664, -0.773605, -0.633520, -0.013716, -0.900789, -0.140172, -0.411012, 0.670423, 0.388438, 0.632178, -0.726130, 0.506978, 0.464443, 0.181047, 0.831238, 0.525609, 0.750432, -0.418144, 0.511867, 0.835241, -0.450400, 0.315456, 0.362587, 0.046128, 0.930808, 0.989940, -0.092722, -0.106871, 0.083364, -0.461319, 0.883309, -0.203084, -0.211986, 0.955939, -0.104328, -0.990274, 0.092054, -0.107904, -0.761721, 0.638857, -0.845712, -0.442138, 0.298807, 0.679245, 0.549527, 0.486463, -0.424967, 0.768263, 0.478722, -0.948133, -0.273850, 0.161403, -0.943404, 0.267275, 0.196346, 0.942731, -0.067772, 0.326597, 0.756685, -0.625759, 0.189350, 0.811316, 0.341937, 0.474179, -0.195982, -0.866828, 0.458476, 0.605430, -0.167314, 0.778113, -0.299071, -0.953816, 0.028143, -0.880141, -0.466615, 0.087307, -0.639923, 0.749080, 0.171398, 0.866214, -0.248533, 0.433480, -0.453402, -0.872267, 0.183238, -0.200772, 0.032437, 0.979101, -0.549335, 0.066090, 0.832985, 0.782247, 0.175453, 0.597751, 0.362564, -0.685212, 0.631690, 0.933654, -0.273715, 0.231021, 0.989820, -0.086202, 0.113253, 0.880914, -0.458007, -0.119251, -0.104769, 0.455484, 0.884058, 0.718578, 0.000135, 0.695446, -0.627070, -0.494438, 0.601925, 0.177491, 0.688147, 0.703527, -0.683723, -0.275878, 0.675584, -0.247085, 0.871974, 0.422623, 0.805163, 0.494315, 0.327665, -0.524725, -0.383748, 0.759869, -0.812064, -0.156943, 0.562068, -0.123819, -0.984275, -0.125984, 0.911000, 0.310555, 0.271356, -0.384113, -0.052957, 0.921766, -0.970480, -0.063658, 0.232629, -0.853649, 0.395149, 0.339323, 0.024770, -0.862535, 0.505391, -0.650000, 0.398188, 0.647261, -0.325134, -0.741775, 0.586565, -0.645052, -0.756198, -0.109874, -0.528016, -0.677825, 0.511618, 0.163950, -0.920417, 0.354899, -0.765757, 0.588473, 0.259455, -0.914713, 0.165370, 0.368718}; static float ps147 [441] = { -0.546938, -0.188325, 0.815716, -0.454043, -0.686262, 0.568233, -0.241661, -0.524129, 0.816633, -0.467251, 0.398443, 0.789253, -0.938217, -0.329360, 0.106169, -0.717282, -0.202919, 0.666581, 0.810314, 0.189673, 0.554450, 0.614279, 0.675070, -0.408584, -0.318963, 0.562487, 0.762805, 0.996431, -0.061365, 0.057957, 0.175633, -0.424555, 0.888204, 0.302431, -0.014536, 0.953061, 0.161948, 0.881847, 0.442853, 0.251770, -0.230307, 0.939984, 0.361431, 0.803885, 0.472374, -0.796962, 0.349835, 0.492409, -0.266223, -0.687582, 0.675542, 0.220425, 0.750675, 0.622816, -0.809810, 0.579042, 0.094438, 0.955814, -0.128870, 0.264221, -0.695060, 0.526696, 0.489370, 0.399981, -0.362799, 0.841661, 0.175626, -0.981124, 0.080936, 0.724946, 0.577145, 0.375974, 0.117688, 0.502271, 0.856664, -0.282355, 0.023094, 0.959032, -0.745206, 0.656281, -0.118166, 0.298217, -0.826905, 0.476754, 0.008317, 0.810664, 0.585453, 0.438090, 0.656505, 0.614066, -0.425165, 0.873515, 0.237078, -0.734345, 0.611684, 0.294247, 0.602394, 0.798185, 0.004679, -0.028684, 0.338277, 0.940609, -0.647994, 0.381452, 0.659240, 0.478216, 0.826653, 0.296570, -0.365026, 0.701500, 0.612090, -0.698841, -0.681912, 0.215909, -0.872811, -0.359485, 0.330109, -0.909910, 0.401409, 0.104568, -0.197912, 0.826616, 0.526817, 0.456414, 0.803170, -0.382890, 0.796298, -0.018973, 0.604606, 0.442721, 0.890739, 0.102874, -0.807543, -0.024319, 0.589307, -0.577865, 0.203719, 0.790298, 0.326254, -0.694854, 0.640887, 0.754608, 0.655921, -0.018285, -0.924855, -0.005604, 0.380278, 0.344633, 0.407239, 0.845804, -0.950505, -0.282768, -0.128773, 0.058341, 0.667923, 0.741940, 0.677248, 0.127780, 0.724574, 0.493446, -0.707918, 0.505335, -0.439710, -0.537405, 0.719619, -0.196017, -0.337966, 0.920520, -0.522500, 0.556270, 0.646187, 0.782836, 0.596391, 0.177442, -0.540607, -0.818760, 0.193328, -0.861263, 0.156877, 0.483338, 0.870312, -0.481614, 0.102986, -0.387731, 0.912626, -0.129535, -0.132958, -0.137450, 0.981545, 0.325768, -0.537663, 0.777685, -0.846929, 0.435905, 0.304465, 0.746440, -0.225425, 0.626108, -0.924913, 0.232511, 0.300790, -0.735277, 0.182782, 0.652655, -0.950744, -0.177872, 0.253865, 0.573217, -0.295320, 0.764335, 0.871192, -0.184556, 0.454932, -0.972990, 0.207829, 0.100489, -0.510333, 0.858694, 0.046968, 0.630145, 0.530681, 0.566829, 0.023021, 0.999735, 0.000721, -0.482699, 0.011976, 0.875704, 0.087921, 0.970186, 0.225850, -0.235972, 0.916991, 0.321629, -0.039766, 0.919212, 0.391749, 0.352680, 0.191422, 0.915955, -0.592635, -0.374071, 0.713340, -0.859580, -0.195519, 0.472118, 0.785665, -0.540359, 0.301236, 0.658121, -0.575109, 0.485928, -0.077879, -0.810389, 0.580694, -0.306477, -0.906363, 0.290823, 0.286153, 0.592340, 0.753160, 0.583785, -0.799682, 0.140375, 0.510371, 0.058030, 0.857994, 0.020649, -0.291988, 0.956199, -0.113589, -0.916369, 0.383883, 0.906919, 0.027412, 0.420412, -0.755910, -0.371854, 0.538818, -0.758615, -0.526541, 0.383741, -0.154917, 0.696371, 0.700763, -0.881983, -0.469590, -0.039888, 0.786902, 0.391420, 0.477049, 0.134531, 0.126923, 0.982747, 0.643009, -0.086025, 0.761012, 0.792528, -0.391281, 0.467759, -0.097887, 0.532859, 0.840523, 0.033838, -0.970881, 0.237159, 0.635301, -0.702964, 0.319742, -0.404082, -0.364156, 0.839112, -0.659350, -0.004509, 0.751822, 0.525580, 0.273643, 0.805534, -0.618864, -0.534799, 0.575324, 0.130865, -0.616922, 0.776068, -0.305701, 0.948853, 0.078904, 0.954491, -0.281674, 0.098016, 0.454176, -0.148833, 0.878392, -0.057684, 0.069151, 0.995937, 0.654153, -0.420676, 0.628582, 0.864762, 0.422281, 0.271781, 0.903882, 0.233704, 0.358302, 0.893181, -0.344724, 0.288780, 0.983646, -0.021238, -0.178855, 0.090893, -0.890736, 0.445340, -0.592512, 0.758421, 0.271526, -0.384333, -0.918367, 0.094287, 0.498360, 0.478242, 0.723133, -0.561228, 0.681377, 0.469839, -0.398451, 0.807983, 0.434052, 0.174943, 0.316604, 0.932286, -0.113587, 0.980370, 0.161162, 0.125229, -0.769934, 0.625715, 0.973342, 0.086840, 0.212283, -0.068507, -0.666700, 0.742171, -0.234919, -0.970120, -0.060666, 0.502015, -0.545108, 0.671445, 0.673042, 0.336694, 0.658523, -0.188787, 0.217651, 0.957595, -0.838817, -0.515644, 0.174634, 0.245151, -0.925237, 0.289546, 0.453484, -0.830362, 0.323807, -0.350693, -0.174454, 0.920098, 0.287765, 0.918284, 0.271930, -0.675605, 0.733421, 0.075181, -0.164819, -0.974433, 0.152690, 0.640125, 0.739443, 0.208482, 0.275389, 0.818949, -0.503471, -0.394241, 0.215257, 0.893442, 0.565324, 0.698264, 0.439131, -0.258769, 0.399102, 0.879634, 0.093069, -0.092597, 0.991345, 0.990461, 0.135750, -0.023648, -0.034558, -0.489573, 0.871277}; static float ps148 [444] = { 0.239476, -0.697006, 0.675895, 0.902823, -0.413898, 0.116617, 0.424033, -0.440315, 0.791403, -0.053212, 0.635067, 0.770622, -0.794566, 0.296971, 0.529597, 0.570766, -0.116612, 0.812790, -0.412944, 0.140420, 0.899866, -0.579184, 0.598154, 0.553857, 0.573503, 0.471068, 0.670216, 0.859844, -0.229739, 0.455948, 0.599474, -0.503351, 0.622308, 0.790127, 0.517550, 0.328393, -0.384183, 0.693515, 0.609459, 0.043654, -0.668307, 0.742603, -0.897715, -0.246054, 0.365464, -0.576860, 0.042375, 0.815743, -0.974159, 0.225340, -0.015349, 0.781260, 0.181542, 0.597223, 0.057793, 0.764601, 0.641908, -0.550315, 0.796948, 0.249050, -0.868939, -0.073090, 0.489493, -0.275221, 0.594522, 0.755511, -0.660469, -0.261233, 0.703945, -0.665225, -0.733409, 0.139956, -0.720381, -0.063255, 0.690689, 0.195803, 0.047549, 0.979490, -0.904642, 0.144745, 0.400839, -0.147634, 0.937264, 0.315818, -0.689650, 0.719489, -0.081964, 0.936405, -0.061992, 0.345402, 0.634031, -0.714811, 0.295042, 0.392779, -0.032632, 0.919054, -0.202282, 0.022325, 0.979073, -0.708293, 0.692553, 0.136720, 0.466161, 0.344174, 0.815008, 0.281808, 0.918179, 0.278445, 0.682617, 0.686796, 0.249691, -0.349817, 0.385446, 0.853850, -0.990518, 0.046462, -0.129286, 0.347484, -0.779566, 0.521087, -0.377546, 0.925990, 0.000923, -0.533192, -0.164790, 0.829789, 0.824657, -0.565549, -0.009782, 0.429109, -0.611271, 0.664991, 0.174769, 0.617762, 0.766698, -0.360141, -0.295272, 0.884937, -0.877507, 0.349824, 0.328031, 0.064339, -0.962422, 0.263827, -0.960738, -0.137426, -0.241033, 0.544455, -0.680667, 0.490164, -0.811038, 0.533770, 0.239391, -0.213420, 0.893610, -0.394860, -0.299902, -0.693840, 0.654710, -0.070392, -0.993147, 0.093292, -0.170485, -0.405870, 0.897889, -0.157689, 0.467373, 0.869883, -0.020379, 0.993435, 0.112567, -0.563126, -0.761406, 0.321171, 0.745042, -0.375103, 0.551552, -0.963446, -0.208743, 0.167923, -0.624644, -0.619948, 0.474851, -0.665622, 0.654469, 0.358631, 0.109197, -0.816593, 0.566791, -0.579959, -0.812201, -0.063066, -0.913963, 0.390558, 0.110161, -0.379747, -0.550393, -0.743545, -0.166021, -0.942976, 0.288502, 0.273458, 0.417331, 0.866635, -0.984682, -0.170464, -0.036665, 0.922108, 0.337518, 0.189203, 0.411207, -0.245912, 0.877745, 0.187429, 0.977787, 0.093825, 0.276561, 0.732306, 0.622287, -0.515610, 0.842604, -0.155450, -0.440505, -0.747547, 0.497120, -0.045614, 0.312693, 0.948758, -0.374182, -0.873010, 0.312796, -0.524993, 0.293304, 0.798972, 0.225070, -0.360521, 0.905190, 0.940829, -0.243033, 0.236168, -0.280263, 0.843013, 0.459109, 0.356366, 0.190490, 0.914722, 0.822250, 0.560176, -0.100538, -0.487418, -0.586709, 0.646682, -0.377581, -0.070893, 0.923259, 0.787935, -0.577181, 0.214523, 0.734941, 0.676074, 0.052783, -0.746675, 0.486150, 0.454021, 0.018439, -0.297336, 0.954595, -0.227565, 0.965409, 0.127275, -0.891459, -0.131290, -0.433663, 0.845411, 0.518878, 0.126670, 0.859260, 0.331238, 0.389812, 0.832346, -0.039387, 0.552855, -0.102067, -0.773071, 0.626054, 0.033258, 0.895636, -0.443543, -0.471722, 0.507687, 0.720925, -0.389969, -0.918027, -0.071766, 0.664949, 0.565589, 0.487804, 0.739329, 0.383800, 0.553254, 0.068182, 0.477146, 0.876175, -0.784532, -0.443731, 0.433142, 0.069074, 0.950718, 0.302266, -0.012545, 0.113746, 0.993431, 0.163938, 0.864900, 0.474417, 0.877553, 0.414785, -0.240527, -0.476353, 0.762490, 0.437833, 0.030318, -0.491493, 0.870353, 0.152362, -0.985640, 0.072802, -0.245315, -0.841422, 0.481487, -0.550925, 0.832848, 0.053350, -0.234406, 0.230809, 0.944341, -0.053673, 0.870184, 0.489795, -0.149567, -0.601486, 0.784757, 0.712034, -0.556036, 0.428756, -0.173158, 0.755849, 0.631434, 0.696000, 0.027196, 0.717526, -0.804953, 0.092886, 0.586023, -0.996432, 0.011193, 0.083649, -0.487617, -0.863472, 0.129019, -0.185534, -0.195178, 0.963059, 0.441780, -0.827312, 0.346966, 0.845593, -0.411315, 0.340283, 0.370092, 0.814445, 0.446890, 0.486194, 0.837627, 0.248989, 0.306138, -0.929277, 0.206697, 0.536945, 0.110072, 0.836406, 0.590324, -0.323025, 0.739711, -0.336220, -0.509051, 0.792353, -0.646809, 0.406911, 0.645029, -0.371733, 0.892206, 0.256482, 0.159931, 0.262348, 0.951628, 0.006290, -0.092908, 0.995655, -0.657009, -0.452260, 0.603158, 0.926020, 0.376433, -0.028005, 0.558741, 0.722765, 0.406719, -0.961680, 0.189118, 0.198511, -0.792597, -0.259309, 0.551859, 0.475785, 0.653826, 0.588336, -0.956241, -0.030663, 0.290970, 0.214027, -0.162149, 0.963276, -0.678257, 0.193364, 0.708927, 0.637372, 0.263007, 0.724282, -0.740343, -0.603306, 0.296503, 0.234726, -0.540290, 0.808078, 0.728387, -0.188349, 0.658769, 0.286809, 0.951215, -0.113715, -0.508825, -0.395245, 0.764773}; static float ps149 [447] = { 0.585047, -0.203522, 0.785047, 0.025353, 0.238936, 0.970704, -0.474544, -0.857743, 0.197697, -0.848727, 0.444133, 0.287068, -0.737135, -0.467882, 0.487563, -0.154833, -0.702164, 0.694977, 0.783319, 0.172777, 0.597126, -0.410308, 0.584956, 0.699624, -0.729473, 0.514700, 0.450504, 0.550730, 0.003220, 0.834677, 0.220259, 0.972683, 0.073300, 0.714163, -0.586026, 0.382811, 0.056254, -0.971485, 0.230330, -0.214319, 0.960510, 0.177451, -0.714506, 0.699627, 0.001855, 0.967268, 0.149948, 0.204714, 0.897409, -0.419436, 0.136861, 0.788960, 0.548340, -0.277247, -0.542569, 0.644559, 0.538667, -0.890701, -0.437667, 0.122880, -0.952838, -0.242066, 0.183039, -0.001546, -0.886881, 0.461995, -0.902531, 0.065583, 0.425602, 0.279376, -0.940590, 0.192974, -0.015404, 0.732237, 0.680876, 0.000000, 0.000000, 1.000000, -0.867583, -0.360378, 0.342677, 0.225760, -0.315805, 0.921574, 0.382229, -0.835462, 0.394846, 0.559937, -0.726040, 0.399169, -0.274915, 0.486736, 0.829162, 0.471480, -0.857424, 0.206230, 0.898129, 0.158699, 0.410096, 0.738206, -0.413525, 0.532963, 0.355602, -0.934637, -0.001400, 0.787163, -0.589822, 0.180235, 0.839918, -0.420003, 0.343708, -0.158524, -0.321030, 0.933708, 0.992113, -0.096635, -0.079831, -0.647526, -0.727440, 0.227025, 0.030756, -0.770075, 0.637211, 0.820016, 0.346231, 0.455740, -0.323195, -0.873418, 0.364261, -0.542477, -0.602441, 0.585478, -0.471405, 0.795447, 0.380844, -0.137415, -0.941785, 0.306853, 0.310626, 0.454348, 0.834913, 0.202204, -0.113702, 0.972721, 0.367506, 0.031713, 0.929480, -0.149794, 0.828157, 0.540110, -0.495818, -0.769808, 0.401946, -0.738665, 0.353571, 0.573900, -0.649974, -0.636031, 0.415931, -0.862338, -0.498804, -0.086992, -0.859997, 0.286442, 0.422323, 0.020717, -0.221973, 0.974833, 0.800423, 0.524248, 0.290666, 0.934345, -0.235455, 0.267506, 0.841665, -0.029250, 0.539207, 0.629923, 0.190239, 0.752998, 0.091159, 0.432766, 0.896885, -0.176733, -0.101766, 0.978984, -0.496512, 0.157225, 0.853672, 0.136876, 0.948360, 0.286142, -0.425453, -0.904894, -0.012523, 0.260387, 0.864212, 0.430507, 0.501880, 0.381949, 0.776036, 0.643338, -0.738265, 0.202685, -0.278059, 0.883918, 0.375995, -0.127275, 0.370018, 0.920265, 0.236331, -0.666898, 0.706678, -0.545374, 0.838116, -0.011317, 0.854866, -0.231155, 0.464512, -0.519398, -0.274077, 0.809387, 0.711147, -0.015055, 0.702882, -0.350930, 0.753757, 0.555606, -0.082238, -0.993489, 0.078845, 0.423458, -0.371305, 0.826327, -0.187842, -0.829703, 0.525650, 0.035874, -0.429636, 0.902289, 0.379701, 0.739632, 0.555673, 0.140960, -0.989638, 0.027312, -0.216388, 0.674592, 0.705763, -0.488948, -0.473008, 0.732935, 0.540026, 0.534303, 0.650302, -0.151254, -0.526909, 0.836355, 0.349424, 0.910130, 0.222635, 0.613736, 0.788884, -0.031467, 0.775806, 0.626035, -0.078778, -0.679174, -0.169457, 0.714148, 0.185186, 0.755643, 0.628260, -0.553357, -0.816032, -0.166994, -0.904626, -0.154805, 0.397099, -0.164086, 0.138870, 0.976622, 0.681364, 0.363094, 0.635535, -0.927695, 0.354258, 0.117829, 0.404595, -0.175479, 0.897502, 0.936195, -0.038731, 0.349339, 0.988788, -0.048839, 0.141115, 0.903620, 0.343545, 0.255828, 0.417584, -0.706642, 0.571210, -0.330841, -0.602514, 0.726307, -0.463254, 0.381789, 0.799771, 0.143732, 0.606333, 0.782114, -0.789317, 0.150016, 0.595377, -0.644341, 0.674968, 0.359504, 0.040169, -0.614613, 0.787805, 0.445011, 0.212801, 0.869874, -0.993854, -0.109356, 0.017215, -0.591336, 0.475254, 0.651503, -0.669628, 0.045299, 0.741314, -0.810136, -0.058903, 0.583275, 0.706582, 0.517242, 0.482910, 0.658562, 0.684698, 0.312226, -0.945775, 0.199277, 0.256512, -0.072938, 0.936669, 0.342536, -0.652307, -0.382517, 0.654352, -0.762905, 0.613677, 0.203410, 0.967466, -0.247109, 0.054286, -0.796792, -0.267484, 0.541826, 0.185253, -0.907086, 0.377989, 0.220448, -0.803562, 0.552894, 0.253911, 0.283582, 0.924722, -0.603123, 0.777102, 0.179872, 0.591716, -0.574700, 0.565324, -0.521891, -0.061833, 0.850768, 0.597220, -0.398712, 0.695958, 0.950657, 0.307340, 0.042343, -0.419495, 0.886576, 0.194955, -0.631253, 0.259356, 0.730926, -0.369551, -0.735626, 0.567703, -0.970285, -0.033710, 0.239605, 0.730372, 0.672568, 0.119203, -0.343989, 0.033653, 0.938370, 0.847927, -0.528908, -0.035725, -0.068250, 0.564289, 0.822752, -0.284327, -0.947333, 0.147371, -0.318790, 0.268441, 0.909017, 0.352109, 0.608170, 0.711441, 0.055267, 0.866287, 0.496480, -0.352701, -0.193036, 0.915608, -0.330939, -0.404101, 0.852750, 0.428720, -0.550420, 0.716405, -0.001143, -0.991242, -0.132057, 0.180746, 0.100830, 0.978348, 0.236839, -0.502445, 0.831539, 0.560302, 0.664561, 0.494388, 0.736773, -0.220496, 0.639177, 0.466801, 0.807250, 0.361171}; static float ps150 [450] = { 0.374279, -0.424123, 0.824642, -0.791503, 0.045115, 0.609498, 0.525612, -0.692064, 0.494751, 0.844951, -0.487953, 0.218996, -0.031644, 0.612132, 0.790123, 0.282933, -0.224262, 0.932553, -0.232227, 0.018381, 0.972488, 0.716004, 0.586129, 0.379197, -0.826546, -0.399099, -0.396916, -0.394386, 0.393754, 0.830311, 0.469957, -0.234236, 0.851043, 0.572009, -0.762428, 0.302504, 0.523251, 0.502874, 0.687988, -0.130149, -0.543965, 0.828953, -0.754087, -0.532113, 0.384979, -0.098429, 0.185759, 0.977653, -0.495041, -0.517748, 0.697762, -0.530911, 0.224519, 0.817144, -0.085251, -0.712047, 0.696937, 0.530782, 0.159277, 0.832407, -0.211466, 0.531823, 0.820028, -0.555591, -0.145110, 0.818695, -0.621193, -0.344665, 0.703793, 0.326207, -0.738114, 0.590573, -0.326282, -0.486708, 0.810343, -0.972887, 0.058169, 0.223845, -0.801453, 0.561822, 0.205012, 0.705384, -0.608003, 0.364369, 0.210000, -0.015507, 0.977578, 0.976200, -0.150784, 0.155876, -0.248218, -0.795307, 0.553059, -0.559189, -0.639677, -0.527372, 0.911774, -0.287568, 0.293212, 0.032950, 0.844252, -0.534933, -0.263612, -0.963448, 0.047714, -0.596185, -0.696626, 0.399093, -0.116482, -0.973528, 0.196661, 0.230071, -0.933261, 0.275848, 0.254717, 0.954932, 0.152395, -0.293831, -0.655187, 0.695984, 0.905612, 0.186759, 0.380772, -0.831550, 0.239292, 0.501263, -0.698462, 0.235613, 0.675749, 0.972112, 0.230809, 0.041541, -0.185489, 0.837299, 0.514320, -0.396421, 0.576248, 0.714695, -0.976240, 0.205487, 0.068778, -0.205327, 0.700458, 0.683520, 0.239706, 0.347733, 0.906434, -0.700405, 0.577321, 0.419683, 0.735755, -0.658492, 0.158281, -0.028410, 0.937283, -0.347409, -0.568084, 0.415816, 0.710195, -0.999894, 0.006905, -0.012841, 0.457042, -0.586145, 0.668990, 0.571526, 0.745212, 0.343535, 0.404299, 0.877308, 0.258600, 0.691386, 0.459969, 0.557148, 0.334296, 0.526631, 0.781604, 0.929749, 0.327039, -0.169149, 0.396209, 0.794837, 0.459622, 0.135107, 0.515845, 0.845961, -0.832315, 0.417886, 0.364175, -0.715790, -0.153378, 0.681263, 0.354076, -0.855640, -0.377506, 0.661130, -0.704579, -0.257827, -0.640600, -0.766817, 0.040293, -0.279755, 0.958891, -0.047590, 0.179566, -0.857709, 0.481758, -0.190308, -0.903066, 0.385038, -0.637619, -0.536603, 0.552720, 0.836079, -0.548599, 0.003435, 0.788476, 0.260197, 0.557318, -0.460422, -0.684627, 0.565064, -0.454600, 0.030883, 0.890160, 0.172978, 0.678667, 0.713785, 0.375523, 0.676276, 0.633746, 0.831212, 0.517080, 0.204242, 0.412999, -0.034420, 0.910081, 0.936315, -0.053213, 0.347106, -0.532860, -0.817359, 0.219056, -0.194987, 0.358050, 0.913116, -0.448909, -0.893392, 0.018194, -0.408880, -0.816595, 0.407419, 0.116265, 0.189934, 0.974888, -0.902411, 0.049355, 0.428039, 0.647362, -0.524953, 0.552582, -0.560885, 0.588764, 0.582035, 0.597241, -0.032462, 0.801405, 0.067568, 0.997302, 0.028683, -0.705305, -0.674230, 0.218996, 0.900328, 0.434824, 0.018365, 0.639381, -0.223325, 0.735743, 0.441595, 0.346941, 0.827421, 0.420482, -0.886204, 0.194517, -0.981729, -0.129669, 0.139261, -0.922820, 0.242337, 0.299458, -0.333148, 0.199180, 0.921596, 0.083952, -0.206037, 0.974936, -0.126146, -0.170108, 0.977318, 0.122580, -0.740029, 0.661311, 0.788441, 0.615061, -0.007782, -0.511278, 0.831473, 0.217364, 0.838516, 0.510511, -0.190447, -0.468262, 0.883086, 0.029840, -0.920931, -0.322138, -0.219349, 0.179468, -0.412464, 0.893121, 0.856941, -0.194004, 0.477508, -0.451101, -0.322527, 0.832156, -0.377443, 0.733599, 0.565128, 0.068772, -0.580535, 0.811326, -0.343067, -0.910370, 0.231368, 0.737852, -0.329679, 0.588970, -0.594916, 0.798024, -0.096087, -0.317021, 0.931610, 0.177763, 0.804103, -0.423027, 0.417692, -0.929921, -0.147241, 0.336997, 0.711821, 0.115269, 0.692838, 0.199858, 0.808773, 0.553121, -0.530205, 0.734664, 0.423264, -0.861782, -0.348066, 0.369029, -0.023917, -0.383307, 0.923311, 0.335085, 0.161860, 0.928181, 0.085401, -0.988335, 0.126096, 0.217496, 0.905007, 0.365594, 0.004586, 0.384883, 0.922954, 0.693369, -0.718029, -0.060611, 0.852506, 0.047150, 0.520586, 0.975166, 0.089533, 0.202569, 0.908696, -0.392493, -0.142200, -0.000000, -0.000000, 1.000000, 0.559733, -0.413976, 0.717860, -0.152095, 0.934762, 0.321071, 0.552228, 0.821940, 0.139497, -0.349857, -0.153418, 0.924155, 0.265503, -0.596463, 0.757456, 0.382462, -0.831923, 0.402028, 0.017533, 0.891512, 0.452657, -0.126277, 0.986461, 0.104641, -0.230456, -0.335819, 0.913299, -0.840467, -0.155538, 0.519060, 0.930936, -0.357095, 0.076427, 0.762964, -0.090396, 0.640090, 0.630645, 0.314236, 0.709608, -0.757463, -0.354123, 0.548495, -0.717977, 0.416861, 0.557437, -0.007117, 0.773287, 0.634016, 0.707381, 0.684348, 0.176858, -0.642336, 0.044540, 0.765127, -0.049101, -0.968407, -0.244494}; //static float ps246 [738] = { -0.996801000000, 0.000000000000, 0.079922200000, 0.992869000000, 0.090802700000, 0.077241400000, 0.992869000000, -0.090802700000, 0.077241400000, -0.979656000000, -0.184676000000, 0.078547500000, -0.979656000000, 0.184676000000, 0.078547500000, 0.975263000000, -0.000000000000, 0.221047000000, -0.966274000000, -0.093954200000, 0.239767000000, -0.966274000000, 0.093954200000, 0.239767000000, 0.961659000000, 0.263845000000, 0.074813400000, 0.961659000000, -0.263845000000, 0.074813400000, 0.960950000000, 0.170695000000, 0.217803000000, 0.960950000000, -0.170695000000, 0.217803000000, 0.935659000000, 0.080770400000, 0.343537000000, 0.935659000000, -0.080770400000, 0.343537000000, -0.933862000000, -0.272408000000, 0.231724000000, -0.933862000000, 0.272408000000, 0.231724000000, -0.933083000000, -0.351794000000, 0.074813400000, -0.933083000000, 0.351794000000, 0.074813400000, -0.919651000000, 0.000000000000, 0.392738000000, 0.915627000000, 0.328527000000, 0.231724000000, 0.915627000000, -0.328527000000, 0.231724000000, -0.904358000000, -0.181605000000, 0.386207000000, -0.904358000000, 0.181605000000, 0.386207000000, 0.901581000000, 0.226771000000, 0.368411000000, 0.901581000000, -0.226771000000, 0.368411000000, 0.901108000000, 0.426421000000, 0.078547500000, 0.901108000000, -0.426421000000, 0.078547500000, 0.894427000000, -0.000000000000, 0.447214000000, -0.877757000000, -0.426737000000, 0.217803000000, -0.877757000000, 0.426737000000, 0.217803000000, 0.866952000000, 0.130689000000, 0.480952000000, 0.866952000000, -0.130689000000, 0.480952000000, -0.862687000000, -0.346475000000, 0.368411000000, -0.862687000000, 0.346475000000, 0.368411000000, -0.856620000000, -0.510133000000, 0.077241400000, -0.856620000000, 0.510133000000, 0.077241400000, -0.847355000000, -0.087948400000, 0.523694000000, -0.847355000000, 0.087948400000, 0.523694000000, 0.838386000000, 0.384646000000, 0.386207000000, 0.838386000000, -0.384646000000, 0.386207000000, 0.836957000000, 0.491951000000, 0.239767000000, 0.836957000000, -0.491951000000, 0.239767000000, 0.824489000000, -0.000000000000, 0.565879000000, -0.822295000000, -0.256042000000, 0.508206000000, -0.822295000000, 0.256042000000, 0.508206000000, 0.815748000000, 0.276190000000, 0.508206000000, 0.815748000000, -0.276190000000, 0.508206000000, 0.806429000000, 0.585905000000, 0.079922200000, 0.806429000000, -0.585905000000, 0.079922200000, -0.804440000000, -0.484622000000, 0.343537000000, -0.804440000000, 0.484622000000, 0.343537000000, -0.789005000000, -0.573245000000, 0.221047000000, -0.789005000000, 0.573245000000, 0.221047000000, 0.782361000000, 0.140152000000, 0.606852000000, 0.782361000000, -0.140152000000, 0.606852000000, -0.778196000000, -0.403852000000, 0.480952000000, -0.778196000000, 0.403852000000, 0.480952000000, -0.762555000000, 0.000000000000, 0.646923000000, -0.749875000000, -0.657055000000, 0.077241400000, -0.749875000000, -0.181605000000, 0.636165000000, -0.749875000000, 0.181605000000, 0.636165000000, -0.749875000000, 0.657055000000, 0.077241400000, 0.744013000000, 0.540557000000, 0.392738000000, 0.744013000000, -0.540557000000, 0.392738000000, 0.737219000000, 0.426911000000, 0.523694000000, 0.737219000000, -0.426911000000, 0.523694000000, 0.726507000000, 0.643972000000, 0.239767000000, 0.726507000000, -0.643972000000, 0.239767000000, 0.726009000000, -0.000000000000, 0.687685000000, -0.723607000000, -0.525731000000, 0.447214000000, -0.723607000000, 0.525731000000, 0.447214000000, -0.715322000000, -0.346475000000, 0.606852000000, -0.715322000000, 0.346475000000, 0.606852000000, 0.713407000000, 0.293844000000, 0.636165000000, 0.713407000000, -0.293844000000, 0.636165000000, -0.709489000000, -0.615311000000, 0.343537000000, -0.709489000000, 0.615311000000, 0.343537000000, 0.684008000000, 0.725233000000, 0.078547500000, 0.684008000000, -0.725233000000, 0.078547500000, -0.677093000000, -0.702927000000, 0.217803000000, -0.677093000000, 0.702927000000, 0.217803000000, -0.667025000000, -0.484622000000, 0.565879000000, -0.667025000000, 0.484622000000, 0.565879000000, 0.665669000000, 0.146922000000, 0.731641000000, 0.665669000000, -0.146922000000, 0.731641000000, -0.646585000000, -0.093954200000, 0.757034000000, -0.646585000000, 0.093954200000, 0.757034000000, 0.633829000000, 0.569214000000, 0.523694000000, 0.633829000000, -0.569214000000, 0.523694000000, 0.624896000000, 0.678490000000, 0.386207000000, -0.624896000000, -0.272408000000, 0.731641000000, -0.624896000000, 0.272408000000, 0.731641000000, 0.624896000000, -0.678490000000, 0.386207000000, -0.624562000000, -0.615311000000, 0.480952000000, -0.624562000000, 0.615311000000, 0.480952000000, -0.622914000000, -0.778705000000, 0.074813400000, -0.622914000000, 0.778705000000, 0.074813400000, 0.616920000000, 0.448219000000, 0.646923000000, 0.616920000000, -0.448219000000, 0.646923000000, 0.598507000000, -0.000000000000, 0.801117000000, -0.596102000000, -0.713397000000, 0.368411000000, -0.596102000000, 0.713397000000, 0.368411000000, 0.595392000000, 0.769293000000, 0.231724000000, 0.595392000000, -0.769293000000, 0.231724000000, -0.587353000000, -0.426737000000, 0.687685000000, -0.587353000000, 0.426737000000, 0.687685000000, 0.578323000000, 0.304042000000, 0.757034000000, 0.578323000000, -0.304042000000, 0.757034000000, -0.550564000000, -0.573245000000, 0.606852000000, -0.550564000000, 0.573245000000, 0.606852000000, 0.548101000000, 0.833060000000, 0.074813400000, 0.548101000000, -0.833060000000, 0.074813400000, -0.547655000000, -0.803977000000, 0.231724000000, -0.547655000000, 0.803977000000, 0.231724000000, 0.519830000000, 0.149406000000, 0.841103000000, 0.519830000000, -0.149406000000, 0.841103000000, -0.517268000000, 0.000000000000, 0.855824000000, 0.514753000000, 0.690475000000, 0.508206000000, 0.514753000000, -0.690475000000, 0.508206000000, -0.508370000000, -0.184676000000, 0.841103000000, -0.508370000000, 0.184676000000, 0.841103000000, 0.499917000000, 0.587688000000, 0.636165000000, 0.499917000000, -0.587688000000, 0.636165000000, -0.497614000000, -0.702927000000, 0.508206000000, -0.497614000000, 0.702927000000, 0.508206000000, 0.494276000000, 0.787378000000, 0.368411000000, 0.494276000000, -0.787378000000, 0.368411000000, -0.484203000000, -0.351794000000, 0.801117000000, -0.484203000000, 0.351794000000, 0.801117000000, -0.478368000000, -0.874640000000, 0.078547500000, -0.478368000000, 0.874640000000, 0.078547500000, 0.467873000000, 0.456063000000, 0.757034000000, 0.467873000000, -0.456063000000, 0.757034000000, 0.459290000000, 0.861170000000, 0.217803000000, 0.459290000000, -0.861170000000, 0.217803000000, -0.452179000000, -0.803977000000, 0.386207000000, -0.452179000000, -0.510133000000, 0.731641000000, -0.452179000000, 0.510133000000, 0.731641000000, -0.452179000000, 0.803977000000, 0.386207000000, 0.448881000000, -0.000000000000, 0.893592000000, 0.418478000000, 0.304042000000, 0.855824000000, 0.418478000000, -0.304042000000, 0.855824000000, -0.404441000000, -0.657055000000, 0.636165000000, -0.404441000000, 0.657055000000, 0.636165000000, 0.393172000000, 0.916215000000, 0.077241400000, 0.393172000000, -0.916215000000, 0.077241400000, 0.392196000000, 0.784135000000, 0.480952000000, 0.392196000000, -0.784135000000, 0.480952000000, -0.387951000000, -0.889947000000, 0.239767000000, -0.387951000000, 0.889947000000, 0.239767000000, 0.375055000000, 0.700760000000, 0.606852000000, 0.375055000000, -0.700760000000, 0.606852000000, -0.374938000000, -0.090802700000, 0.922592000000, -0.374938000000, 0.090802700000, 0.922592000000, 0.365952000000, 0.864906000000, 0.343537000000, 0.365952000000, -0.864906000000, 0.343537000000, -0.363152000000, -0.263845000000, 0.893592000000, -0.363152000000, 0.263845000000, 0.893592000000, 0.356703000000, 0.146922000000, 0.922592000000, 0.356703000000, -0.146922000000, 0.922592000000, -0.345491000000, -0.778705000000, 0.523694000000, -0.345491000000, 0.778705000000, 0.523694000000, 0.345434000000, 0.587688000000, 0.731641000000, 0.345434000000, -0.587688000000, 0.731641000000, -0.332733000000, -0.426421000000, 0.841103000000, -0.332733000000, 0.426421000000, 0.841103000000, -0.308028000000, -0.948014000000, 0.079922200000, -0.308028000000, 0.948014000000, 0.079922200000, 0.302730000000, 0.448219000000, 0.841103000000, 0.302730000000, -0.448219000000, 0.841103000000, 0.301373000000, 0.927530000000, 0.221047000000, 0.301373000000, -0.927530000000, 0.221047000000, 0.290404000000, -0.000000000000, 0.956904000000, -0.289161000000, -0.585905000000, 0.757034000000, -0.289161000000, 0.585905000000, 0.757034000000, -0.284188000000, -0.874640000000, 0.392738000000, -0.284188000000, 0.874640000000, 0.392738000000, 0.276393000000, 0.850651000000, 0.447214000000, 0.276393000000, -0.850651000000, 0.447214000000, 0.254781000000, 0.784135000000, 0.565879000000, 0.254781000000, -0.784135000000, 0.565879000000, 0.249958000000, 0.293844000000, 0.922592000000, 0.249958000000, -0.293844000000, 0.922592000000, -0.238441000000, 0.000000000000, 0.971157000000, -0.235643000000, -0.725233000000, 0.646923000000, -0.235643000000, 0.725233000000, 0.646923000000, -0.234941000000, -0.170695000000, 0.956904000000, -0.234941000000, 0.170695000000, 0.956904000000, 0.224349000000, 0.690475000000, 0.687685000000, 0.224349000000, -0.690475000000, 0.687685000000, 0.220455000000, 0.972334000000, 0.077241400000, 0.220455000000, -0.972334000000, 0.077241400000, 0.212317000000, 0.914824000000, 0.343537000000, 0.212317000000, -0.914824000000, 0.343537000000, -0.209239000000, -0.948014000000, 0.239767000000, -0.209239000000, 0.948014000000, 0.239767000000, -0.202221000000, -0.328527000000, 0.922592000000, -0.202221000000, 0.328527000000, 0.922592000000, 0.192903000000, 0.140152000000, 0.971157000000, 0.192903000000, -0.140152000000, 0.971157000000, 0.184949000000, 0.569214000000, 0.801117000000, 0.184949000000, -0.569214000000, 0.801117000000, -0.178203000000, -0.833060000000, 0.523694000000, -0.178203000000, 0.833060000000, 0.523694000000, -0.159844000000, -0.491951000000, 0.855824000000, -0.159844000000, 0.491951000000, 0.855824000000, 0.143610000000, 0.864906000000, 0.480952000000, 0.143610000000, -0.864906000000, 0.480952000000, 0.138712000000, 0.426911000000, 0.893592000000, 0.138712000000, -0.426911000000, 0.893592000000, 0.137415000000, -0.000000000000, 0.990514000000, 0.134609000000, 0.966666000000, 0.217803000000, 0.134609000000, -0.966666000000, 0.217803000000, -0.127093000000, -0.988776000000, 0.078547500000, -0.127093000000, 0.988776000000, 0.078547500000, -0.111171000000, -0.080770400000, 0.990514000000, -0.111171000000, 0.080770400000, 0.990514000000, -0.110450000000, -0.643972000000, 0.757034000000, -0.110450000000, 0.643972000000, 0.757034000000, 0.108470000000, 0.787378000000, 0.606852000000, 0.108470000000, -0.787378000000, 0.606852000000, -0.106745000000, -0.916215000000, 0.386207000000, -0.106745000000, 0.916215000000, 0.386207000000, 0.089739600000, 0.276190000000, 0.956904000000, 0.089739600000, -0.276190000000, 0.956904000000, -0.073682200000, -0.226771000000, 0.971157000000, -0.073682200000, 0.226771000000, 0.971157000000, 0.065972000000, 0.678490000000, 0.731641000000, 0.065972000000, -0.678490000000, 0.731641000000, 0.062932200000, 0.927530000000, 0.368411000000, 0.062932200000, -0.927530000000, 0.368411000000, -0.059007200000, -0.769293000000, 0.636165000000, -0.059007200000, 0.769293000000, 0.636165000000, 0.046237200000, 0.996125000000, 0.074813400000, 0.046237200000, -0.996125000000, 0.074813400000, 0.042463500000, 0.130689000000, 0.990514000000, 0.042463500000, -0.130689000000, 0.990514000000, -0.029503600000, -0.972334000000, 0.231724000000, -0.029503600000, -0.384646000000, 0.922592000000, -0.029503600000, 0.384646000000, 0.922592000000, -0.029503600000, 0.972334000000, 0.231724000000, 0.018542600000, 0.540557000000, 0.841103000000, 0.018542600000, -0.540557000000, 0.841103000000, -0.010592300000, -0.861170000000, 0.508206000000, -0.010592300000, 0.861170000000, 0.508206000000, -0.000000000000, -0.000000000000, 1.000000000000}; //static float ps256 [768] = { -0.620130, 0.642380, 0.450318, -0.718782, 0.617632, 0.319191, -0.248402, 0.840801, 0.480988, -0.570135, -0.166209, 0.804562, 0.950801, 0.065535, 0.302791, -0.654486, -0.600488, 0.459416, 0.659421, 0.308655, 0.685489, 0.794086, 0.087188, 0.601519, 0.627976, -0.125828, 0.767993, 0.663437, -0.414870, 0.622683, -0.467373, 0.236486, 0.851843, -0.649163, -0.026427, 0.760190, -0.764200, -0.037654, 0.643879, 0.645691, 0.716458, 0.264142, 0.311288, -0.707015, 0.635004, -0.068251, -0.913618, 0.400803, 0.921930, -0.207222, 0.327268, -0.375380, -0.077486, 0.923627, -0.558133, -0.829707, -0.008603, -0.837962, -0.482703, 0.254591, -0.036415, -0.973851, 0.224251, -0.894816, 0.088757, 0.437524, 0.529977, 0.365359, 0.765269, 0.128541, -0.547209, 0.827067, 0.038387, 0.858153, 0.511957, -0.256205, 0.730722, 0.632775, 0.313154, 0.146255, 0.938373, 0.920560, 0.365562, 0.137601, 0.016146, -0.758089, 0.651951, -0.257125, -0.765503, 0.589824, 0.901740, -0.352943, 0.249594, -0.091927, -0.005200, 0.995752, -0.498853, 0.382347, 0.777789, -0.957324, 0.079378, 0.277903, -0.101911, -0.822626, 0.559375, -0.215483, -0.864219, 0.454634, 0.119626, -0.399029, 0.909102, 0.835600, -0.053750, 0.546702, 0.656971, -0.271980, 0.703147, 0.962514, -0.218925, 0.160118, -0.794647, -0.193686, 0.575345, 0.543597, -0.510360, 0.666359, 0.183203, 0.579642, 0.794010, 0.239699, 0.921520, 0.305523, 0.429131, 0.648634, 0.628587, 0.272929, 0.302174, 0.913346, 0.564022, 0.207258, 0.799327, 0.347074, -0.014907, 0.937719, 0.171548, 0.793770, 0.583524, 0.854685, -0.197055, 0.480295, 0.836728, 0.494048, 0.236226, 0.672090, -0.729131, 0.129089, 0.582074, -0.687731, 0.433838, -0.607903, 0.255359, 0.751829, -0.832957, 0.377875, 0.404220, 0.019866, -0.255952, -0.966485, 0.222679, -0.124972, 0.966848, 0.847158, -0.341919, 0.406711, 0.734568, 0.590964, 0.333423, -0.793510, 0.598167, 0.111973, 0.156910, -0.681296, 0.714993, 0.155387, -0.987852, -0.002013, -0.126756, 0.688721, 0.713861, -0.169980, -0.440767, 0.881380, 0.066832, -0.067507, 0.995478, -0.028045, -0.346395, 0.937669, 0.688272, 0.537729, 0.486959, 0.425722, 0.257792, 0.867355, -0.317481, -0.219554, 0.922498, 0.977462, -0.210963, -0.007885, -0.262644, 0.042262, 0.963967, 0.987630, 0.071435, 0.139585, -0.295400, -0.939523, 0.173307, 0.429713, -0.900955, 0.060230, -0.780770, -0.606777, 0.149066, -0.699430, 0.116328, 0.705170, -0.871481, 0.490374, -0.007319, 0.784918, -0.616502, 0.061882, -0.628289, 0.395222, 0.670114, -0.693675, 0.719711, 0.028833, 0.686486, 0.148024, 0.711917, -0.516393, -0.706505, 0.483932, -0.419656, -0.902843, -0.093611, -0.452757, -0.250257, 0.855794, -0.677330, -0.733726, 0.053578, -0.174263, -0.286354, 0.942143, 0.295657, -0.804905, 0.514505, -0.869061, -0.348774, 0.350842, -0.180734, -0.939832, 0.289916, -0.685062, -0.472675, 0.554318, -0.483363, -0.803152, 0.348291, -0.877589, -0.203823, 0.433928, -0.306188, -0.514540, 0.800936, 0.248074, -0.287721, 0.925028, 0.076252, -0.940511, 0.331095, 0.611572, 0.671740, 0.418025, -0.152410, -0.584055, 0.797277, 0.437590, -0.758547, 0.482826, -0.065740, 0.406353, 0.911348, -0.253187, 0.598285, 0.760231, -0.598244, 0.738975, 0.309872, 0.735456, -0.511846, -0.443980, -0.736505, -0.598332, 0.315531, 0.720077, -0.020782, 0.693583, 0.735547, 0.394694, 0.550624, 0.617284, 0.461182, 0.637394, -0.831349, 0.244845, 0.498908, -0.692060, -0.182096, 0.698494, 0.953801, 0.218666, 0.206029, 0.780316, 0.625281, 0.011467, -0.353865, 0.349331, 0.867610, -0.325677, -0.881558, 0.341745, 0.395261, -0.892361, 0.217855, 0.119676, -0.979011, 0.164973, -0.105177, -0.971084, -0.214321, 0.277615, -0.954320, 0.110473, 0.774029, 0.237439, 0.586943, -0.741556, 0.388644, 0.546855, -0.935339, 0.344423, 0.080708, -0.730238, 0.255546, 0.633599, 0.929945, -0.357765, 0.084895, -0.373247, -0.795324, 0.477647, -0.567371, 0.110262, 0.816047, 0.854176, -0.492195, 0.167712, 0.340151, 0.551967, 0.761334, -0.808702, 0.105634, 0.578656, 0.861798, 0.501775, 0.074331, -0.319296, -0.370765, 0.872114, -0.569215, 0.821996, -0.017790, 0.837072, 0.296740, 0.459626, -0.584706, 0.798355, 0.144041, -0.134900, -0.711034, 0.690096, 0.266450, -0.441901, 0.856579, -0.366202, 0.849992, 0.378693, -0.019791, -0.499101, 0.866318, 0.386699, 0.410577, 0.825767, -0.698640, 0.690583, 0.187076, 0.484836, 0.513333, 0.708113, 0.044640, -0.863416, 0.502513, -0.916026, -0.353738, 0.189120, -0.453680, 0.885409, 0.101122, 0.374137, -0.175619, 0.910593, -0.286118, -0.646122, 0.707576, 0.028534, 0.099760, 0.994602, 0.412101, -0.469382, 0.780931, -0.287550, -0.957731, 0.008113, -0.416431, 0.088875, 0.904813, -0.933220, -0.358525, 0.023689, -0.814096, 0.502744, 0.290682, 0.229816, 0.446843, 0.864590, -0.054564, -0.177204, 0.982660, 0.598571, 0.038613, 0.800138, -0.580704, -0.315567, 0.750467, 0.130867, 0.698714, 0.703329, -0.336993, 0.915939, 0.217923, -0.493934, 0.756214, 0.429150, -0.666933, -0.737672, -0.105070, -0.476896, 0.838116, 0.264823, 0.508576, 0.038874, -0.860139, -0.188440, 0.307793, 0.932606, -0.058191, 0.960034, 0.273766, 0.476758, 0.731455, 0.487519, 0.190810, 0.040014, 0.980811, 0.027218, -0.993250, -0.112758, -0.132347, -0.989745, -0.053756, -0.233702, 0.452517, 0.860588, -0.977785, -0.067101, 0.198579, 0.010295, 0.629172, 0.777198, -0.206855, -0.112640, 0.971866, 0.755718, -0.166569, 0.633360, -0.867686, -0.489340, 0.087566, -0.540484, -0.822680, -0.176279, -0.552383, -0.588815, 0.590060, 0.408374, -0.600034, 0.687887, 0.151396, 0.201806, 0.967654, -0.908588, 0.223984, 0.352561, 0.284267, 0.680542, 0.675318, 0.756288, -0.614133, 0.225541, -0.673174, -0.709401, 0.208774, 0.997067, 0.070525, -0.029721, 0.512916, 0.789942, 0.336018, 0.518916, -0.227678, 0.823947, -0.385114, 0.633154, 0.671419, 0.876850, 0.101736, 0.469876, 0.540608, -0.822439, 0.177023, 0.236040, -0.933091, 0.271341, 0.762904, 0.623095, 0.172424, 0.498306, -0.800809, 0.332257, 0.707924, -0.593135, 0.383451, 0.541684, -0.371693, 0.753938, -0.634193, 0.560004, -0.533099, 0.058866, 0.497286, 0.865587, 0.564270, 0.600864, 0.566181, 0.329542, 0.771485, 0.544254, 0.635964, -0.717502, 0.284149, 0.366066, 0.839325, 0.401906, -0.407014, -0.684778, 0.604499, 0.001305, 0.764224, 0.644950, 0.159817, -0.790250, 0.591578, -0.562474, -0.810067, 0.165573, -0.143285, 0.152241, 0.977902, 0.153335, 0.981772, -0.112299, -0.608221, -0.714282, 0.346220, -0.775181, -0.476385, 0.414912, -0.991473, 0.073673, 0.107490, 0.308573, -0.949687, -0.053640, 0.497279, -0.650830, 0.573702, -0.306653, 0.202320, 0.930070, 0.798532, 0.450359, 0.399405, -0.379113, 0.753469, 0.537176, -0.125276, 0.811828, 0.570299, 0.396121, 0.883338, 0.250605, 0.186984, -0.884024, 0.428414, -0.091922, 0.899655, 0.426816, -0.433498, -0.898776, 0.065433, 0.217505, -0.919248, -0.328139, 0.097447, -0.236298, 0.966782, -0.452536, -0.412501, 0.790604, -0.869251, 0.470555, 0.151593, -0.900643, 0.350970, 0.256247, -0.349022, 0.861353, -0.369127, -0.936828, -0.210371, 0.279459, 0.073639, 0.926939, 0.367916, 0.207787, 0.868368, 0.450290, 0.749579, -0.456767, 0.479057, -0.858236, -0.051870, 0.510628, -0.000777, -0.998588, 0.053116, -0.436413, -0.556048, 0.707357, 0.266925, 0.951675, 0.151873, -0.111266, 0.546236, 0.830209, -0.508059, 0.648008, 0.567416, 0.001856, -0.639340, 0.768922, 0.914045, -0.055527, 0.401794, -0.630529, 0.525988, 0.570763, 0.969196, -0.076957, 0.233960, 0.909922, 0.205559, 0.360260, 0.974964, 0.217320, 0.047096, -0.795091, -0.340784, 0.501694, -0.185220, 0.968324, 0.167458, 0.272552, -0.582122, 0.766061, -0.510696, 0.521459, 0.683572, -0.959285, 0.214491, 0.183757, 0.886393, 0.354224, 0.298047, -0.930737, -0.061497, 0.360481, 0.463009, 0.095403, 0.881204, -0.697735, -0.332759, 0.634379, 0.995219, -0.071685, 0.066331, -0.574963, -0.457503, 0.678313, 0.105025, 0.354067, 0.929304, 0.396109, -0.329252, 0.857141, -0.768114, 0.310746, -0.559855, -0.433437, -0.873681, 0.220939, -0.378453, 0.496000, 0.781510, 0.493624, -0.069092, 0.866927, 0.813815, -0.482045, 0.324556, -0.969788, -0.214033, 0.117055}; //static float ps755 [2265] = { -0.9994266714825543, 0, -0.033857470804872, -0.9963958764033671, 0, 0.08482486360947544, -0.9916866386330564, -0.12860074160506021, 0.004411350734000926, -0.9916866386330564, 0.12860074160506021, 0.004411350734000926, -0.98607357578129, 0, -0.16630966041063486, -0.9857439588996775, -0.12048320108981783, 0.11744209529781555, -0.9857439588996775, 0.12048320108981783, 0.11744209529781555, -0.9830738669028043, -0.13576245663339054, -0.1230216549296677, -0.9830738669028043, 0.13576245663339054, -0.1230216549296677, -0.9822469463768458, 0, 0.1875924740850802, -0.9683162594941432, -0.24649537802113122, 0.04004560167472076, -0.9683162594941432, 0.24649537802113122, 0.04004560167472076, -0.967244736312809, -0.08971798394659967, 0.2374622147452561, -0.967244736312809, 0.08971798394659967, 0.2374622147452561, -0.9621351351385714, -0.2605138798701924, -0.0801779279282143, -0.9621351351385714, 0.2605138798701924, -0.0801779279282143, -0.9614507908933246, -0.22165711242617028, 0.16272830485656992, -0.9614507908933246, 0.22165711242617028, 0.16272830485656992, -0.9551169259871324, -0.14106195520847561, -0.2604864343601271, -0.9551169259871324, 0.14106195520847561, -0.2604864343601271, -0.9517112057440018, 0, -0.3069947570583225, -0.9465965938004058, 0, 0.32242036009760555, -0.9389619707336497, -0.271524913266781, -0.21124544726797656, -0.9389619707336497, 0.271524913266781, -0.21124544726797656, -0.9373125561577, -0.19116759016150822, 0.2913762593983249, -0.9373125561577, 0.19116759016150822, 0.2913762593983249, -0.931509891817533, -0.35476868706133874, 0.0801779279282143, -0.931509891817533, 0.35476868706133874, 0.0801779279282143, -0.9282706578194226, -0.36974306703169696, -0.040045601674720765, -0.9282706578194226, 0.36974306703169696, -0.040045601674720765, -0.9196658769956819, -0.0930563708211101, 0.38151695445860245, -0.9196658769956819, 0.0930563708211101, 0.38151695445860245, -0.9192345310435216, -0.3322397296317068, 0.21124544726797656, -0.9192345310435215, 0.3322397296317067, 0.21124544726797653, -0.9081168108377711, -0.38580222481518056, -0.1627283048565699, -0.9081168108377711, 0.38580222481518056, -0.1627283048565699, -0.905039215834912, -0.14364161499041464, -0.4003387368765019, -0.905039215834912, 0.14364161499041464, -0.4003387368765019, -0.895768418755139, -0.2779306951014105, -0.3469199744629367, -0.895768418755139, 0.2779306951014105, -0.3469199744629367, -0.8944271909999159, 0, -0.447213595499958, -0.8882250561447018, 0, 0.45940858681215463, -0.8882250561447018, 0, 0.45940858681215474, -0.8880554375372868, -0.3016688104181361, 0.34691997446293665, -0.8880554375372868, 0.3016688104181361, 0.34691997446293665, -0.8778809630980393, -0.47885859563629063, -0.004411350734000925, -0.8778809630980393, 0.47885859563629063, -0.004411350734000925, -0.8751226348743671, 0.19647727299831622, 0.4422183342260814, -0.8751226348743671, 0.4680021862650972, 0.12302165492966767, -0.875122634874367, -0.4680021862650972, 0.12302165492966767, -0.875122634874367, -0.19647727299831622, 0.4422183342260814, -0.8706672771858278, -0.39628066808369156, -0.2913762593983249, -0.8706672771858278, 0.39628066808369156, -0.2913762593983249, -0.8683018636018623, -0.48193280435927155, -0.1174420952978156, -0.8683018636018623, 0.48193280435927155, -0.1174420952978156, -0.8556199616698325, 0.44728212428674363, 0.2604864343601271, -0.8556199616698322, -0.44728212428674363, 0.2604864343601271, -0.8468638011056542, -0.09425480719114633, 0.5233906129252252, -0.8468638011056542, 0.09425480719114633, 0.5233906129252252, -0.8352523372260013, -0.4959488176483333, -0.2374622147452561, -0.8352523372260013, 0.4959488176483333, -0.2374622147452561, -0.8351224597613233, -0.22824303804682877, -0.5004753668117452, -0.8351224597613233, 0.22824303804682877, -0.5004753668117452, -0.8295223498394129, -0.08877540026300262, -0.5513724688674999, -0.8295223498394129, 0.08877540026300262, -0.5513724688674999, -0.8234755272545975, -0.35543072586240004, -0.4422183342260814, -0.8234755272545975, 0.35543072586240004, -0.4422183342260814, -0.8166225290930591, -0.41576019618739724, 0.4003387368765019, -0.8166225290930591, 0.41576019618739724, 0.4003387368765019, -0.8097861540334746, 0.306220169078268, 0.5004753668117451, -0.8097861540334745, -0.306220169078268, 0.5004753668117451, -0.8085531618609739, -0.5874482582451998, 0.033857470804871996, -0.8085531618609739, 0.5874482582451998, 0.033857470804871996, -0.8081338527952605, 0, 0.5889988760314302, -0.8061011971354436, -0.585666801594933, -0.08482486360947541, -0.8061011971354436, 0.585666801594933, -0.08482486360947541, -0.7987224860367548, -0.46528185410555045, -0.38151695445860245, -0.7987224860367548, 0.46528185410555045, -0.38151695445860245, -0.7977502805111363, 0.5795995055195465, 0.16630966041063483, -0.7977502805111361, -0.5795995055195465, 0.16630966041063483, -0.794654472291766, -0.5773502691896257, -0.1875924740850802, -0.794654472291766, 0.5773502691896257, -0.1875924740850802, -0.7868988425360586, 0.19647727299831622, 0.5849674288458774, -0.7868988425360585, -0.19647727299831622, 0.5849674288458774, -0.7699505391839696, 0.5594018111778118, 0.3069947570583225, -0.7699505391839695, -0.5594018111778118, 0.3069947570583225, -0.7658127312019672, -0.5563955177061672, -0.32242036009760555, -0.7658127312019672, 0.5563955177061672, -0.32242036009760555, -0.7609618011718721, 0, -0.6487966839906476, -0.7525262214051114, -0.0930563708211101, 0.6519545980720968, -0.7525262214051114, 0.0930563708211101, 0.6519545980720968, -0.7521009799446995, -0.3035740818246284, -0.5849674288458774, -0.7521009799446995, 0.3035740818246284, -0.5849674288458774, -0.7496516053274307, -0.17177061608955554, -0.6391536013183533, -0.7496516053274307, 0.17177061608955554, -0.6391536013183533, -0.7405287926400659, -0.4215203121710784, -0.5233906129252252, -0.7405287926400659, 0.4215203121710784, -0.5233906129252252, -0.7297825215675532, -0.641115565076049, -0.2374622147452561, -0.7297825215675532, 0.641115565076049, -0.2374622147452561, -0.7267017243993805, 0.6869389665317207, -0.004411350734000925, -0.7267017243993803, -0.6869389665317207, -0.004411350734000925, -0.7266653661026955, -0.6768787187959852, -0.11744209529781557, -0.7266653661026955, 0.6768787187959852, -0.11744209529781557, -0.7236067977499792, 0.5257311121191337, 0.447213595499958, -0.723606797749979, -0.5257311121191337, 0.447213595499958, -0.72327854927488, 0.41576019618739724, 0.5513724688674999, -0.7232785492748799, -0.41576019618739724, 0.5513724688674999, -0.7185891652507057, -0.5220855887185097, -0.45940858681215474, -0.7185891652507057, 0.5220855887185097, -0.45940858681215474, -0.7155242952261605, 0.6876704554941067, 0.12302165492966767, -0.7155242952261603, -0.6876704554941067, 0.12302165492966767, -0.7117124032047751, 0, 0.7024709639013443, -0.7074451234849853, -0.30166881041813615, 0.6391536013183533, -0.7074451234849853, 0.30166881041813615, 0.6391536013183533, -0.6897916878076654, -0.6755251623335724, 0.26048643436012703, -0.6897916878076654, 0.6755251623335724, 0.26048643436012703, -0.6893281612357385, -0.6158502249638206, -0.38151695445860245, -0.6893281612357385, 0.6158502249638206, -0.38151695445860245, -0.6807264326348014, -0.08390581259561895, -0.7277165234656735, -0.6807264326348014, 0.08390581259561895, -0.7277165234656735, -0.6797937675642477, 0.19116759016150822, 0.7080504120842295, -0.6797937675642476, -0.19116759016150822, 0.7080504120842295, -0.6635036642300076, -0.36703962947616986, -0.6519545980720968, -0.6635036642300076, 0.36703962947616986, -0.6519545980720968, -0.6623302008428754, -0.24491492196023698, -0.7080504120842295, -0.6623302008428754, 0.24491492196023698, -0.7080504120842295, -0.6537940206410678, -0.4750091605513505, -0.5889988760314302, -0.6537940206410678, 0.4750091605513505, -0.5889988760314302, -0.6477616832793809, 0.6481772114408144, 0.4003387368765019, -0.6477616832793808, -0.6481772114408144, 0.4003387368765019, -0.647543247338096, -0.7444509665688808, -0.1627283048565699, -0.647543247338096, 0.7444509665688808, -0.1627283048565699, -0.6459362967593755, -0.7055963265124218, -0.2913762593983249, -0.6459362967593755, 0.7055963265124218, -0.2913762593983249, -0.644957657958078, -0.08971798394659967, 0.7589336616581112, -0.644957657958078, 0.08971798394659967, 0.7589336616581112, -0.6384979619012642, -0.7685809667396409, -0.04004560167472076, -0.6384979619012642, 0.7685809667396409, -0.04004560167472076, -0.6297256213908132, -0.5740277938094211, -0.5233906129252252, -0.6297256213908132, 0.5740277938094211, -0.5233906129252252, -0.6252574586071488, -0.776288999232417, 0.08017792792821428, -0.6252574586071488, 0.776288999232417, 0.08017792792821428, -0.6189168071929715, 0.5594018111778118, 0.5513724688674999, -0.6189168071929714, -0.5594018111778118, 0.5513724688674999, -0.6156310292182143, 0.4472821242867436, 0.6487966839906475, -0.6156310292182142, -0.44728212428674363, 0.6487966839906476, -0.6070619982066863, 0, 0.7946544722917661, -0.6035685408534394, 0, -0.7973111164984783, -0.6000378517471081, 0.7715762680897256, 0.21124544726797656, -0.600037851747108, -0.7715762680897256, 0.21124544726797656, -0.600037851747108, -0.3322397296317067, 0.7277165234656734, -0.600037851747108, 0.3322397296317067, 0.7277165234656734, -0.595894253326634, -0.1589592585807398, -0.787173419878844, -0.595894253326634, 0.1589592585807398, -0.787173419878844, -0.5925026402964927, -0.6733376315905675, -0.4422183342260814, -0.5925026402964927, 0.6733376315905675, -0.4422183342260814, -0.5757874293000979, -0.418334054477401, -0.7024709639013442, -0.5757874293000979, 0.418334054477401, -0.7024709639013442, -0.5755224857007216, 0.22165711242617026, 0.7871734198788439, -0.5755224857007215, -0.22165711242617026, 0.7871734198788439, -0.574516613769574, -0.3065132259869937, -0.7589336616581113, -0.574516613769574, 0.3065132259869937, -0.7589336616581113, -0.5613283100572769, -0.7513701216091022, 0.3469199744629367, -0.5613283100572769, 0.751370121609102, 0.34691997446293665, -0.5541093394289913, -0.5176080003344399, -0.6519545980720968, -0.5541093394289913, 0.5176080003344399, -0.6519545980720968, -0.5483907441273382, -0.809100088223958, -0.21124544726797653, -0.5483907441273382, 0.809100088223958, -0.21124544726797653, -0.545881503504257, -0.12048320108981789, 0.8291544985025905, -0.545881503504257, 0.12048320108981789, 0.8291544985025905, -0.5450795306789344, -0.8345416736796134, -0.08017792792821428, -0.5450795306789344, 0.8345416736796134, -0.08017792792821428, -0.5414703706287631, 0.6755251623335724, 0.5004753668117451, -0.541470370628763, -0.6755251623335724, 0.5004753668117451, -0.5411354630743502, -0.7660410837037032, -0.34691997446293676, -0.5411354630743502, 0.7660410837037032, -0.34691997446293676, -0.5336572156169057, -0.8447522275830474, 0.04004560167472076, -0.5336572156169057, 0.8447522275830474, 0.04004560167472076, -0.5242037314217923, -0.07617126084340645, -0.8481794544699813, -0.5242037314217923, 0.07617126084340645, -0.8481794544699813, -0.5214714469128553, 0, 0.853268732612776, -0.5211280929865946, -0.6214809875527959, -0.5849674288458774, -0.5211280929865946, 0.6214809875527959, -0.5849674288458774, -0.5124456619994747, -0.22338814004068744, -0.8291544985025905, -0.5124456619994747, 0.22338814004068744, -0.8291544985025905, -0.5079130747973478, -0.8458982251124606, 0.1627283048565699, -0.5079130747973478, 0.8458982251124606, 0.1627283048565699, -0.5055166536557195, -0.5795995055195465, 0.6391536013183533, -0.5055166536557195, 0.5795995055195464, 0.6391536013183532, -0.5014006532964664, -0.4680021862650972, 0.7277165234656735, -0.5014006532964664, 0.4680021862650971, 0.7277165234656734, -0.49112347318842303, -0.35682208977308993, -0.7946544722917661, -0.49112347318842303, 0.35682208977308993, -0.7946544722917661, -0.4882972068205223, -0.35476868706133874, 0.7973111164984783, -0.4882972068205223, 0.35476868706133874, 0.7973111164984783, -0.47513906108389614, -0.7237176796562059, -0.5004753668117452, -0.47513906108389614, 0.7237176796562059, -0.5004753668117452, -0.4714566912212953, -0.8323631802054368, 0.2913762593983249, -0.4714566912212953, 0.8323631802054368, 0.2913762593983249, -0.46904679811112565, -0.45167997341470945, -0.7589336616581113, -0.46904679811112565, 0.45167997341470945, -0.7589336616581113, -0.46886207100726823, -0.24649537802113128, 0.8481794544699813, -0.46886207100726823, 0.24649537802113128, 0.8481794544699813, -0.45728875712731204, 0.7715762680897255, 0.4422183342260813, -0.457288757127312, -0.7715762680897256, 0.4422183342260814, -0.44744137931788447, -0.12860074160506021, 0.8850186785219495, -0.44744137931788447, 0.12860074160506021, 0.8850186785219495, -0.4432126849970109, 0, -0.8964164857128302, -0.4375992204164231, -0.5542305803889672, -0.7080504120842295, -0.4375992204164231, 0.5542305803889672, -0.7080504120842295, -0.4375772992040651, -0.1589592585807398, -0.8850186785219495, -0.4375772992040651, 0.1589592585807398, -0.8850186785219495, -0.4329043006482858, -0.893005900819577, -0.12302165492966766, -0.4329043006482858, 0.893005900819577, -0.12302165492966766, -0.4300261059865685, -0.6876704554941067, 0.5849674288458774, -0.4300261059865685, 0.6876704554941067, 0.5849674288458774, -0.42930525344753856, -0.8647796348646817, -0.26048643436012714, -0.42930525344753856, 0.8647796348646817, -0.26048643436012714, -0.4287545977360634, -0.9034102251496204, 0.004411350734000925, -0.4287545977360634, 0.9034102251496204, 0.004411350734000925, -0.4218792626337932, -0.3065132259869937, -0.853268732612776, -0.4218792626337932, 0.3065132259869937, -0.853268732612776, -0.4191979689030107, -0.9002668588366725, 0.11744209529781557, -0.4191979689030107, 0.9002668588366725, 0.11744209529781557, -0.41667415268590485, 0, 0.9090559116377184, -0.4162837922165572, -0.8163557435909476, -0.4003387368765019, -0.4162837922165572, 0.8163557435909476, -0.4003387368765019, -0.39501864964664196, -0.6598810046918482, -0.6391536013183534, -0.39501864964664196, 0.6598810046918482, -0.6391536013183534, -0.39187900917506946, 0.5874482582451998, 0.7080504120842295, -0.39187900917506935, -0.5874482582451998, 0.7080504120842295, -0.38865466988251257, 0.47885859563629063, 0.7871734198788439, -0.38865466988251246, -0.47885859563629063, 0.7871734198788439, -0.38422193450165043, 0.8921800275819267, 0.2374622147452561, -0.3842219345016504, -0.8921800275819267, 0.2374622147452561, -0.3793173834627134, -0.36974306703169685, 0.8481794544699811, -0.3793173834627134, 0.36974306703169685, 0.8481794544699811, -0.37269425299060066, -0.8458982251124604, 0.3815169544586024, -0.37269425299060066, 0.8458982251124604, 0.3815169544586024, -0.370809164500308, -0.41833405447740113, -0.8291544985025905, -0.370809164500308, 0.41833405447740113, -0.8291544985025905, -0.35856659428513216, -0.2605138798701924, 0.89641648571283, -0.35856659428513216, 0.2605138798701924, 0.89641648571283, -0.35133695503389567, 0.776288999232417, 0.523390612925225, -0.3513369550338956, -0.776288999232417, 0.523390612925225, -0.3464593304371572, -0.08390581259561895, -0.9343049539447521, -0.3464593304371572, 0.08390581259561895, -0.9343049539447521, -0.34076692622105814, -0.7614895288635357, -0.5513724688674999, -0.34076692622105814, 0.7614895288635357, -0.5513724688674999, -0.3370964706396787, -0.24491492196023704, -0.9090559116377184, -0.3370964706396787, 0.24491492196023704, -0.9090559116377184, -0.33532068982695884, -0.51760800033444, -0.787173419878844, -0.3353206898269588, 0.51760800033444, -0.787173419878844, -0.32961008540874664, -0.1357624566333905, 0.9343049539447521, -0.32961008540874664, 0.1357624566333905, 0.9343049539447521, -0.32104525897913894, -0.6869389665317207, 0.6519545980720968, -0.32104525897913894, 0.6869389665317207, 0.6519545980720968, -0.3088398261196968, -0.9505112484726589, -0.033857470804871996, -0.3088398261196968, 0.9505112484726589, -0.033857470804871996, -0.30790325893376, -0.9476287910630427, 0.08482486360947541, -0.30790325893376, 0.9476287910630427, 0.08482486360947541, -0.30471349262049113, -0.9378116997932586, -0.16630966041063486, -0.30471349262049113, 0.9378116997932586, -0.16630966041063486, -0.3035309991033431, -0.9341723589627156, 0.1875924740850802, -0.3035309991033431, 0.9341723589627156, 0.1875924740850802, -0.29409493631196854, -0.9051311438539504, -0.3069947570583225, -0.29409493631196854, 0.9051311438539504, -0.3069947570583225, -0.29251443430176444, -0.9002668588366725, 0.32242036009760555, -0.29251443430176444, 0.9002668588366725, 0.32242036009760555, -0.2922336268554169, 0, 0.9563469597039189, -0.2901552060284897, -0.6214809875527959, -0.7277165234656735, -0.2901552060284897, 0.6214809875527959, -0.7277165234656735, -0.28639806050540606, -0.3670396294761699, -0.8850186785219495, -0.28639806050540606, 0.3670396294761699, -0.8850186785219495, -0.28462975022258863, 0.585666801594933, 0.7589336616581112, -0.2846297502225886, -0.585666801594933, 0.7589336616581112, -0.2832729949983337, -0.48193280435927144, 0.8291544985025904, -0.2832729949983337, 0.48193280435927144, 0.8291544985025904, -0.27639320225002095, -0.85065080835204, -0.447213595499958, -0.27639320225002095, 0.85065080835204, -0.447213595499958, -0.27447663717835485, -0.8447522275830474, 0.45940858681215474, -0.27447663717835485, 0.8447522275830474, 0.45940858681215474, -0.26057356349967536, -0.38580222481518056, 0.8850186785219493, -0.26057356349967536, 0.38580222481518056, 0.8850186785219493, -0.24972709424343778, -0.7685809667396409, 0.5889988760314302, -0.24972709424343778, 0.7685809667396409, 0.5889988760314302, -0.23998893245161798, 0, -0.9707756240763016, -0.2364219704538591, -0.17177061608955557, -0.9563469597039189, -0.2364219704538591, 0.17177061608955557, -0.9563469597039189, -0.2351501286322781, -0.7237176796562059, -0.6487966839906476, -0.2351501286322781, 0.7237176796562059, -0.6487966839906476, -0.23443103550363395, -0.4750091605513506, -0.8481794544699813, -0.2344310355036339, -0.4750091605513506, -0.8481794544699813, -0.2344310355036339, 0.4750091605513506, -0.8481794544699813, -0.230972886958105, -0.271524913266781, 0.9343049539447521, -0.230972886958105, 0.271524913266781, 0.9343049539447521, -0.2199312276977106, -0.6768787187959852, 0.7024709639013442, -0.2199312276977106, 0.6768787187959852, 0.7024709639013442, -0.21356818797909516, -0.9476287910630424, 0.23746221474525606, -0.21356818797909516, 0.9476287910630424, 0.23746221474525606, -0.19569051728621087, -0.9034102251496204, 0.38151695445860245, -0.19569051728621087, 0.9034102251496204, 0.38151695445860245, -0.1941551248152605, -0.14106195520847564, 0.9707756240763016, -0.1941551248152605, 0.14106195520847564, 0.9707756240763016, -0.19002530190186945, -0.9747295721835683, 0.11744209529781557, -0.19002530190186945, 0.9747295721835683, 0.11744209529781557, -0.1875924740850802, -0.5773502691896257, 0.794654472291766, -0.1875924740850802, 0.5773502691896257, 0.794654472291766, -0.18686099078895035, -0.30357408182462847, -0.9343049539447523, -0.18686099078895035, 0.30357408182462847, -0.9343049539447523, -0.18651293639380231, -0.5740277938094211, -0.7973111164984783, -0.18651293639380231, 0.5740277938094211, -0.7973111164984783, -0.1841414511282999, -0.9828898544399904, 0.004411350734000925, -0.1841414511282999, 0.9828898544399904, 0.004411350734000925, -0.1746687625494374, -0.9769117134151961, -0.12302165492966767, -0.1746687625494374, 0.9769117134151961, -0.12302165492966767, -0.17205365789132968, -0.8345416736796134, 0.523390612925225, -0.17205365789132968, 0.8345416736796134, 0.523390612925225, -0.17190608040737973, -0.8163557435909476, -0.5513724688674999, -0.17190608040737973, 0.8163557435909476, -0.5513724688674999, -0.16114353917736582, -0.4959488176483333, 0.8532687326127759, -0.16114353917736582, 0.4959488176483333, 0.8532687326127759, -0.16098947004282693, -0.9519607177030348, -0.26048643436012714, -0.16098947004282693, 0.9519607177030348, -0.26048643436012714, -0.1510337319909983, 0, 0.9885286095004389, -0.14404152327474903, -0.7444509665688808, 0.6519545980720968, -0.14404152327474903, 0.7444509665688808, 0.6519545980720968, -0.14306120432097033, -0.9051311438539504, -0.4003387368765019, -0.14306120432097033, 0.9051311438539504, -0.4003387368765019, -0.13696025178662646, -0.42152031217107844, -0.8964164857128302, -0.13696025178662646, 0.42152031217107844, -0.8964164857128302, -0.13055686638028288, -0.6733376315905675, -0.7277165234656735, -0.13055686638028288, 0.6733376315905675, -0.7277165234656735, -0.12875939429672653, -0.39628066808369167, 0.9090559116377184, -0.12875939429672653, 0.39628066808369167, 0.9090559116377184, -0.12218885590458858, -0.08877540026300264, -0.988528609500439, -0.12218885590458858, 0.08877540026300264, -0.988528609500439, -0.11397600370003338, -0.641115565076049, 0.7589336616581112, -0.11397600370003338, 0.641115565076049, 0.7589336616581112, -0.10783432656620794, -0.9505112484726589, 0.2913762593983249, -0.10783432656620794, 0.9505112484726589, 0.2913762593983249, -0.09030515702615106, -0.27793069510141055, 0.9563469597039189, -0.09030515702615106, 0.27793069510141055, 0.9563469597039189, -0.08954468754455468, -0.5220855887185099, -0.8481794544699813, -0.08954468754455468, 0.5220855887185099, -0.8481794544699813, -0.08629619248519454, -0.9828898544399904, 0.1627283048565699, -0.08629619248519454, 0.9828898544399904, 0.1627283048565699, -0.08356677554941112, -0.893005900819577, 0.4422183342260813, -0.08356677554941112, 0.893005900819577, 0.4422183342260813, -0.07416065858945113, -0.22824303804682883, -0.9707756240763016, -0.07416065858945113, 0.22824303804682883, -0.9707756240763016, -0.06829152216663177, -0.7660410837037032, -0.6391536013183534, -0.06829152216663177, 0.7660410837037032, -0.6391536013183534, -0.06479514460963778, -0.9970947492698604, 0.040045601674720765, -0.06479514460963778, 0.9970947492698604, 0.040045601674720765, -0.056304124408667555, -0.8091000882239582, 0.5849674288458774, -0.056304124408667555, 0.8091000882239582, 0.5849674288458774, -0.0541003279971925, -0.5563955177061674, 0.8291544985025905, -0.0541003279971925, 0.5563955177061674, 0.8291544985025905, -0.049552684607175844, -0.9955481059804994, -0.08017792792821428, -0.049552684607175844, 0.9955481059804994, -0.08017792792821428, -0.046671989909089814, -0.14364161499041467, 0.988528609500439, -0.046671989909089814, 0.14364161499041467, 0.988528609500439, -0.04099500381701781, -0.8647796348646815, -0.5004753668117452, -0.04099500381701781, 0.8647796348646815, -0.5004753668117452, -0.032962212429640814, -0.6158502249638206, -0.7871734198788439, -0.032962212429640814, 0.6158502249638206, -0.7871734198788439, -0.03191966792964132, -0.9769117134151959, -0.21124544726797653, -0.03191966792964132, 0.9769117134151959, -0.21124544726797653, -0.028256644519982034, -0.7055963265124218, 0.7080504120842295, -0.028256644519982034, 0.7055963265124218, 0.7080504120842295, -0.027262651140743457, -0.35543072586240004, -0.9343049539447521, -0.027262651140743457, 0.35543072586240004, -0.9343049539447521, -0.0159604168919119, -0.4652818541055505, 0.8850186785219495, -0.0159604168919119, 0.4652818541055505, 0.8850186785219495, -0.012479865765074368, -0.9378116997932586, -0.34691997446293676, -0.012479865765074368, 0.9378116997932586, -0.34691997446293676, 0, 0, -1., 0, 0, 1., 0.012479865765074368, -0.9378116997932586, 0.34691997446293676, 0.012479865765074368, 0.9378116997932586, 0.34691997446293676, 0.0159604168919119, -0.4652818541055505, -0.8850186785219495, 0.0159604168919119, 0.4652818541055505, -0.8850186785219495, 0.027262651140743457, -0.35543072586240004, 0.9343049539447521, 0.027262651140743457, 0.35543072586240004, 0.9343049539447521, 0.028256644519982034, -0.7055963265124218, -0.7080504120842295, 0.028256644519982034, 0.7055963265124218, -0.7080504120842295, 0.03191966792964132, -0.9769117134151959, 0.21124544726797653, 0.03191966792964132, 0.9769117134151959, 0.21124544726797653, 0.032962212429640814, -0.6158502249638206, 0.7871734198788439, 0.032962212429640814, 0.6158502249638206, 0.7871734198788439, 0.04099500381701781, -0.8647796348646815, 0.5004753668117452, 0.04099500381701781, 0.8647796348646815, 0.5004753668117452, 0.046671989909089814, -0.14364161499041467, -0.988528609500439, 0.046671989909089814, 0.14364161499041467, -0.988528609500439, 0.049552684607175844, -0.9955481059804994, 0.08017792792821428, 0.049552684607175844, 0.9955481059804994, 0.08017792792821428, 0.0541003279971925, -0.5563955177061674, -0.8291544985025905, 0.0541003279971925, 0.5563955177061674, -0.8291544985025905, 0.056304124408667555, -0.8091000882239582, -0.5849674288458774, 0.056304124408667555, 0.8091000882239582, -0.5849674288458774, 0.06479514460963778, -0.9970947492698604, -0.040045601674720765, 0.06479514460963778, 0.9970947492698604, -0.040045601674720765, 0.06829152216663177, -0.7660410837037032, 0.6391536013183534, 0.06829152216663177, 0.7660410837037032, 0.6391536013183534, 0.07416065858945113, -0.22824303804682883, 0.9707756240763016, 0.07416065858945113, 0.22824303804682883, 0.9707756240763016, 0.08356677554941112, -0.893005900819577, -0.4422183342260813, 0.08356677554941112, 0.893005900819577, -0.4422183342260813, 0.08629619248519454, -0.9828898544399904, -0.1627283048565699, 0.08629619248519454, 0.9828898544399904, -0.1627283048565699, 0.08954468754455468, -0.5220855887185099, 0.8481794544699813, 0.08954468754455468, 0.5220855887185099, 0.8481794544699813, 0.09030515702615106, -0.27793069510141055, -0.9563469597039189, 0.09030515702615106, 0.27793069510141055, -0.9563469597039189, 0.10783432656620794, -0.9505112484726589, -0.2913762593983249, 0.10783432656620794, 0.9505112484726589, -0.2913762593983249, 0.11397600370003338, -0.641115565076049, -0.7589336616581112, 0.11397600370003338, 0.641115565076049, -0.7589336616581112, 0.12218885590458858, -0.08877540026300264, 0.988528609500439, 0.12218885590458858, 0.08877540026300264, 0.988528609500439, 0.12875939429672653, -0.39628066808369167, -0.9090559116377184, 0.12875939429672653, 0.39628066808369167, -0.9090559116377184, 0.13055686638028288, -0.6733376315905675, 0.7277165234656735, 0.13055686638028288, 0.6733376315905675, 0.7277165234656735, 0.13696025178662646, -0.42152031217107844, 0.8964164857128302, 0.13696025178662646, 0.42152031217107844, 0.8964164857128302, 0.14306120432097033, -0.9051311438539504, 0.4003387368765019, 0.14306120432097033, 0.9051311438539504, 0.4003387368765019, 0.14404152327474903, -0.7444509665688808, -0.6519545980720968, 0.14404152327474903, 0.7444509665688808, -0.6519545980720968, 0.1510337319909983, 0, -0.9885286095004389, 0.16098947004282693, -0.9519607177030348, 0.26048643436012714, 0.16098947004282693, 0.9519607177030348, 0.26048643436012714, 0.16114353917736582, -0.4959488176483333, -0.8532687326127759, 0.16114353917736582, 0.4959488176483333, -0.8532687326127759, 0.17190608040737973, -0.8163557435909476, 0.5513724688674999, 0.17190608040737973, 0.8163557435909476, 0.5513724688674999, 0.17205365789132968, -0.8345416736796134, -0.523390612925225, 0.17205365789132968, 0.8345416736796134, -0.523390612925225, 0.1746687625494374, -0.9769117134151961, 0.12302165492966767, 0.1746687625494374, 0.9769117134151961, 0.12302165492966767, 0.1841414511282999, -0.9828898544399904, -0.004411350734000925, 0.1841414511282999, 0.9828898544399904, -0.004411350734000925, 0.18651293639380231, -0.5740277938094211, 0.7973111164984783, 0.18651293639380231, 0.5740277938094211, 0.7973111164984783, 0.18686099078895035, -0.30357408182462847, 0.9343049539447523, 0.18686099078895035, 0.30357408182462847, 0.9343049539447523, 0.1875924740850802, -0.5773502691896257, -0.794654472291766, 0.1875924740850802, 0.5773502691896257, -0.794654472291766, 0.19002530190186945, -0.9747295721835683, -0.11744209529781557, 0.19002530190186945, 0.9747295721835683, -0.11744209529781557, 0.1941551248152605, -0.14106195520847564, -0.9707756240763016, 0.1941551248152605, 0.14106195520847564, -0.9707756240763016, 0.19569051728621087, -0.9034102251496204, -0.38151695445860245, 0.19569051728621087, 0.9034102251496204, -0.38151695445860245, 0.21356818797909516, -0.9476287910630424, -0.23746221474525606, 0.21356818797909516, 0.9476287910630424, -0.23746221474525606, 0.2199312276977106, -0.6768787187959852, -0.7024709639013442, 0.2199312276977106, 0.6768787187959852, -0.7024709639013442, 0.230972886958105, -0.271524913266781, -0.9343049539447521, 0.230972886958105, 0.271524913266781, -0.9343049539447521, 0.2344310355036339, -0.4750091605513506, 0.8481794544699813, 0.23443103550363395, 0.4750091605513506, 0.8481794544699813, 0.2351501286322781, -0.7237176796562059, 0.6487966839906476, 0.2351501286322781, 0.7237176796562059, 0.6487966839906476, 0.2364219704538591, -0.17177061608955557, 0.9563469597039189, 0.2364219704538591, 0.17177061608955557, 0.9563469597039189, 0.23998893245161798, 0, 0.9707756240763016, 0.24972709424343778, -0.7685809667396409, -0.5889988760314302, 0.24972709424343778, 0.7685809667396409, -0.5889988760314302, 0.26057356349967536, -0.38580222481518056, -0.8850186785219493, 0.26057356349967536, 0.38580222481518056, -0.8850186785219493, 0.27447663717835485, -0.8447522275830474, -0.45940858681215474, 0.27447663717835485, 0.8447522275830474, -0.45940858681215474, 0.27639320225002095, -0.85065080835204, 0.447213595499958, 0.27639320225002095, 0.85065080835204, 0.447213595499958, 0.2832729949983337, -0.48193280435927144, -0.8291544985025904, 0.2832729949983337, 0.48193280435927144, -0.8291544985025904, 0.2846297502225886, -0.585666801594933, -0.7589336616581112, 0.2846297502225886, 0.585666801594933, -0.7589336616581112, 0.28639806050540606, -0.3670396294761699, 0.8850186785219495, 0.2863980605054061, 0.3670396294761699, 0.8850186785219495, 0.2901552060284897, -0.6214809875527959, 0.7277165234656735, 0.2901552060284897, 0.6214809875527959, 0.7277165234656735, 0.2922336268554169, 0, -0.9563469597039189, 0.29251443430176444, -0.9002668588366725, -0.32242036009760555, 0.29251443430176444, 0.9002668588366725, -0.32242036009760555, 0.29409493631196854, -0.9051311438539504, 0.3069947570583225, 0.29409493631196854, 0.9051311438539504, 0.3069947570583225, 0.3035309991033431, -0.9341723589627156, -0.1875924740850802, 0.3035309991033431, 0.9341723589627156, -0.1875924740850802, 0.30471349262049113, -0.9378116997932586, 0.16630966041063486, 0.30471349262049113, 0.9378116997932586, 0.16630966041063486, 0.30790325893376, -0.9476287910630427, -0.08482486360947541, 0.30790325893376, 0.9476287910630427, -0.08482486360947541, 0.3088398261196968, -0.9505112484726589, 0.033857470804871996, 0.3088398261196968, 0.9505112484726589, 0.033857470804871996, 0.3210452589791389, -0.6869389665317207, -0.6519545980720968, 0.32104525897913894, 0.6869389665317207, -0.6519545980720968, 0.32961008540874664, -0.1357624566333905, -0.9343049539447521, 0.32961008540874664, 0.1357624566333905, -0.9343049539447521, 0.3353206898269588, -0.51760800033444, 0.787173419878844, 0.33532068982695884, 0.51760800033444, 0.787173419878844, 0.3370964706396787, -0.24491492196023704, 0.9090559116377184, 0.3370964706396787, 0.24491492196023704, 0.9090559116377184, 0.34076692622105814, -0.7614895288635357, 0.5513724688674999, 0.34076692622105814, 0.7614895288635357, 0.5513724688674999, 0.3464593304371572, -0.08390581259561895, 0.9343049539447521, 0.3464593304371572, 0.08390581259561895, 0.9343049539447521, 0.3513369550338956, -0.776288999232417, -0.523390612925225, 0.3513369550338956, 0.776288999232417, -0.523390612925225, 0.35856659428513216, -0.2605138798701924, -0.89641648571283, 0.35856659428513216, 0.2605138798701924, -0.89641648571283, 0.370809164500308, -0.41833405447740113, 0.8291544985025905, 0.370809164500308, 0.41833405447740113, 0.8291544985025905, 0.3726942529906006, -0.8458982251124604, -0.3815169544586024, 0.37269425299060066, 0.8458982251124604, -0.3815169544586024, 0.3793173834627134, -0.36974306703169685, -0.8481794544699811, 0.3793173834627134, 0.36974306703169685, -0.8481794544699811, 0.3842219345016504, -0.8921800275819267, -0.2374622147452561, 0.3842219345016504, 0.8921800275819267, -0.2374622147452561, 0.38865466988251246, -0.47885859563629063, -0.7871734198788439, 0.38865466988251246, 0.47885859563629063, -0.7871734198788439, 0.39187900917506935, -0.5874482582451998, -0.7080504120842295, 0.39187900917506935, 0.5874482582451998, -0.7080504120842295, 0.39501864964664196, -0.6598810046918482, 0.6391536013183534, 0.39501864964664196, 0.6598810046918482, 0.6391536013183534, 0.4162837922165572, -0.8163557435909476, 0.4003387368765019, 0.4162837922165572, 0.8163557435909476, 0.4003387368765019, 0.41667415268590485, 0, -0.9090559116377184, 0.4191979689030107, -0.9002668588366725, -0.11744209529781557, 0.4191979689030107, 0.9002668588366725, -0.11744209529781557, 0.4218792626337932, -0.3065132259869937, 0.853268732612776, 0.4218792626337932, 0.3065132259869937, 0.853268732612776, 0.4287545977360634, -0.9034102251496204, -0.004411350734000925, 0.4287545977360634, 0.9034102251496204, -0.004411350734000925, 0.42930525344753856, -0.8647796348646817, 0.26048643436012714, 0.42930525344753856, 0.8647796348646817, 0.26048643436012714, 0.4300261059865684, -0.6876704554941067, -0.5849674288458774, 0.4300261059865685, 0.6876704554941067, -0.5849674288458774, 0.4329043006482858, -0.893005900819577, 0.12302165492966766, 0.4329043006482858, 0.893005900819577, 0.12302165492966766, 0.4375772992040651, -0.1589592585807398, 0.8850186785219495, 0.4375772992040651, 0.1589592585807398, 0.8850186785219495, 0.4375992204164231, -0.5542305803889672, 0.7080504120842295, 0.4375992204164231, 0.5542305803889672, 0.7080504120842295, 0.4432126849970109, 0, 0.8964164857128302, 0.44744137931788447, -0.12860074160506021, -0.8850186785219495, 0.44744137931788447, 0.12860074160506021, -0.8850186785219495, 0.457288757127312, -0.7715762680897256, -0.4422183342260814, 0.457288757127312, 0.7715762680897256, -0.4422183342260814, 0.46886207100726823, -0.24649537802113128, -0.8481794544699813, 0.46886207100726823, 0.24649537802113128, -0.8481794544699813, 0.46904679811112565, -0.45167997341470945, 0.7589336616581113, 0.46904679811112565, 0.45167997341470945, 0.7589336616581113, 0.4714566912212952, -0.8323631802054368, -0.2913762593983249, 0.4714566912212953, 0.8323631802054368, -0.2913762593983249, 0.47513906108389614, -0.7237176796562059, 0.5004753668117452, 0.47513906108389614, 0.7237176796562059, 0.5004753668117452, 0.4882972068205223, -0.35476868706133874, -0.7973111164984783, 0.4882972068205223, 0.35476868706133874, -0.7973111164984783, 0.49112347318842303, -0.35682208977308993, 0.7946544722917661, 0.49112347318842303, 0.35682208977308993, 0.7946544722917661, 0.5014006532964664, -0.4680021862650972, -0.7277165234656735, 0.5014006532964664, 0.4680021862650972, -0.7277165234656735, 0.5055166536557194, -0.5795995055195465, -0.6391536013183533, 0.5055166536557195, 0.5795995055195465, -0.6391536013183533, 0.5079130747973478, -0.8458982251124606, -0.1627283048565699, 0.5079130747973478, 0.8458982251124606, -0.1627283048565699, 0.5124456619994747, -0.22338814004068744, 0.8291544985025905, 0.5124456619994747, 0.22338814004068744, 0.8291544985025905, 0.5211280929865946, -0.6214809875527959, 0.5849674288458774, 0.5211280929865946, 0.6214809875527959, 0.5849674288458774, 0.5214714469128553, 0, -0.853268732612776, 0.5242037314217923, -0.07617126084340645, 0.8481794544699813, 0.5242037314217923, 0.07617126084340645, 0.8481794544699813, 0.5336572156169057, -0.8447522275830474, -0.04004560167472076, 0.5336572156169057, 0.8447522275830474, -0.04004560167472076, 0.5411354630743502, -0.7660410837037032, 0.34691997446293676, 0.5411354630743502, 0.7660410837037032, 0.34691997446293676, 0.5414703706287629, -0.6755251623335724, -0.5004753668117451, 0.541470370628763, 0.6755251623335724, -0.5004753668117451, 0.5450795306789344, -0.8345416736796134, 0.08017792792821428, 0.5450795306789344, 0.8345416736796134, 0.08017792792821428, 0.545881503504257, -0.12048320108981789, -0.8291544985025905, 0.545881503504257, 0.12048320108981789, -0.8291544985025905, 0.5483907441273382, -0.809100088223958, 0.21124544726797653, 0.5483907441273382, 0.809100088223958, 0.21124544726797653, 0.5541093394289913, -0.5176080003344399, 0.6519545980720968, 0.5541093394289913, 0.5176080003344399, 0.6519545980720968, 0.5613283100572769, -0.7513701216091022, -0.3469199744629367, 0.5613283100572769, 0.7513701216091022, -0.3469199744629367, 0.574516613769574, -0.3065132259869937, 0.7589336616581113, 0.574516613769574, 0.3065132259869937, 0.7589336616581113, 0.5755224857007215, -0.22165711242617026, -0.7871734198788439, 0.5755224857007215, 0.22165711242617026, -0.7871734198788439, 0.5757874293000979, -0.418334054477401, 0.7024709639013442, 0.5757874293000979, 0.418334054477401, 0.7024709639013442, 0.5925026402964927, -0.6733376315905675, 0.4422183342260814, 0.5925026402964927, 0.6733376315905675, 0.4422183342260814, 0.595894253326634, -0.1589592585807398, 0.787173419878844, 0.595894253326634, 0.1589592585807398, 0.787173419878844, 0.6000378517471079, -0.7715762680897256, -0.21124544726797656, 0.600037851747108, -0.3322397296317068, -0.7277165234656735, 0.600037851747108, 0.3322397296317067, -0.7277165234656734, 0.600037851747108, 0.7715762680897256, -0.21124544726797656, 0.6035685408534394, 0, 0.7973111164984783, 0.6070619982066863, 0, -0.7946544722917661, 0.6156310292182142, -0.44728212428674363, -0.6487966839906476, 0.6156310292182142, 0.44728212428674363, -0.6487966839906476, 0.6189168071929713, -0.5594018111778118, -0.5513724688674999, 0.6189168071929714, 0.5594018111778118, -0.5513724688674999, 0.6252574586071488, -0.776288999232417, -0.08017792792821428, 0.6252574586071488, 0.776288999232417, -0.08017792792821428, 0.6297256213908132, -0.5740277938094211, 0.5233906129252252, 0.6297256213908132, 0.5740277938094211, 0.5233906129252252, 0.6384979619012642, -0.7685809667396409, 0.04004560167472076, 0.6384979619012642, 0.7685809667396409, 0.04004560167472076, 0.644957657958078, -0.08971798394659967, -0.7589336616581112, 0.644957657958078, 0.08971798394659967, -0.7589336616581112, 0.6459362967593755, -0.7055963265124218, 0.2913762593983249, 0.6459362967593755, 0.7055963265124218, 0.2913762593983249, 0.647543247338096, -0.7444509665688808, 0.1627283048565699, 0.647543247338096, 0.7444509665688808, 0.1627283048565699, 0.6477616832793808, -0.6481772114408144, -0.4003387368765019, 0.6477616832793808, 0.6481772114408144, -0.4003387368765019, 0.6537940206410678, -0.4750091605513505, 0.5889988760314302, 0.6537940206410678, 0.4750091605513505, 0.5889988760314302, 0.6623302008428754, -0.24491492196023698, 0.7080504120842295, 0.6623302008428754, 0.24491492196023698, 0.7080504120842295, 0.6635036642300076, -0.36703962947616986, 0.6519545980720968, 0.6635036642300076, 0.36703962947616986, 0.6519545980720968, 0.6797937675642476, -0.19116759016150825, -0.7080504120842296, 0.6797937675642476, 0.19116759016150822, -0.7080504120842295, 0.6807264326348014, -0.08390581259561895, 0.7277165234656735, 0.6807264326348014, 0.08390581259561895, 0.7277165234656735, 0.6893281612357385, -0.6158502249638206, 0.38151695445860245, 0.6893281612357385, 0.6158502249638206, 0.38151695445860245, 0.6897916878076654, -0.6755251623335724, -0.26048643436012703, 0.6897916878076654, 0.6755251623335724, -0.26048643436012703, 0.7074451234849853, -0.3016688104181362, -0.6391536013183534, 0.7074451234849853, 0.30166881041813615, -0.6391536013183533, 0.7117124032047751, 0, -0.7024709639013443, 0.7155242952261603, -0.6876704554941067, -0.12302165492966767, 0.7155242952261603, 0.6876704554941067, -0.12302165492966767, 0.7185891652507057, -0.5220855887185097, 0.45940858681215474, 0.7185891652507057, 0.5220855887185097, 0.45940858681215474, 0.7232785492748799, -0.41576019618739724, -0.5513724688674999, 0.7232785492748799, 0.41576019618739724, -0.5513724688674999, 0.7236067977499789, -0.5257311121191337, -0.447213595499958, 0.723606797749979, 0.5257311121191337, -0.447213595499958, 0.7266653661026955, -0.6768787187959852, 0.11744209529781557, 0.7266653661026955, 0.6768787187959852, 0.11744209529781557, 0.7267017243993803, -0.6869389665317207, 0.004411350734000925, 0.7267017243993803, 0.6869389665317207, 0.004411350734000925, 0.7297825215675532, -0.641115565076049, 0.2374622147452561, 0.7297825215675532, 0.641115565076049, 0.2374622147452561, 0.7405287926400659, -0.4215203121710784, 0.5233906129252252, 0.7405287926400659, 0.4215203121710784, 0.5233906129252252, 0.7496516053274307, -0.17177061608955554, 0.6391536013183533, 0.7496516053274307, 0.17177061608955554, 0.6391536013183533, 0.7521009799446995, -0.3035740818246284, 0.5849674288458774, 0.7521009799446995, 0.3035740818246284, 0.5849674288458774, 0.7525262214051114, -0.0930563708211101, -0.6519545980720968, 0.7525262214051114, 0.0930563708211101, -0.6519545980720968, 0.7609618011718721, 0, 0.6487966839906476, 0.7658127312019672, -0.5563955177061672, 0.32242036009760555, 0.7658127312019672, 0.5563955177061672, 0.32242036009760555, 0.7699505391839694, -0.5594018111778118, -0.3069947570583225, 0.7699505391839695, 0.5594018111778118, -0.3069947570583225, 0.7868988425360585, -0.19647727299831622, -0.5849674288458774, 0.7868988425360585, 0.19647727299831622, -0.5849674288458774, 0.794654472291766, -0.5773502691896257, 0.1875924740850802, 0.794654472291766, 0.5773502691896257, 0.1875924740850802, 0.7977502805111361, 0.5795995055195465, -0.16630966041063483, 0.7977502805111362, -0.5795995055195466, -0.16630966041063486, 0.7987224860367548, -0.46528185410555045, 0.38151695445860245, 0.7987224860367548, 0.46528185410555045, 0.38151695445860245, 0.8061011971354436, -0.585666801594933, 0.08482486360947541, 0.8061011971354436, 0.585666801594933, 0.08482486360947541, 0.8081338527952605, 0, -0.5889988760314302, 0.8085531618609739, 0.5874482582451998, -0.033857470804871996, 0.808553161860974, -0.5874482582451999, -0.033857470804872, 0.8097861540334745, -0.30622016907826805, -0.5004753668117452, 0.8097861540334745, 0.306220169078268, -0.5004753668117451, 0.816622529093059, -0.41576019618739724, -0.4003387368765019, 0.8166225290930591, 0.41576019618739724, -0.4003387368765019, 0.8234755272545975, -0.35543072586240004, 0.4422183342260814, 0.8234755272545975, 0.35543072586240004, 0.4422183342260814, 0.8295223498394129, -0.08877540026300262, 0.5513724688674999, 0.8295223498394129, 0.08877540026300262, 0.5513724688674999, 0.8351224597613233, -0.22824303804682877, 0.5004753668117452, 0.8351224597613233, 0.22824303804682877, 0.5004753668117452, 0.8352523372260013, -0.4959488176483333, 0.2374622147452561, 0.8352523372260013, 0.4959488176483333, 0.2374622147452561, 0.8468638011056542, -0.09425480719114633, -0.5233906129252252, 0.8468638011056542, 0.09425480719114633, -0.5233906129252252, 0.8556199616698322, -0.44728212428674363, -0.2604864343601271, 0.8556199616698322, 0.44728212428674363, -0.2604864343601271, 0.8683018636018623, -0.48193280435927155, 0.1174420952978156, 0.8683018636018623, 0.48193280435927155, 0.1174420952978156, 0.8706672771858278, -0.39628066808369156, 0.2913762593983249, 0.8706672771858278, 0.39628066808369156, 0.2913762593983249, 0.875122634874367, -0.4680021862650972, -0.12302165492966767, 0.875122634874367, -0.19647727299831622, -0.4422183342260814, 0.875122634874367, 0.19647727299831622, -0.4422183342260814, 0.875122634874367, 0.4680021862650972, -0.12302165492966767, 0.8778809630980393, -0.47885859563629063, 0.004411350734000925, 0.8778809630980393, 0.47885859563629063, 0.004411350734000925, 0.8880554375372868, -0.30166881041813615, -0.3469199744629367, 0.8880554375372868, 0.3016688104181361, -0.34691997446293665, 0.8882250561447018, 0, -0.45940858681215474, 0.8882250561447018, 0, -0.45940858681215463, 0.8944271909999159, 0, 0.447213595499958, 0.895768418755139, -0.2779306951014105, 0.3469199744629367, 0.895768418755139, 0.2779306951014105, 0.3469199744629367, 0.905039215834912, -0.14364161499041464, 0.4003387368765019, 0.905039215834912, 0.14364161499041464, 0.4003387368765019, 0.9081168108377711, -0.38580222481518056, 0.1627283048565699, 0.9081168108377711, 0.38580222481518056, 0.1627283048565699, 0.9192345310435216, -0.3322397296317068, -0.21124544726797656, 0.9192345310435216, 0.3322397296317068, -0.21124544726797656, 0.9196658769956818, -0.0930563708211101, -0.38151695445860245, 0.9196658769956819, 0.0930563708211101, -0.38151695445860245, 0.9282706578194226, -0.36974306703169696, 0.040045601674720765, 0.9282706578194226, 0.36974306703169696, 0.040045601674720765, 0.931509891817533, 0.35476868706133874, -0.0801779279282143, 0.9315098918175331, -0.3547686870613388, -0.08017792792821432, 0.9373125561577, -0.19116759016150822, -0.2913762593983249, 0.9373125561577, 0.19116759016150822, -0.2913762593983249, 0.9389619707336497, -0.271524913266781, 0.21124544726797656, 0.9389619707336497, 0.271524913266781, 0.21124544726797656, 0.9465965938004058, 0, -0.32242036009760555, 0.9517112057440018, 0, 0.3069947570583225, 0.9551169259871324, -0.14106195520847561, 0.2604864343601271, 0.9551169259871324, 0.14106195520847561, 0.2604864343601271, 0.9614507908933246, -0.22165711242617028, -0.16272830485656992, 0.9614507908933246, 0.22165711242617028, -0.16272830485656992, 0.9621351351385714, -0.2605138798701924, 0.0801779279282143, 0.9621351351385714, 0.2605138798701924, 0.0801779279282143, 0.967244736312809, -0.08971798394659967, -0.2374622147452561, 0.967244736312809, 0.08971798394659967, -0.2374622147452561, 0.9683162594941432, -0.24649537802113122, -0.04004560167472076, 0.9683162594941432, 0.24649537802113122, -0.04004560167472076, 0.9822469463768458, 0, -0.1875924740850802, 0.9830738669028043, -0.13576245663339054, 0.1230216549296677, 0.9830738669028043, 0.13576245663339054, 0.1230216549296677, 0.9857439588996775, -0.12048320108981783, -0.11744209529781555, 0.9857439588996775, 0.12048320108981783, -0.11744209529781555, 0.98607357578129, 0, 0.16630966041063486, 0.9916866386330564, -0.12860074160506021, -0.004411350734000926, 0.9916866386330564, 0.12860074160506021, -0.004411350734000926, 0.9963958764033671, 0, -0.08482486360947544, 0.9994266714825543, 0, 0.033857470804872}; float* get_dti_dirarr(unsigned int ndir) { if(ndir==3) return ps3; if(ndir==4) return ps4; if(ndir==5) return ps5; if(ndir==6) return ps6; if(ndir==7) return ps7; if(ndir==8) return ps8; if(ndir==9) return ps9; if(ndir==10) return ps10; if(ndir==11) return ps11; if(ndir==12) return ps12; if(ndir==13) return ps13; if(ndir==14) return ps14; if(ndir==15) return ps15; if(ndir==16) return ps16; if(ndir==17) return ps17; if(ndir==18) return ps18; if(ndir==19) return ps19; if(ndir==20) return ps20; if(ndir==21) return ps21; if(ndir==22) return ps22; if(ndir==23) return ps23; if(ndir==24) return ps24; if(ndir==25) return ps25; if(ndir==26) return ps26; if(ndir==27) return ps27; if(ndir==28) return ps28; if(ndir==29) return ps29; if(ndir==30) return ps30; if(ndir==31) return ps31; if(ndir==32) return ps32; if(ndir==33) return ps33; if(ndir==34) return ps34; if(ndir==35) return ps35; if(ndir==36) return ps36; if(ndir==37) return ps37; if(ndir==38) return ps38; if(ndir==39) return ps39; if(ndir==40) return ps40; if(ndir==41) return ps41; if(ndir==42) return ps42; if(ndir==43) return ps43; if(ndir==44) return ps44; if(ndir==45) return ps45; if(ndir==46) return ps46; if(ndir==47) return ps47; if(ndir==48) return ps48; if(ndir==49) return ps49; if(ndir==50) return ps50; if(ndir==51) return ps51; if(ndir==52) return ps52; if(ndir==53) return ps53; if(ndir==54) return ps54; if(ndir==55) return ps55; if(ndir==56) return ps56; if(ndir==57) return ps57; if(ndir==58) return ps58; if(ndir==59) return ps59; if(ndir==60) return ps60; if(ndir==61) return ps61; if(ndir==62) return ps62; if(ndir==63) return ps63; if(ndir==64) return ps64; if(ndir==65) return ps65; if(ndir==66) return ps66; if(ndir==67) return ps67; if(ndir==68) return ps68; if(ndir==69) return ps69; if(ndir==70) return ps70; if(ndir==71) return ps71; if(ndir==72) return ps72; if(ndir==73) return ps73; if(ndir==74) return ps74; if(ndir==75) return ps75; if(ndir==76) return ps76; if(ndir==77) return ps77; if(ndir==78) return ps78; if(ndir==79) return ps79; if(ndir==80) return ps80; if(ndir==81) return ps81; if(ndir==82) return ps82; if(ndir==83) return ps83; if(ndir==84) return ps84; if(ndir==85) return ps85; if(ndir==86) return ps86; if(ndir==87) return ps87; if(ndir==88) return ps88; if(ndir==89) return ps89; if(ndir==90) return ps90; if(ndir==91) return ps91; if(ndir==92) return ps92; if(ndir==93) return ps93; if(ndir==94) return ps94; if(ndir==95) return ps95; if(ndir==96) return ps96; if(ndir==97) return ps97; if(ndir==98) return ps98; if(ndir==99) return ps99; if(ndir==100) return ps100; if(ndir==101) return ps101; if(ndir==102) return ps102; if(ndir==103) return ps103; if(ndir==104) return ps104; if(ndir==105) return ps105; if(ndir==106) return ps106; if(ndir==107) return ps107; if(ndir==108) return ps108; if(ndir==109) return ps109; if(ndir==110) return ps110; if(ndir==111) return ps111; if(ndir==112) return ps112; if(ndir==113) return ps113; if(ndir==114) return ps114; if(ndir==115) return ps115; if(ndir==116) return ps116; if(ndir==117) return ps117; if(ndir==118) return ps118; if(ndir==119) return ps119; if(ndir==120) return ps120; if(ndir==121) return ps121; if(ndir==122) return ps122; if(ndir==123) return ps123; if(ndir==124) return ps124; if(ndir==125) return ps125; if(ndir==126) return ps126; if(ndir==127) return ps127; if(ndir==128) return ps128; if(ndir==129) return ps129; if(ndir==130) return ps130; if(ndir==131) return ps131; if(ndir==132) return ps132; if(ndir==133) return ps133; if(ndir==134) return ps134; if(ndir==135) return ps135; if(ndir==136) return ps136; if(ndir==137) return ps137; if(ndir==138) return ps138; if(ndir==139) return ps139; if(ndir==140) return ps140; if(ndir==141) return ps141; if(ndir==142) return ps142; if(ndir==143) return ps143; if(ndir==144) return ps144; if(ndir==145) return ps145; if(ndir==146) return ps146; if(ndir==147) return ps147; if(ndir==148) return ps148; if(ndir==149) return ps149; if(ndir==150) return ps150; // if(ndir==246) return ps246; // if(ndir==256) return ps256; // if(ndir==755) return ps755; return 0; } odin-1.8.5/odinseq/seqloop.cpp0000644000175000017500000003433511455553540013246 00000000000000#include "seqloop.h" #include "seqdelay.h" SeqObjLoop::SeqObjLoop(const STD_string& object_label) : SeqCounter(object_label), SeqObjList(object_label), times(0), numof_acq_cache(0), is_toplevel_reploop(false) { } SeqObjLoop::SeqObjLoop(const SeqObjLoop& sl) : numof_acq_cache(0), is_toplevel_reploop(false) { SeqObjLoop::operator = (sl); } SeqObjLoop& SeqObjLoop::operator = (const SeqObjLoop& sl) { SeqObjList::operator = ((const SeqObjList&)sl); // cast is necessary to avoid calling SeqObjList::operator = (const SeqObjLoop&) SeqCounter::operator = (sl); times=sl.times; return *this; } double SeqObjLoop::get_preduration() const { counterdriver->update_driver(this,this,&vectors); return counterdriver->get_preduration(); } double SeqObjLoop::get_postduration() const { counterdriver->update_driver(this,this,&vectors); return counterdriver->get_postduration(); } float SeqObjLoop::get_single_duration() const { counterdriver->update_driver(this,this,&vectors); // required for correct preduration/postduration_inloop return counterdriver->get_preduration_inloop()+SeqObjList::get_duration()+counterdriver->get_postduration_inloop(); } STD_string SeqObjLoop::get_program(programContext& context) const { Log odinlog(this,"SeqObjLoop::get_program"); STD_string result; if(!get_times()) return result; counterdriver->outdate_cache(); counterdriver->update_driver(this,this,&vectors); if(unroll_program(context)) { ODINLOG(odinlog,normalDebug) << "unrolling loop in program" << STD_endl; // retrieve kernel with counter set to 1st iteration so that can be used later to avoid multiple get_program() calls init_counter(); prep_veciterations(); STD_string loopkernel=SeqObjList::get_program(context); // do we actually have to create a program? if(!counterdriver->create_program(context,loopkernel)) { return result; } result+=counterdriver->get_program_head_unrolled(context, 0); result+=loopkernel; // retrieve remaining loop kernels increment_counter(); for(; get_counter()get_program_head_unrolled(context, get_counter()); result+=SeqObjList::get_program(context); } disable_counter(); prep_veciterations(); // Reset to default iteration if outside loop } else { // unroll_program ODINLOG(odinlog,normalDebug) << "loop command in program" << STD_endl; context.nestlevel++; context.neststatus=true; disable_counter(); // retrieve kernel with counter disabled so that can be used later with loop commands ODINLOG(odinlog,normalDebug) << "retrieving initial loopkernel" << STD_endl; STD_string loopkernel=SeqObjList::get_program(context); // do we actually have to create a program? if(!counterdriver->create_program(context,loopkernel)) { context.nestlevel--; context.neststatus=false; return result; } result+=counterdriver->get_program_head(context,loopkernel,get_times()); result+=loopkernel; context.nestlevel--; result+=counterdriver->get_program_tail(context,loopkernel,get_times()); context.neststatus=false; } return result; } double SeqObjLoop::get_duration() const { Log odinlog(this,"get_duration"); double result=0.0; counterdriver->update_driver(this,this,&vectors); result+=counterdriver->get_preduration(); result+=counterdriver->get_postduration(); double preduration_inloop =counterdriver->get_preduration_inloop(); double postduration_inloop=counterdriver->get_postduration_inloop(); if(!is_repetition_loop(true)) { ODINLOG(odinlog,normalDebug) << "is vector loop" << STD_endl; for(init_counter(); get_counter()set_times(t); } times=t; return *this; } int SeqObjLoop::get_times() const { Log odinlog(this,"get_times"); if(n_vectors()) { return SeqCounter::get_times(); } else { ODINLOG(odinlog,normalDebug) << "times=" << times << STD_endl; return times; } } unsigned int SeqObjLoop::get_numof_acq() const { if(numof_acq_cache) return numof_acq_cache; queryContext context; context.action=count_acqs; unsigned int result=0; if(is_obj_repetition_loop()) { SeqObjList::query(context); result=context.numof_acqs*get_times(); } else { for(init_counter(); get_counter() odinlog(this,"query"); if(context.action==tag_toplevel_reploop) { if(is_repetition_loop() && get_times()>1 && context.repetitions_prot==get_times()) { if(get_numof_acq()) is_toplevel_reploop=true; // do not tag dummy loops } return; // do not query sub-branch } SeqObjList::query(context); // default if(context.action==count_acqs) context.numof_acqs=get_numof_acq(); } bool SeqObjLoop::contains_acq_iter() const { queryContext qc; qc.action=check_acq_iter; SeqObjList::query(qc); return qc.check_acq_iter_result; } RecoValList SeqObjLoop::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { Log odinlog(this,"get_recovallist"); RecoValList result(get_label()); if(!contains_acq_iter() && is_acq_repetition_loop()) { unsigned int totaltimes=reptimes*get_times(); ODINLOG(odinlog,normalDebug) << "repetition loop reptimes/get_times()/totaltimes=" << reptimes << "/" << get_times() << "/" << totaltimes << STD_endl; for(constiter it=get_const_begin();it!=get_const_end();++it) { result.add_sublist((*it)->get_recovallist(totaltimes,coords)); } result.multiply_repetitions(get_times()); } else { ODINLOG(odinlog,normalDebug) << "explicit loop reptimes/get_times()=" << reptimes << "/" << get_times() << STD_endl; RecoValList* thisiter; for(init_counter(); get_counter()get_label() << STD_endl; thisiter->add_sublist((*it)->get_recovallist(reptimes,coords)); } result.add_sublist(*thisiter); delete thisiter; } disable_counter(); } return result; } SeqObjLoop& SeqObjLoop::operator () (const SeqObjBase& embeddedBody) { Log odinlog(this,"operator () (const SeqObjBase&)"); ODINLOG(odinlog,normalDebug) << " label=" << get_label() << STD_endl; SeqObjLoop& loop=set_embed_body(embeddedBody); ODINLOG(odinlog,normalDebug) << " loop.label=" << loop.get_label() << STD_endl; return loop; } unsigned int SeqObjLoop::event(eventContext& context) const { Log odinlog(this,"event"); unsigned int result=0; looplevel++; counterdriver->update_driver(this,this,&vectors); double predur=counterdriver->get_preduration(); ODINLOG(odinlog,normalDebug) << "predur=" << predur << STD_endl; if(predur) { SeqDelay sd("predelay",predur); result+=sd.event(context); } int niterations=get_times(); ODINLOG(odinlog,normalDebug) << "niterations=" << niterations << STD_endl; // within fSEQCheck it is sufficient to call the loop kernel for only one iteration: if( context.action==seqRun && context.seqcheck && is_repetition_loop(true) ) { niterations=1; } // to count events, is is sufficient to call the loop kernel for only one iteration: unsigned count_factor=1; if(context.action==countEvents && is_obj_repetition_loop()) { niterations=1; count_factor=get_times(); } unsigned int n_events=0; for(init_counter(); get_counter()get_postduration_inloop(); if(postdur_inloop) { SeqDelay sd("postdelay_inloop",postdur_inloop); n_events+=sd.event(context); } } disable_counter(); prep_veciterations(); // Reset to default iteration if outside loop result+=n_events*count_factor; looplevel--; double postdur=counterdriver->get_postduration(); ODINLOG(odinlog,normalDebug) << "postdur=" << postdur << STD_endl; if(postdur) { SeqDelay sd("postdelay",postdur); result+=sd.event(context); } return result; } SeqValList SeqObjLoop::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()+STD_string("freqlist")); if(is_repetition_loop()) { for(constiter it=get_const_begin();it!=get_const_end();++it) { result.add_sublist((*it)->get_freqvallist(action)); } result.multiply_repetitions(get_times()); } else { SeqValList* thisiter; for(init_counter(); get_counter()add_sublist((*it)->get_freqvallist(action)); } result.add_sublist(*thisiter); delete thisiter; } disable_counter(); } return result; } SeqValList SeqObjLoop::get_delayvallist() const { Log odinlog(this,"get_delayvallist"); SeqValList result(get_label()+STD_string("delaylist")); if(is_repetition_loop()) { for(constiter it=get_const_begin();it!=get_const_end();++it) { result.add_sublist((*it)->get_delayvallist()); } result.multiply_repetitions(get_times()); } else { SeqValList* thisiter; for(init_counter(); get_counter()add_sublist((*it)->get_delayvallist()); } result.add_sublist(*thisiter); delete thisiter; } disable_counter(); } return result; } double SeqObjLoop::get_rf_energy() const { double result=0.0; if(is_repetition_loop(true)) result=SeqObjList::get_rf_energy()*get_times(); else { for(init_counter(); get_counter()outdate_cache(); return *this; } SeqObjLoop& SeqObjLoop::operator [] (unsigned int t) { set_times(t); counterdriver->outdate_cache(); return *this; } bool SeqObjLoop::is_repetition_loop(bool only_qualvectors) const { Log odinlog(this,"is_repetition_loop"); if(only_qualvectors) { bool result=true; for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { if((*veciter)->is_qualvector()) { ODINLOG(odinlog,normalDebug) << (*veciter)->get_label() << " alters" << STD_endl; result=false; } else ODINLOG(odinlog,normalDebug) << (*veciter)->get_label() << " NOT alters" << STD_endl; } ODINLOG(odinlog,normalDebug) << result << STD_endl; return result; } else return !(n_vectors()); } bool SeqObjLoop::is_acq_repetition_loop() const { Log odinlog(this,"is_acq_repetition_loop"); if(is_repetition_loop()) { ODINLOG(odinlog,normalDebug) << "is_repetition_loop()==true" << STD_endl; return true; } bool result=true; for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { if((*veciter)->is_acq_vector()) { ODINLOG(odinlog,normalDebug) << (*veciter)->get_label() << " is acq vector" << STD_endl; result=false; break; } else ODINLOG(odinlog,normalDebug) << (*veciter)->get_label() << " is NOT acq vector" << STD_endl; } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } bool SeqObjLoop::is_obj_repetition_loop() const { for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { if((*veciter)->is_obj_vector()) return false; } return true; } bool SeqObjLoop::unroll_program(programContext& context) const { return counterdriver->unroll_program(this,this,&vectors,context); } SeqObjLoop& SeqObjLoop::set_body(const SeqObjBase& so) { clear(); (*this)+=(so); counterdriver->outdate_cache(); return *this; } bool SeqObjLoop::prep() { Log odinlog(this,"prep"); if(!SeqObjList::prep()) return false; if(!SeqCounter::prep()) return false; for(constinstiter it=get_const_inst_begin();it!=get_const_inst_begin();++it) { if((*it)->get_times()==0) { ODINLOG(odinlog,warningLog) << "loop " << (*it)->get_label() << " has 0 iterations" << STD_endl; } } // reset for next prep_acquisition numof_acq_cache=0; is_toplevel_reploop=false; return true; } void SeqObjLoop::clear_container() { SeqObjList::clear_container(); SeqCounter::clear_container(); Embed::clear_instances(); } STD_string SeqObjLoop::get_properties() const { return "Times="+itos(get_times())+", NumOfVectors="+itos(n_vectors())+", "+SeqObjList::get_properties(); } void SeqObjLoop::add_vector(const SeqVector& seqvector) { Log odinlog(this,"add_vector"); for(institer it=get_inst_begin();it!=get_inst_end();++it) { (*it)->add_vector(seqvector); } SeqCounter::add_vector(seqvector); } odin-1.8.5/odinseq/seqparallel.cpp0000644000175000017500000001526411322062345014060 00000000000000#include "seqparallel.h" #include "seqdelay.h" #include "seqgradchan.h" #include "seqgradchanparallel.h" #include SeqParallel::SeqParallel(const STD_string& object_label) : SeqObjBase(object_label), pardriver(object_label) { } SeqParallel::SeqParallel(const SeqParallel& sgp) : pardriver(sgp.get_label()) { SeqParallel::operator = (sgp); } SeqParallel& SeqParallel::operator = (const SeqParallel& sgp) { SeqObjBase::operator = (sgp); pardriver=sgp.pardriver; pulsptr=sgp.pulsptr; gradptr=sgp.gradptr; return *this; } SeqParallel& SeqParallel::operator /= (SeqGradChan& sgc) { SeqGradChanParallel* sgcp=new SeqGradChanParallel(sgc.get_label()); sgcp->set_temporary(); (*sgcp)+=sgc; set_gradptr((SeqGradObjInterface*)sgcp); return *this; } SeqParallel& SeqParallel::operator /= (SeqGradChanList& sgcl) { SeqGradChanParallel* sgcp=new SeqGradChanParallel(sgcl.get_label()); sgcp->set_temporary(); (*sgcp)+=sgcl; set_gradptr((SeqGradObjInterface*)sgcp); return *this; } SeqParallel& SeqParallel::operator /= (SeqGradChanParallel& sgcp) { set_gradptr((SeqGradObjInterface*)&sgcp); return *this; } SeqParallel& SeqParallel::operator /= (SeqGradObjInterface& sgoa) { set_gradptr((SeqGradObjInterface*)&sgoa); return *this; } SeqParallel& SeqParallel::operator /= (const SeqObjBase& soa) { SeqObjList* sol=new SeqObjList(soa.get_label()); sol->set_temporary(); (*sol)+=soa; set_pulsptr(sol); return *this; } double SeqParallel::get_duration() const { Log odinlog(this,"SeqParallel::get_duration()"); const SeqObjBase* soa=get_pulsptr(); const SeqGradObjInterface* sgoa=get_const_gradptr(); double result=0.0; if(soa) result=soa->get_duration(); double graddur=0.0; if(sgoa) graddur=sgoa->get_gradduration(); if(graddur>result) result=graddur; double dur_driver=pardriver->get_duration(soa,sgoa); if(dur_driver>result) result=dur_driver; return result; } double SeqParallel::get_gradduration() const { Log odinlog(this,"SeqParallel::get_gradduration()"); double result=0.0; const SeqGradObjInterface* sgoa=get_const_gradptr(); if(sgoa) { result=sgoa->get_gradduration(); ODINLOG(odinlog,normalDebug) << "gradduration=" << result << STD_endl; } else ODINLOG(odinlog,normalDebug) << "no gradobject defined" << STD_endl; return result; } double SeqParallel::get_pulprogduration() const { return pardriver->get_predelay(get_pulsptr(),get_const_gradptr()); } SeqGradInterface& SeqParallel::set_strength(float gradstrength) { SeqGradObjInterface* sgoa=get_gradptr(); if(sgoa) sgoa->set_strength(gradstrength); return *this; } SeqGradInterface& SeqParallel::invert_strength() { SeqGradObjInterface* sgoa=get_gradptr(); if(sgoa) sgoa->invert_strength(); return *this; } float SeqParallel::get_strength() const { float result=0.0; const SeqGradObjInterface* sgoa=get_const_gradptr(); if(sgoa) result=sgoa->get_strength(); return result; } SeqGradInterface& SeqParallel::set_gradrotmatrix(const RotMatrix& matrix) { SeqGradObjInterface* sgoa=get_gradptr(); if(sgoa) sgoa->set_gradrotmatrix(matrix); return *this; } fvector SeqParallel::get_gradintegral() const { fvector result(3); const SeqGradObjInterface* sgoa=get_const_gradptr(); if(sgoa) result=sgoa->get_gradintegral(); return result; } void SeqParallel::query(queryContext& context) const { SeqTreeObj::query(context); // default context.parentnode=this; const SeqObjBase* soa=get_pulsptr(); context.treelevel++; if(soa) soa->query(context); if(context.action!=count_acqs) { context.parentnode=this; // reset to this because it might changed by last query const SeqGradObjInterface* sgoa=get_const_gradptr(); if(sgoa) sgoa->query(context); } context.treelevel--; } RecoValList SeqParallel::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { RecoValList result(get_label()); const SeqObjBase* soa=get_pulsptr(); if(soa) result=soa->get_recovallist(reptimes,coords); return result; } STD_string SeqParallel::get_properties() const { STD_string result; if(get_pulsptr()) result+="RF"; else result+="-"; result+="/"; if(get_const_gradptr()) result+="Grad"; else result+="-"; return result; } unsigned int SeqParallel::event(eventContext& context) const { Log odinlog(this,"event"); unsigned int result=0; double startelapsed=context.elapsed; ODINLOG(odinlog,normalDebug) << "startelapsed=" << startelapsed << STD_endl; const SeqObjBase* soa=get_pulsptr(); const SeqGradObjInterface* sgoa=get_const_gradptr(); double starteleapsed_pre=startelapsed+pardriver->get_predelay(soa,sgoa); bool flush_cache=context.noflush; context.noflush=true; context.elapsed=starteleapsed_pre; if(sgoa) result+=sgoa->event(context); context.elapsed=starteleapsed_pre; if(soa) result+=soa->event(context); context.noflush=flush_cache; context.elapsed=startelapsed+get_duration(); return result; } SeqValList SeqParallel::get_freqvallist(freqlistAction action) const { const SeqObjBase* soa=get_pulsptr(); if(soa) return soa->get_freqvallist(action); else return SeqValList(); } SeqValList SeqParallel::get_delayvallist() const { const SeqObjBase* soa=get_pulsptr(); if(soa) return soa->get_delayvallist(); else return SeqValList(); } double SeqParallel::get_rf_energy() const { double result=0.0; const SeqObjBase* soa=get_pulsptr(); if(soa) result=soa->get_rf_energy(); return result; } void SeqParallel::clear() { pulsptr.clear_handledobj(); gradptr.clear_handledobj(); const_gradptr.clear_handledobj(); } SeqParallel& SeqParallel::set_pulsptr(const SeqObjBase* pptr) { pulsptr.set_handled(pptr); return *this; } const SeqObjBase* SeqParallel::get_pulsptr() const {return pulsptr.get_handled();} SeqParallel& SeqParallel::set_gradptr(SeqGradObjInterface* gptr) { gradptr.set_handled(gptr); return *this; } SeqParallel& SeqParallel::set_gradptr(const SeqGradObjInterface* gptr) { const_gradptr.set_handled(gptr); return *this; } SeqParallel& SeqParallel::clear_gradptr() { gradptr.clear_handledobj(); const_gradptr.clear_handledobj(); return *this; } SeqGradObjInterface* SeqParallel::get_gradptr() const {return gradptr.get_handled();} const SeqGradObjInterface* SeqParallel::get_const_gradptr() const { if(gradptr.get_handled()) return gradptr.get_handled(); else return const_gradptr.get_handled(); } // Template instantiations template class Handled; template class Handler; template class Handled; template class Handler; template class Handled; template class Handler; odin-1.8.5/odinseq/seqclass.cpp0000644000175000017500000001275311455553540013402 00000000000000#include "seqclass.h" #include "seqplatform.h" #include "seqvec.h" #include #include const char* Seq::get_compName() {return "Seq";} LOGGROUNDWORK(Seq) /////////////////////////////////////////////////////////////////////////// SeqClass::SeqClass() : systemInfo(*systemInfo_ptr) { Log odinlog("SeqClass","SeqClass"); set_label("unnamedSeqClass"); // Do NOT use the MessageHandlers in here if(allseqobjs) allseqobjs->push_back(this); } SeqClass::~SeqClass() { Log odinlog(this,"~SeqClass"); if(allseqobjs) allseqobjs->remove(this); if(tmpseqobjs) tmpseqobjs->remove(this); if(seqobjs2prep) seqobjs2prep->remove(this); if(seqobjs2clear) seqobjs2clear->remove(this); } SeqClass& SeqClass::operator = (const SeqClass& sc) { Labeled::operator = (sc); return *this; } void SeqClass::marshall_error() const { Log odinlog(this, "marshall_error"); ODINLOG(odinlog,errorLog) << "Marshalling error: No sub-object available" << STD_endl; } bool SeqClass::prep_all() { Log odinlog("SeqClass","prep_all"); bool result=true; STD_list< SeqClass* >::iterator it; // two stage iteration through the list because prep() may modify the 'allseqobjs' list seqobjs2prep->clear(); for(it=allseqobjs->begin(); it!=allseqobjs->end(); ++it) { (*it)->prepped=false; seqobjs2prep->push_back(*it); } while(seqobjs2prep->begin()!=seqobjs2prep->end()) { ODINLOG(odinlog,normalDebug) << "seqobjs2prep->size()=" << seqobjs2prep->size() << STD_endl; SeqClass* scs=*(seqobjs2prep->begin()); bool do_prep=true; if(scs->prepped) do_prep=false; if(do_prep) { ODINLOG(odinlog,normalDebug) << "prepping " << scs->get_label() << STD_endl; if(!(scs->prep())) { result=false; ODINLOG(odinlog,errorLog) << scs->get_label() << "->prep() failed" << STD_endl; } scs->prepped=true; } seqobjs2prep->remove(scs); } return result; } void SeqClass::init_static() { Log odinlog("SeqClass","init_static"); allseqobjs.init("allseqobjs"); tmpseqobjs.init("tmpseqobjs"); seqobjs2prep.init("seqobjs2prep"); seqobjs2clear.init("seqobjs2clear"); ODINLOG(odinlog,normalDebug) << "seqobjs done" << STD_endl; geometryInfo.init("geometryInfo"); ODINLOG(odinlog,normalDebug) << "geometryInfo done" << STD_endl; studyInfo.init("studyInfo"); ODINLOG(odinlog,normalDebug) << "studyInfo done" << STD_endl; recoInfo.init("recoInfo"); ODINLOG(odinlog,normalDebug) << "recoInfo done" << STD_endl; systemInfo_ptr=new SystemInterface(); // create systemInfo_platform ODINLOG(odinlog,normalDebug) << "systemInfo_ptr done" << STD_endl; SeqPlatformProxy(); // create platform instances } void SeqClass::destroy_static() { Log odinlog("SeqClass","destroy_static"); delete systemInfo_ptr; recoInfo.destroy(); geometryInfo.destroy(); studyInfo.destroy(); seqobjs2clear.destroy(); seqobjs2prep.destroy(); tmpseqobjs.destroy(); allseqobjs.destroy(); } SeqClass& SeqClass::set_temporary() { if(tmpseqobjs) tmpseqobjs->push_back(this); return *this; } void SeqClass::clear_temporary() { Log odinlog("SeqClass","clear_temporary"); if(!tmpseqobjs) return; STD_list garbage; STD_list::iterator it; for(it=tmpseqobjs->begin(); it!=tmpseqobjs->end(); ++it) { ODINLOG(odinlog,normalDebug) << "tmpobj >" << (*it)->get_label() << "<" << STD_endl; garbage.push_back(*it); } tmpseqobjs->erase(tmpseqobjs->begin(),tmpseqobjs->end()); for(it=garbage.begin(); it!=garbage.end(); ++it) { ODINLOG(odinlog,normalDebug) << "deleting >" << (*it)->get_label() << "<(" << (void*)(*it) << ")" << STD_endl; allseqobjs->remove(*it); delete (*it); } } void SeqClass::clear_containers() { Log odinlog("SeqClass","clear_containers"); STD_list< SeqClass*>::iterator it; // two stage iteration through the list because clear_container() may modify the 'allseqobjs' list seqobjs2clear->clear(); for(it=allseqobjs->begin(); it!=allseqobjs->end(); ++it) seqobjs2clear->push_back(*it); while(seqobjs2clear->begin()!=seqobjs2clear->end()) { SeqClass* scs=*(seqobjs2clear->begin()); ODINLOG(odinlog,normalDebug) << "clearing >" << scs->get_label() << "<" << STD_endl; scs->clear_container(); ODINLOG(odinlog,normalDebug) << "removing >" << scs->get_label() << "<" << STD_endl; seqobjs2clear->remove(scs); } } void SeqClass::clear_objlists() { if(allseqobjs) allseqobjs->clear(); if(tmpseqobjs) tmpseqobjs->clear(); if(seqobjs2prep) seqobjs2prep->clear(); if(seqobjs2clear) seqobjs2clear->clear(); } SystemInterface* SeqClass::systemInfo_ptr; template class SingletonHandler; SingletonHandler SeqClass::geometryInfo; template class SingletonHandler; SingletonHandler SeqClass::studyInfo; template class SingletonHandler; SingletonHandler SeqClass::recoInfo; template class SingletonHandler; SingletonHandler SeqClass::allseqobjs; SingletonHandler SeqClass::tmpseqobjs; SingletonHandler SeqClass::seqobjs2prep; SingletonHandler SeqClass::seqobjs2clear; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; SeqVector& SeqClass::get_dummyvec() { if(!dummyvec) dummyvec=new SeqVector("dummyvec"); return *dummyvec; } SeqVector* SeqClass::dummyvec=0; odin-1.8.5/odinseq/seqgradphase.h0000644000175000017500000001576511455553540013706 00000000000000/*************************************************************************** seqgradphase.h - description ------------------- begin : Tue Mar 21 2006 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADPHASE_H #define SEQGRADPHASE_H #include #include #define DEFAULT_ACL_BANDS 4 /** * @addtogroup odinseq * @{ */ /** * \brief Phase Encoding * * A phase encoding gradient * */ class SeqGradPhaseEnc : public SeqGradVectorPulse { public: /** * Constructs a phase encoding gradient labeled 'object_label' with the following properties: * - nsteps: The number of phase encoding steps * - fov: The Field of View * - gradchannel: The channel this object should be played out * - gradstrength: The maximum gradient strength * - scheme: The phase encoding scheme * - reorder: The reordering scheme * - nsegments: The number of segments for segmented reordering * - reduction: Reduction factor for parallel imaging (sparsely sampled k-space) * - acl_bands: Number of autocalibration bands (bunch of adjacent lines between actual k-space lines) for GRAPPA * - partial_fourier: The amount of partial Fourier undersampling (0=no undersampling, 1=half fourier) * - nucleus: The nucleus this object should be calculated for */ SeqGradPhaseEnc(const STD_string& object_label, unsigned int nsteps, float fov, direction gradchannel, float gradstrength, encodingScheme scheme=linearEncoding, reorderScheme reorder=noReorder, unsigned int nsegments=1, unsigned int reduction=1, unsigned int acl_bands=DEFAULT_ACL_BANDS, float partial_fourier=0.0, const STD_string& nucleus=""); /** * Constructs a phase encoding gradient labeled 'object_label' with the following properties: * - nsteps: The number of phase encoding steps * - fov: The Field of View * - gradduration: The duration of the gradient * - gradchannel: The channel this object should be played out * - scheme: The phase encoding scheme * - reorder: The reordering scheme * - nsegments: The number of segments for segmented reordering * - reduction: Reduction factor for parallel imaging (sparsely sampled k-space) * - acl_bands: Number of autocalibration bands (bunch of adjacent lines between actual k-space lines) for GRAPPA * - partial_fourier: The amount of partial Fourier undersampling (0=no undersampling, 1=half fourier) * - nucleus: The nucleus this object should be calculated for */ SeqGradPhaseEnc(const STD_string& object_label, unsigned int nsteps, float fov, float gradduration, direction gradchannel, encodingScheme scheme=linearEncoding, reorderScheme reorder=noReorder, unsigned int nsegments=1, unsigned int reduction=1, unsigned int acl_bands=DEFAULT_ACL_BANDS, float partial_fourier=0.0, const STD_string& nucleus=""); /** * Constructs an empty phase encoding gradient labeled 'object_label' */ SeqGradPhaseEnc(const STD_string& object_label="unnamedSeqGradPhaseEnc") : SeqGradVectorPulse(object_label) {} /** * Constructs a copy of 'sgpe' */ SeqGradPhaseEnc(const SeqGradPhaseEnc& sgpe) {SeqGradPhaseEnc::operator = (sgpe);} /** * Assignment operator that makes this object become a copy of 'sgpe' */ SeqGradPhaseEnc& operator = (const SeqGradPhaseEnc& sgpe) {SeqGradVectorPulse::operator = (sgpe); return *this;} private: void init_encoding(unsigned int nsteps,encodingScheme scheme, reorderScheme reorder, unsigned int nsegments, unsigned int reduction, unsigned int acl_bands, float partial_fourier); }; /////////////////////////////////////////////////////////////////////////////////////////////////// /** * \brief Flow-Compensated Phase Encoding * * A phase encoding gradient with 1st order flow compensation * */ class SeqGradPhaseEncFlowComp : public SeqGradChanList { public: /** * Constructs a flow-compensated phase encoding gradient labeled 'object_label' with the following properties: * - t0: The starting time of the gradient after excitation * - nsteps: The number of phase encoding steps * - fov: The Field of View * - gradchannel: The channel this object should be played out * - gradstrength: The maximum gradient strength * - scheme: The phase encoding scheme * - reorder: The reordering scheme * - nsegments: The number of segments for segmented reordering * - reduction: Reduction factor for parallel imaging (sparsely sampled k-space) * - acl_bands: Number of autocalibration bands (bunch of adjacent lines between actual k-space lines) for GRAPPA * - partial_fourier: The amount of partial Fourier undersampling (0=no undersampling, 1=half fourier) * - nucleus: The nucleus this object should be calculated for */ SeqGradPhaseEncFlowComp(const STD_string& object_label, double t0, unsigned int nsteps, float fov, direction gradchannel, float gradstrength, encodingScheme scheme=linearEncoding, reorderScheme reorder=noReorder, unsigned int nsegments=1, unsigned int reduction=1, unsigned int acl_bands=DEFAULT_ACL_BANDS, float partial_fourier=0.0, const STD_string& nucleus=""); /** * Constructs an empty flow-compensated phase encoding gradient labeled 'object_label' */ SeqGradPhaseEncFlowComp(const STD_string& object_label="unnamedSeqGradPhaseEncFlowComp") : SeqGradChanList(object_label) {} /** * Constructs a copy of 'sgpefc' */ SeqGradPhaseEncFlowComp(const SeqGradPhaseEncFlowComp& sgpefc) {SeqGradPhaseEncFlowComp::operator = (sgpefc);} /** * Assignment operator that makes this object become a copy of 'sgpefc' */ SeqGradPhaseEncFlowComp& operator = (const SeqGradPhaseEncFlowComp& sgpefc); /** * conversion operator for loop insertion */ operator const SeqVector& () const {return simvec;} private: void build_seq(); static void calc_flowcomp_pe(float& negfact, float& tc, float Gpos, float M0, float t0, float slewrate); SeqGradVectorPulse pos; SeqGradVectorPulse neg; SeqSimultanVector simvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqpulsar.cpp0000644000175000017500000003741111322062345013570 00000000000000#include "seqpulsar.h" #include "seqsim.h" #include "seqgradramp.h" #include SeqPulsar::SeqPulsar(const STD_string& object_label, bool rephased, bool interactive) : SeqPulsNdim(object_label), OdinPulse(object_label) { Log odinlog(this,"SeqPulsar(object_label)"); register_pulse(this); for(int i=0;i odinlog(this,"~SeqPulsar"); unregister_pulse(this); for(int i=0;i odinlog(this,"set_flipangle"); OdinPulse::set_flipangle(flipangle); // refresh(); return *this; } SeqPulsInterface& SeqPulsar::set_pulsduration(float pulsduration) { Log odinlog(this,"set_pulsduration"); OdinPulse::set_Tp(pulsduration); // refresh(); return *this; } SeqPulsInterface& SeqPulsar::set_power(float pulspower) { SeqPulsNdim::set_power(pulspower); attenuation_set=true; return *this; } SeqPulsInterface& SeqPulsar::set_pulse_type(pulseType type) { SeqPulsNdim::set_pulse_type(type); OdinPulse::set_pulse_type(type); return *this; } SeqPulsar& SeqPulsar::set_rephased(bool rephased, float strength) { Log odinlog(this,"set_refocused"); rephased_pulse=rephased; rephaser_strength=strength; SeqPulsar::update(); return *this; } fvector SeqPulsar::get_reph_gradintegral() const { fvector result(n_directions); result=0.0; for(int i=0;iget_gradintegral(); } return result; } SeqPulsar& SeqPulsar::operator = (const SeqPulsar& sp) { Log odinlog(this,"operator="); always_refresh=sp.always_refresh; // assign before OdinPulse::operator = to avoid call of SeqPulsar::update() OdinPulse::operator = (sp); SeqPulsNdim::operator = (sp); attenuation_set=sp.attenuation_set; rephased_pulse=sp.rephased_pulse; rephaser_strength=sp.rephaser_strength; SeqPulsar::update(); // do NOT call virtual function in constructor return *this; } OdinPulse& SeqPulsar::update() { Log odinlog(this,"update"); if(always_refresh) refresh(); return *this; } SeqPulsar& SeqPulsar::set_interactive(bool flag) { always_refresh=flag; return *this; } STD_string SeqPulsar::get_properties() const { return "Shape="+get_shape()+", Trajectory="+get_trajectory()+", Filter="+get_filter(); } SeqPulsar& SeqPulsar::refresh() { Log odinlog(this,"refresh"); int i,j,index; SeqPulsNdim::set_nucleus(OdinPulse::get_nucleus()); OdinPulse::recalc_pulse(); int npts=OdinPulse::get_size(); float Tp=OdinPulse::get_Tp(); float dt=secureDivision(Tp,float(npts)); float G0=OdinPulse::get_G0(); ODINLOG(odinlog,normalDebug) << "npts/Tp/dt/G0=" << npts << "/" << Tp << "/" << dt << "/" << G0 << STD_endl; fvector pulsegrad[n_directions]; for(i=0;iGinitMax) { GinitMax=fabs(Ginit); GinitMaxChannel=direction(i); } } ODINLOG(odinlog,normalDebug) << "GinitMax/GinitMaxChannel=" << GinitMax << "/" << GinitMaxChannel << STD_endl; // find maximum final gradient strength float GfinalMax=0.0; direction GfinalMaxChannel=readDirection; for(i=0;iGfinalMax) { GfinalMax=fabs(Gfinal); GfinalMaxChannel=direction(i); } } ODINLOG(odinlog,normalDebug) << "GfinalMax=" << GfinalMax << STD_endl; ODINLOG(odinlog,normalDebug) << "GfinalMaxChannel=" << GfinalMaxChannel << STD_endl; // use gradient ramp objects to generate the pulse ramps // these are pointers because of the delete[]-does-not-call-destructor-of-base-class bug in GCC SeqGradRamp* onramp[n_directions]; SeqGradRamp* offramp[n_directions]; for(i=0;iget_duration(); ODINLOG(odinlog,normalDebug) << "maxinit/dur[" << i << "]=" << initStrength*G0 << "/" << onrampdur << STD_endl; } if(i==GfinalMaxChannel && finalStrength!=0.0) { offramp[i]=new SeqGradRamp("offramp",direction(i),finalStrength*G0,0.0,dt); offrampdur=(offramp[i])->get_duration(); ODINLOG(odinlog,normalDebug) << "maxfinal/dur[" << i << "]=" << finalStrength*G0 << "/" << offrampdur << STD_endl; } } // generate the other ramps for(i=0;iget_npts(); int rampOff_npts=0; if(offramp[GfinalMaxChannel]) rampOff_npts=offramp[GfinalMaxChannel]->get_npts(); int total_pts=rampOn_npts+npts+rampOff_npts; ODINLOG(odinlog,normalDebug) << "dt=" << dt << STD_endl; ODINLOG(odinlog,normalDebug) << "rampOn_npts=" << rampOn_npts << STD_endl; ODINLOG(odinlog,normalDebug) << "rampOff_npts=" << rampOff_npts << STD_endl; // the arrays that will be assigned to the SeqPulsNdim base class cvector wv(total_pts); fvector Gpulse[n_directions]; for(i=0;iget_strength()/G0; else Gpulse[i][j]=0.0; } } /////////////////////////////////// // Gradient part No 2 cvector b1pulse=OdinPulse::get_B1(); for(j=0;jget_strength()/G0; else Gpulse[i][index]=0.0; } } /////////////////////////////////// // Deal with rephasing gradient lobe bool add_refoc_lobe=false; if(rephased_pulse && get_rel_center()!=1.0) add_refoc_lobe=true; ODINLOG(odinlog,normalDebug) << "add_refoc_lobe=" << add_refoc_lobe << STD_endl; // calculate the gradient integral that will be rephased float rephase_integral[n_directions]; for(i=0;i0.0) { reph_grad[i]=new SeqGradTrapez(get_label()+"_reph_grad", -rephase_integral[i], rephaser_strength, direction(i)); } else { reph_grad[i]=new SeqGradTrapez(get_label()+"_reph_grad", -rephase_integral[i], direction(i), rephdur); } } } /////////////////////////////////// // copying generated pulse into the base class SeqPulsNdim update_B10andPower(); float rel_magnetic_center=( (float)rampOn_npts + get_rel_center() * float(npts) ) / float(total_pts); set_rel_magnetic_center(rel_magnetic_center); SeqPulsNdim::set_rfwave(wv); SeqPulsNdim::set_pulsduration(total_pts*dt); ODINLOG(odinlog,normalDebug) << "total_pts=" << total_pts << STD_endl; ODINLOG(odinlog,normalDebug) << "dt=" << dt << STD_endl; ODINLOG(odinlog,normalDebug) << "pulsduration=" << total_pts*dt << STD_endl; for(i=0;i odinlog(this,"SeqPulsar::update_B10andPower"); OdinPulse::update_B10andPower(); float pow,argument; if(is_adiabatic()) { argument=secureInv(get_Tp_1pulse()); } else { argument=secureInv(get_Tp_1pulse())*get_flipangle()/90.0; } if (argument==0.0) pow=_MAX_PULSE_ATTENUATION_; else pow=-20.*log10(argument)+get_pulse_gain()+systemInfo->get_reference_gain(); if(!attenuation_set) SeqPulsNdim::set_power(pow); float sysflip=get_flipangle()*get_flipangle_corr_factor(); float b10=OdinPulse::get_B10(); ODINLOG(odinlog,normalDebug) << "pow/sysflip/b10=" << pow << "/" << sysflip << "/" << b10 << STD_endl; SeqPulsNdim::set_system_flipangle(sysflip); SeqPulsNdim::set_B1max(b10); } SeqFreqChanInterface& SeqPulsar::set_nucleus(const STD_string& nucleus) { OdinPulse::set_nucleus(nucleus); SeqPulsNdim::set_nucleus(nucleus); SeqPulsar::update(); return *this; } int SeqPulsar::get_dims() const { int result=0; funcMode dimmode=get_dim_mode(); if(dimmode == zeroDeeMode) result=0; if(dimmode == oneDeeMode) result=1; if(dimmode == twoDeeMode) result=2; return result; } void SeqPulsar::register_pulse(SeqPulsar* pls) { Log odinlog("SeqPulsar","register_pulse"); ODINLOG(odinlog,normalDebug) << " " << pls->get_label() << STD_endl; active_pulsar_pulses->push_back(pls); } void SeqPulsar::unregister_pulse(SeqPulsar* pls) { Log odinlog("SeqPulsar","unregister_pulse"); ODINLOG(odinlog,normalDebug) << " " << pls->get_label() << STD_endl; active_pulsar_pulses->remove(pls); } void SeqPulsar::init_static() { active_pulsar_pulses.init("active_pulsar_pulses"); } void SeqPulsar::destroy_static() { active_pulsar_pulses.destroy(); } template class SingletonHandler; SingletonHandler SeqPulsar::active_pulsar_pulses; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; ///////////////////////////////////////////////////////////////////////////// SeqPulsarReph::SeqPulsarReph(const STD_string& object_label,const SeqPulsar& puls) : SeqGradChanParallel(object_label) { dim=puls.get_dims(); if(puls.reph_grad[readDirection]) gxpulse=*(puls.reph_grad[readDirection]); if(puls.reph_grad[phaseDirection]) gypulse=*(puls.reph_grad[phaseDirection]); if(puls.reph_grad[sliceDirection]) gzpulse=*(puls.reph_grad[sliceDirection]); build_seq(); } SeqPulsarReph::SeqPulsarReph(const SeqPulsarReph& spr): SeqGradChanParallel(spr) { dim=0; SeqPulsarReph::operator = (spr); } SeqPulsarReph::SeqPulsarReph(const STD_string& object_label) : SeqGradChanParallel(object_label) { dim=0; } SeqPulsarReph& SeqPulsarReph::operator = (const SeqPulsarReph& spr) { SeqGradChanParallel::operator = (spr); dim=spr.dim; gxpulse=spr.gxpulse; gypulse=spr.gypulse; gzpulse=spr.gzpulse; build_seq(); return *this; } SeqPulsarReph::~SeqPulsarReph() { } float SeqPulsarReph::get_onramp_duration() const {return gzpulse.get_onramp_duration();} float SeqPulsarReph::get_constgrad_duration() const {return gzpulse.get_constgrad_duration();} float SeqPulsarReph::get_offramp_duration() const {return gzpulse.get_offramp_duration();} void SeqPulsarReph::build_seq() { clear(); if(dim==3) (*this) += gxpulse / gypulse / gzpulse; if(dim==2) (*this) += gxpulse / gypulse; if(dim==1) (*this) += gzpulse; } ///////////////////////////////////////////////////////////////////////////// SeqPulsarSinc::SeqPulsarSinc(const STD_string& object_label, float slicethicknes, bool rephased, float duration, float flipangle, float resolution, unsigned int npoints) : SeqPulsar(object_label,rephased,false) { set_dim_mode(oneDeeMode); set_Tp(duration); resize(npoints); SeqPulsar::set_flipangle(flipangle); // do NOT call virtual function in constructor set_shape("Sinc("+ftos(slicethicknes)+")"); set_trajectory("Const(0.0,1.0)"); set_filter("Triangle"); set_spat_resolution(resolution); SeqPulsar::set_encoding_scheme(maxDistEncoding); // do NOT call virtual function in constructor refresh(); set_interactive(true); } SeqPulsarSinc::SeqPulsarSinc(const SeqPulsarSinc& sps) { SeqPulsarSinc::operator = (sps); } SeqPulsarSinc& SeqPulsarSinc::operator = (const SeqPulsarSinc& sps) { SeqPulsar::operator = (sps); refresh(); return *this; } ///////////////////////////////////////////////////////////////////////////// SeqPulsarGauss::SeqPulsarGauss(const STD_string& object_label, float slicethicknes, bool rephased, float duration, float flipangle, unsigned int npoints) : SeqPulsar(object_label, rephased, false) { set_dim_mode(oneDeeMode); set_Tp(duration); resize(npoints); SeqPulsar::set_flipangle(flipangle); // do NOT call virtual function in constructor set_shape("Const"); set_trajectory("Const(0.0,1.0)"); set_filter("Gauss"); set_spat_resolution(0.5*slicethicknes); SeqPulsar::set_encoding_scheme(maxDistEncoding); // do NOT call virtual function in constructor refresh(); set_interactive(true); } SeqPulsarGauss::SeqPulsarGauss(const SeqPulsarGauss& spg) { SeqPulsarGauss::operator = (spg); } SeqPulsarGauss& SeqPulsarGauss::operator = (const SeqPulsarGauss& spg) { SeqPulsar::operator = (spg); refresh(); return *this; } ///////////////////////////////////////////////////////////////////////////// SeqPulsarBP::SeqPulsarBP(const STD_string& object_label, float duration, float flipangle, const STD_string& nucleus) : SeqPulsar(object_label, false, false) { set_dim_mode(zeroDeeMode); SeqPulsar::set_nucleus(nucleus); // do NOT call virtual function in constructor set_Tp(duration); unsigned int npoints=32; resize(npoints); SeqPulsar::set_flipangle(flipangle); // do NOT call virtual function in constructor set_shape("Const"); set_trajectory("Const(0.0,1.0)"); set_filter("NoFilter"); refresh(); set_interactive(true); } SeqPulsarBP::SeqPulsarBP(const SeqPulsarBP& spb) { SeqPulsarBP::operator = (spb); } SeqPulsarBP& SeqPulsarBP::operator = (const SeqPulsarBP& spb) { SeqPulsar::operator = (spb); refresh(); return *this; } odin-1.8.5/odinseq/seqgradtrapez.h0000644000175000017500000003275511455553540014111 00000000000000/*************************************************************************** seqgradtrapez.h - description ------------------- begin : Tue Apr 27 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADTRAPEZ_H #define SEQGRADTRAPEZ_H #include #include #include #include //////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of trapezoidal gradient pulses */ class SeqGradTrapezDriver : public SeqDriverBase { public: SeqGradTrapezDriver() {} virtual ~SeqGradTrapezDriver() {} /** * Update the driver with the following properties: * - channel: The channel (direction) of the trapez * - onrampdur: Duration of the on-ramp * - constdur: Duration of the flat top * - offrampdur: Duration of the off-ramp * - strength: Max gradient strength * - timestep: Dwell time (gradient raster) of the ramps * - type: The shape for the ramps * - exclude_offramp_from_timing: Exclude the off-ramp from timing calculations */ virtual bool update_driver(direction channel, double onrampdur, double constdur, double offrampdur, float strength, double timestep, rampType type, bool exclude_offramp_from_timing) = 0; virtual float get_onramp_integral (double tmin, double tmax) const = 0; virtual float get_offramp_integral(double tmin, double tmax) const = 0; virtual const fvector& get_onramp() const = 0; virtual const fvector& get_offramp() const = 0; virtual SeqGradChanList get_driverchanlist() = 0; virtual bool check_ramptype(rampType type) const = 0; virtual SeqGradTrapezDriver* clone_driver() const = 0; }; //////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The Default driver for trapezoidal gradient pulses */ class SeqGradTrapezDefault : public SeqGradTrapezDriver, public SeqGradChan { public: SeqGradTrapezDefault(); SeqGradTrapezDefault(const SeqGradTrapezDefault& sgtd); ~SeqGradTrapezDefault() {} // overloading virtual functions from SeqGradTrapezDriver bool update_driver(direction channel, double onrampdur, double constdur, double offrampdur, float strength, double timestep, rampType type, bool exclude_offramp_from_timing); float get_onramp_integral (double tmin, double tmax) const {return onramp_cache. get_integral(tmin,tmax);} float get_offramp_integral(double tmin, double tmax) const {return offramp_cache.get_integral(tmin,tmax);} const fvector& get_onramp() const {return onramp_cache.get_wave();} const fvector& get_offramp() const {return offramp_cache.get_wave();} SeqGradChanList get_driverchanlist(); bool check_ramptype(rampType type) const {return true;} SeqGradTrapezDriver* clone_driver() const {return new SeqGradTrapezDefault(*this);} // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} private: // overwriting virtual functions from SeqClass bool prep(); // overloading virtual function from SeqTreeObj STD_string get_properties() const; // overloading virtual functions from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const {return onramp_cache.get_strength();} double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); // overloading virtual functions from SeqGradChan STD_string get_grdpart(float matrixfactor) const {return graddriver->get_trapez_program(get_strength(),matrixfactor);} SeqGradChan& get_subchan(double starttime, double endtime) const; direction get_channel() const {return onramp_cache.get_channel();} float get_integral() const; SeqGradRamp onramp_cache; SeqGradRamp offramp_cache; double const_dur; bool exclude_offramp; }; //////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Trapezoidal gradient * * This class represents a gradient pulse with a trapezoidal shape, i.e. * a piecewise constant gradient with ramps */ class SeqGradTrapez : public SeqGradChanList { public: /** * Constructs a gradient pulse labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradstrength: The maximum gradient strength for this object * - constgradduration: The duration of the constant part of the gradient pulse * - timestep: The time resolution for the ramps * - type: The shape for the ramps * - minrampduration: The minimum duration for the ramps * - steepness: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible */ SeqGradTrapez(const STD_string& object_label,direction gradchannel, float gradstrength, double constgradduration, double timestep=0.01, rampType type = linear, double minrampduration=0.0, float steepness=1.0); /** * Constructs a gradient pulse labeled 'object_label' with the following properties: * - gradintegral: The overall integral for the gradient pulse * - gradchannel: The channel this object should be played out * - constgradduration: The duration of the constant part of the gradient pulse * - timestep: The time resolution for the ramps * - rampType: The shape for the ramps * - minrampduration: The minimum duration for the ramps * - steepness: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible */ SeqGradTrapez(const STD_string& object_label,float gradintegral, direction gradchannel, double constgradduration, double timestep=0.01, rampType type = linear, double minrampduration=0.0, float steepness=1.0); /** * Constructs a gradient pulse labeled 'object_label' with the following properties: * - gradintegral: The overall integral for the gradient pulse * - gradstrength: The strength of the constant part of the gradient pulse * - gradchannel: The channel this object should be played out * - timestep: The time resolution for the ramps * - rampType: The shape for the ramps * - minrampduration: The minimum duration for the ramps * - steepness: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible */ SeqGradTrapez(const STD_string& object_label,float gradintegral, float gradstrength, direction gradchannel, double timestep=0.01, rampType type = linear, double minrampduration=0.0, float steepness=1.0); /** * Constructs a copy of 'sgt' */ SeqGradTrapez(const SeqGradTrapez& sgt); /** * Construct an empty gradient pulse with the given label */ SeqGradTrapez(const STD_string& object_label = "unnamedSeqGradTrapez"); /** * Assignment operator that makes this gradient pulse become a copy of 'sgt' */ SeqGradTrapez& operator = (const SeqGradTrapez& sgt); /** * Sets the duration of the constant part of the gradient pulse */ SeqGradTrapez& set_constgrad_duration(double duration); /** * Returns the duration of the ramp that switches the gradient pulse on */ double get_onramp_duration() const {return onrampdur;} /** * Returns the duration of the constant part of the gradient pulse */ double get_constgrad_duration() const {return constdur;} /** * Returns the duration of the ramp that switches the gradient pulse off */ double get_offramp_duration() const {return offrampdur;} /** * Returns the integral of the ramp that switches the gradient pulse on from tmin to tmax */ float get_onramp_integral(double tmin, double tmax) const {return trapezdriver->get_onramp_integral(tmin,tmax);} /** * Returns the integral of the ramp that switches the gradient pulse on */ float get_onramp_integral() const {return get_onramp_integral(0.0,get_onramp_duration());} /** * Returns the integral of the constant part */ float get_constgrad_integral() const {return constdur*trapezstrength;} /** * Returns the integral of the ramp that switches the gradient pulse off from tmin to tmax */ float get_offramp_integral(double tmin, double tmax) const {return trapezdriver->get_offramp_integral(tmin,tmax);} /** * Returns the integral of the ramp that switches the gradient pulse off */ float get_offramp_integral() const {return get_offramp_integral(0.0,get_offramp_duration());} /** * Sets the overall integral of the gradient pulse */ SeqGradTrapez& set_integral(float gradintegral); /** * Returns the overall integral of the gradient pulse */ float get_integral() const; /** * Returns the number of digitised points of the ramp that switches the gradient pulse on */ unsigned int get_onramp_npts() const; /** * Returns the number of digitised points during the constant part */ unsigned int get_const_npts() const; /** * Returns the number of digitised points of the ramp that switches the gradient pulse off */ unsigned int get_offramp_npts() const; /** * Returns the total number of digitised points */ unsigned int get_npts() const; /** * Returns the waveform of the ramp that switches the gradient pulse on */ fvector get_onramp() const {return trapezdriver->get_onramp();} /** * Returns the waveform of the ramp that switches the gradient pulse on */ fvector get_offramp() const {return trapezdriver->get_offramp();} /** * Returns a waveform which is a digitised version of the whole trapezoid */ fvector get_trapezshape() const; /** * Returns the time resolution for the ramps */ double get_timestep() const {return dt;} /** * Returns the shape type of the ramps */ rampType get_ramptype() const {return rampMode;} /** * Spefifies whether to exclude the off-ramp from timing calculations */ SeqGradTrapez& exclude_offramp_from_timing(bool flag); // overloading virtual function from SeqGradInterface float get_strength() const {return trapezstrength;} double get_gradduration() const {return get_onramp_duration()+get_constgrad_duration()+get_offramp_duration();} // override result of SeqGradChanList which may differ due to concatenating other SeqGradChans private: void common_init(); void check_platform(); void update_driver(); void build_seq(); static void get_ramps(const STD_string& label, float& rampintegral, double& rampondur, double& rampoffdur, float strength, double dwelltime, rampType ramptype, float steepness, double mindur); mutable SeqDriverInterface trapezdriver; rampType rampMode; double dt; float steepnessfactor; bool exclude_offramp_timing; direction trapezchannel; double onrampdur; double constdur; double offrampdur; float trapezstrength; }; //////////////////////////////////////////////////////////////////// /** * \brief 3 simultaneous trapezoids * * A class to place 3 synchronous gradient pulses with * trapezoidal shape on all 3 axes simultaneously. */ class SeqGradTrapezParallel : public SeqGradChanParallel { public: /** * Constructs a gradient pulse labeled 'object_label' with the following properties: * - gradintegral_read: The desired gradient integral on the read channel * - gradintegral_phase: The desired gradient integral on the phase channel * - gradintegral_slice: The desired gradient integral on the slice channel * - maxgradstrength: The maximum gradient strength * - timestep: The time resolution for the ramps * - rampType: The shape for the ramps * - minrampduration: The minimum duration for the ramps */ SeqGradTrapezParallel(const STD_string& object_label, float gradintegral_read, float gradintegral_phase, float gradintegral_slice, float maxgradstrength, double timestep=0.01, rampType type = linear, double minrampduration=0.0); /** * Constructs a copy of 'sgtp' */ SeqGradTrapezParallel(const SeqGradTrapezParallel& sgtp); /** * Construct an empty gradient pulse with the given label */ SeqGradTrapezParallel(const STD_string& object_label = "unnamedSeqGradTrapezParallel"); /** * Assignment operator that makes this gradient pulse become a copy of 'sgtp' */ SeqGradTrapezParallel& operator = (const SeqGradTrapezParallel& sgtp); private: void build_seq(); SeqGradTrapez readgrad; SeqGradTrapez phasegrad; SeqGradTrapez slicegrad; }; /** @} */ #endif odin-1.8.5/odinseq/seqacqspiral.h0000644000175000017500000001017211322062345013701 00000000000000/*************************************************************************** seqacqspiral.h - description ------------------- begin : Tue Nov 11 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQSPIRAL_H #define SEQACQSPIRAL_H #include #include #include #include #include #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Acquisition + spiral gradient * * This class contains a gradient with a spiral k-space trajectory together with an acquisition window */ class SeqAcqSpiral : public virtual SeqAcqInterface, public SeqObjList { // virtual functions of SeqFreqChanInterface are marhshalled to acq public: /** * Constructs an acquisition window with a simultaneous spiral gradient labeled 'object_label' and the * following properties: * - sweepwidth: The sampling frequency * - fov: The Field of View in radial direction * - sizeRadial: The number of image points in radial direction * - numofSegments : The number of spiral interleaves * - traj: The spiral trajectory (will be modified, if neccessary) * - inout: Spiral-in spiral-out trajectory * - optimize: Optimize trajectory for minimum readout length if trajectory has a free tunable parameter * - nucleus: See class 'SeqAcq' for explanation * - phaselist: See class 'SeqAcq' for explanation */ SeqAcqSpiral(const STD_string& object_label,double sweepwidth, float fov, unsigned int sizeRadial, unsigned int numofSegments, JDXtrajectory& traj, bool inout=false, bool optimize=false, const STD_string& nucleus="",const dvector& phaselist=0); /** * Constructs an acquisition window with spiral gradient which is a copy of 'sas' */ SeqAcqSpiral(const SeqAcqSpiral& sas); /** * Constructs an empty acquisition window with spiral gradient with the given label. */ SeqAcqSpiral(const STD_string& object_label="unnamedSeqAcqSpiral"); /** * This assignment operator will make this object become an exact copy of 'sar'. */ SeqAcqSpiral& operator = (const SeqAcqSpiral& sas); /** * Returns the vector of the spiral interleaves (for loop insertion) */ const SeqVector& get_segment_vector() const {return rotvec;} /** * Returns the k-space trajectory for the interleave 'iseg' */ fvector get_ktraj(unsigned int iseg, direction channel) const; /** * Returns the Jacobian determinante, i.e. the correction function * for non-uniform weighting of k-space */ fvector get_denscomp() const; // marshalling virtual functions of SeqAcqInterface to acq, except: double get_acquisition_center() const {return preacq.get_duration()+acq.get_acquisition_center();} double get_acquisition_start() const {return preacq.get_duration()+acq.get_acquisition_start();} SeqAcqInterface& set_sweepwidth(double sw, float os_factor); // produce warning private: // overwriting virtual functions from SeqClass bool prep(); void common_init(); void build_seq(); SeqParallel par; SeqGradSpiral spirgrad_in; SeqGradSpiral spirgrad_out; SeqDelay preacq; SeqAcq acq; SeqGradTrapezParallel gbalance; SeqRotMatrixVector rotvec; bool inout_traj; }; /** @} */ #endif odin-1.8.5/odinseq/seqphase.cpp0000644000175000017500000000404111322062345013353 00000000000000#include "seqphase.h" #include "seqfreq.h" /////////////////////////////////////////////////////////////////// SeqPhaseListVector::SeqPhaseListVector(const STD_string& object_label, const dvector& phase_list) : phasedriver(object_label) { set_label(object_label); set_phaselist(phase_list); } SeqPhaseListVector::SeqPhaseListVector(const SeqPhaseListVector& spl) : phasedriver(spl.get_label()) { SeqPhaseListVector::operator = (spl); } SeqPhaseListVector& SeqPhaseListVector::operator = (const SeqPhaseListVector& spl) { // do NOT copy user because it is set by SeqFreqChan and remains the same over the whole lifetime phasedriver=spl.phasedriver; phaselist=spl.phaselist; return *this; }; bool SeqPhaseListVector::prep() { if(!SeqClass::prep()) return false; phasedriver->prep_driver(phaselist); return true; } bool SeqPhaseListVector::prep_iteration() const { Log odinlog(this,"prep_iteration"); ODINLOG(odinlog,normalDebug) << "user=" << user->get_label() << STD_endl; return user->prep_iteration(); } SeqPhaseListVector& SeqPhaseListVector::set_phaselist(const dvector& pl) { Log odinlog(this,"set_phaselist"); phaselist=pl; // Limit to range 0-360, just as a precaution for flaky drivers for(unsigned int i=0; i #include #include #include #include #include #include #include #include #include #include #include #include /** * @addtogroup odinseq_internals * @{ */ /////////////////////////////////////////////////////////////////////////// // For debugging the Seq component class Seq { public: static const char* get_compName(); }; /////////////////////////////////////////////////////////////////////////// class SeqVector; //forward declaration /** * This is the base class for all Seq* classes. It provides * functions that are common to all classes of the sequence library, * e.g. functions for error/debug message handling and acces to * proxies, i.e. geometryInfo, studyInfo and systemInfo. */ class SeqClass : public virtual Labeled, public StaticHandler { public: /** * Mark object as temporary so that it will be deleted automatically */ SeqClass& set_temporary(); System& get_systemInfo() {return *systemInfo;} // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); protected: // prevent direct construction/assignment/destruction of this class SeqClass(); virtual ~SeqClass(); SeqClass& operator = (const SeqClass& sc); /** * Writes a marshalling error, i.e. mashalling without appropriate sub-object, to the log */ void marshall_error() const; /** * Delete all temporary objects */ static void clear_temporary(); /** * Overload this function in case the class is a container object, i.e. * it contains other sequence objects. The function should clear all * references to other sequence objects, i.e. to thos it contains. */ virtual void clear_container() {} /** * Clear the contents of all container objects */ static void clear_containers(); /** * Overload this function to prepare objects before the measurement. This function * will then be called automatically after editing the sequence parameters and * before the measurement is started. This function should not alter the physical * properties of the sequence object, e.g. its duration. */ virtual bool prep() {prepped=true; return true;} // call prep() of all objects static bool prep_all(); // points to systemInfo of the currently active platform SystemInterface& systemInfo; // points to the geometry parameters static SingletonHandler geometryInfo; // points to the geometry parameters static SingletonHandler studyInfo; // points to the reco parameters static SingletonHandler recoInfo; static SeqVector& get_dummyvec(); private: friend class SeqOperator; friend class SeqMethod; friend class SeqMethodProxy; friend class SystemInterface; friend class SeqPlatformProxy; // remove all references to other sequence objects static void clear_objlists(); bool prepped; // List to hold references to SeqClass objects struct SeqClassList : public STD_list, public Labeled {}; static SingletonHandler allseqobjs; static SingletonHandler tmpseqobjs; static SingletonHandler seqobjs2prep; static SingletonHandler seqobjs2clear; static SystemInterface* systemInfo_ptr; static SeqVector* dummyvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqobjvec.cpp0000644000175000017500000000650311322062345013530 00000000000000#include "seqobjvec.h" #include "seqgrad.h" #include "seqparallel.h" #include "seqgradchanlist.h" SeqObjVector::SeqObjVector(const STD_string& object_label) : SeqVector(object_label), SeqObjBase(object_label) { set_label(object_label); } SeqObjVector::SeqObjVector(const SeqObjVector& sov) { SeqObjVector::operator = (sov); } SeqObjVector& SeqObjVector::operator = (const SeqObjVector& sov) { SeqObjBase::operator = (sov); SeqVector::operator = (sov); clear(); for(constiter it=sov.get_const_begin();it!=sov.get_const_end();++it) { append(**it); } return *this; } SeqObjVector& SeqObjVector::operator += (const SeqObjBase& soa) { append(soa); return *this; } SeqObjVector& SeqObjVector::operator += (SeqGradObjInterface& sgoa) { SeqParallel* par=new SeqParallel(sgoa.get_label()); par->set_temporary(); par->set_gradptr(&sgoa); (*this)+=(*par); return *this; } SeqObjVector& SeqObjVector::operator += (SeqGradChanList& sgcl) { SeqParallel* par=new SeqParallel(sgcl.get_label()); par->set_temporary(); (*par) /= sgcl; (*this)+=(*par); return *this; } STD_string SeqObjVector::get_program(programContext& context) const { STD_string result; constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_program(context); return result; } double SeqObjVector::get_duration() const { double result=0.0; constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_duration(); return result; } unsigned int SeqObjVector::event(eventContext& context) const { unsigned int result=0; constiter it=get_current(); if(it!=get_const_end()) result+=(*it)->event(context); return result; } SeqValList SeqObjVector::get_freqvallist(freqlistAction action) const { SeqValList result; constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_freqvallist(action); return result; } SeqValList SeqObjVector::get_delayvallist() const { SeqValList result; constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_delayvallist(); return result; } double SeqObjVector::get_rf_energy() const { double result=0.0; constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_rf_energy(); return result; } void SeqObjVector::clear_container() { List::clear(); } void SeqObjVector::query(queryContext& context) const { SeqTreeObj::query(context); // defaults if(context.action==count_acqs) { constiter it=get_current(); if(it!=get_const_end()) (*it)->query(context); return; } for(constiter it=get_const_begin();it!=get_const_end();++it) { context.parentnode=this; // reset to this because it might changed by last query (*it)->query(context); } } RecoValList SeqObjVector::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { RecoValList result(get_label()); constiter it=get_current(); if(it!=get_const_end()) result=(*it)->get_recovallist(reptimes,coords); return result; } List::constiter SeqObjVector::get_current() const { unsigned int i=0; unsigned int index=get_current_index(); constiter result=get_const_end(); for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if(i==index) { result=it; return result; } i++; } return result; } odin-1.8.5/odinseq/seqdriver_idea.cpp0000644000175000017500000000174311322062345014536 00000000000000#ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #ifdef IDEA_PLUGIN #include "../platforms/IDEA_n4/odinseq_idea/seqidea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqacq_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqacqepi_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqcounter_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqdec_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqdelay_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqfreq_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqgradchan_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqgradtrapez_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqlist_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqparallel_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqphase_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqpuls_idea.cpp" #include "../platforms/IDEA_n4/odinseq_idea/seqtrigg_idea.cpp" #endif odin-1.8.5/odinseq/seqblsiegprep.h0000755000175000017500000000506711625224370014074 00000000000000/* Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifndef SEQBLSIEGPREP_H #define SEQBLSIEGPREP_H #include /** * @addtogroup odinseq * @{ */ /** * \brief Bloch-Siegert preparation module for B1-mapping * * Preparation module for B1 mapping according to * Sacolick et al. MRM(65)2010: 1315-1322): * Fermi-shaped pulse which is applied off-resonance to produce a * B0-shift depending on the Fermi-shaped pulse's B1 distribution */ class SeqBlSiegPrep : public SeqPulsar { public: /** * Constructs a Fermi-shaped pulse with the following properties: * - duration [ms] * - angle [degree] * - offset [Hz] * - width: fractional distance of the turning points of the fermipulse * - slope: steepnes of the ramp of the fermipulse */ SeqBlSiegPrep ( const STD_string& object_label = "unnamedSeqBlSiegPrep", float duration = 8, float angle = 1000, float offset = 4000, float width = 0.8, float slope = 130 ); /** * constructs a copy of "sbsp" */ SeqBlSiegPrep ( const SeqBlSiegPrep& sbsp ); /** * copies "sbsp" */ SeqBlSiegPrep& operator = ( const SeqBlSiegPrep& sbsp ); /** * destructor */ ~SeqBlSiegPrep() {} /** * prepares the Fermi-shaped rf-pulse -> ready for use */ bool prep(); JcampDxBlock pars; JcampDxBlock info; JDXdouble duration; JDXdouble angle; JDXdouble offset; JDXdouble width; JDXdouble slope; JDXdouble weighting; JDXdouble amplitude; private: }; /** @} */ #endif // SEQBLSIEGPREP_H odin-1.8.5/odinseq/seqacqepi.cpp0000644000175000017500000007336611625224370013541 00000000000000#include "seqacqepi.h" #include "seqgradchanparallel.h" #include "seqgradvec.h" #include "seqveciter.h" SeqEpiDriverDefault::SeqEpiDriverDefault() { SeqAcqInterface::set_marshall(&adc); SeqFreqChanInterface::set_marshall(&adc); templtype=no_template; } SeqEpiDriverDefault::SeqEpiDriverDefault(const SeqEpiDriverDefault& sedi) : SeqEpiDriver(sedi) { SeqAcqInterface::set_marshall(&adc); SeqFreqChanInterface::set_marshall(&adc); adc=sedi.adc; acqdelay_begin=sedi.acqdelay_begin; acqdelay_middle=sedi.acqdelay_middle; acqdelay_end=sedi.acqdelay_end; posread=sedi.posread; negread=sedi.negread; phaseblip1st=sedi.phaseblip1st; phaseblip2nd=sedi.phaseblip2nd; phasezero1st=sedi.phasezero1st; phasezero2nd=sedi.phasezero2nd; phasezero_lastblip=sedi.phasezero_lastblip; gradkernel=sedi.gradkernel; lastgradkernel=sedi.lastgradkernel; oneadckernel=sedi.oneadckernel; adckernel=sedi.adckernel; lastadckernel=sedi.lastadckernel; kernel=sedi.kernel; lastkernel=sedi.lastkernel; loop=sedi.loop; gradint2center_read=sedi.gradint2center_read; gradint2center_phase=sedi.gradint2center_phase; centerindex_phase=sedi.centerindex_phase; readshape=sedi.readshape; templtype=sedi.templtype; echopairs=sedi.echopairs; lastecho=sedi.lastecho; build_seq(); } void SeqEpiDriverDefault::init_driver(const STD_string& object_label,double sweepwidth, float kread_min, float kread_max, unsigned readntps, float kphase_min, float kphase_max, unsigned phasentps,int startindex_phase, bool ramp_sampling,rampType rampmode, float ramp_steepness, const STD_string& nucleus, const dvector& phaselist, const dvector& freqlist, unsigned int echo_pairs) { set_label(object_label); Log odinlog(this,"init_driver"); echopairs=echo_pairs; double read_integral=kread_max-kread_min; double readgraddur=secureDivision(double(readntps),sweepwidth); float readstrength=secureDivision(read_integral,readgraddur); // double rastertime=systemInfo->get_rastertime(gradObj); // if(rastertime>0.0) { // int nraster=(int)secureDivision(readgraddur,rastertime); // if(rastertime*nraster!=readgraddur) nraster++; // always increase length of constant part // readgraddur=nraster*rastertime; // } ODINLOG(odinlog,normalDebug) << "readntps/sweepwidth=" << readntps << "/" << sweepwidth << STD_endl; ODINLOG(odinlog,normalDebug) << "kread_max/kread_min=" << kread_max << "/" << kread_min << STD_endl; ODINLOG(odinlog,normalDebug) << "readgraddur/readstrength=" << readgraddur << "/" << readstrength << STD_endl; adc.set_sweepwidth(sweepwidth,1.0); // To obtain correct pre/post delays double adcpredelay=get_acquisition_start(); double adcpostdelay=adc.get_duration()-adc.get_acquisition_duration()-adcpredelay; double minadcdelay=STD_max(adcpredelay,adcpostdelay); // The min delay at either sides of the ADC kernel, i.e. prior to posread ADC and after negread ODINLOG(odinlog,normalDebug) << "adcpredelay/adcpostdelay/minadcdelay=" << adcpredelay << "/" << adcpostdelay << "/" << minadcdelay << STD_endl; double rastime=systemInfo->get_rastertime(gradObj); // Sampling rate for ramps posread=SeqGradTrapez(object_label+"_posread",readDirection, readstrength,readgraddur,rastime,rampmode,minadcdelay,ramp_steepness); negread=SeqGradTrapez(object_label+"_negread",readDirection,-readstrength,readgraddur,rastime,rampmode,minadcdelay,ramp_steepness); ODINLOG(odinlog,normalDebug) << "posread/negread.get_duration()=" << posread.get_duration() << "/" << negread.get_duration() << STD_endl; double rampondur= posread.get_onramp_duration(); double rampoffdur=posread.get_offramp_duration(); double rampdur=0.5*(rampondur+rampoffdur); ODINLOG(odinlog,normalDebug) << "rampondur/rampoffdur/rampdur=" << rampondur << "/" << rampoffdur << "/" << rampdur << STD_endl; // defaults for non-ramp-sampling double adc2adc_duration=2.0*rampdur; // Duration from the end of acquisition of one ADC to the acquisition start of the next unsigned int nAcqPoints=readntps; float addint4deph=posread.get_onramp_integral(); // Extra dephaser for ramps unsigned int ramp_npoints=0; float rel_gradstartval=1.0; ODINLOG(odinlog,normalDebug) << "ramp_sampling=" << ramp_sampling << STD_endl; if(ramp_sampling) { // Shorten constant part of read gradient according to available ramp integral double onrampintegral_acq=posread.get_onramp_integral(minadcdelay,rampondur); double offrampintegral_acq=posread.get_offramp_integral(0.0,rampoffdur-minadcdelay); double rampintegral_acq=onrampintegral_acq+offrampintegral_acq; ODINLOG(odinlog,normalDebug) << "onrampintegral_acq/offrampintegral_acq/rampintegral_acq=" << onrampintegral_acq << "/" << offrampintegral_acq << "/" << rampintegral_acq << STD_endl; // calculate the shortening of the readout gradient as multiples of the dwell time double subtract_duration=secureDivision(rampintegral_acq, readstrength); unsigned int subtract_npoints=(unsigned int)(subtract_duration*sweepwidth+0.5); double subtract_duration_grid=secureDivision(subtract_npoints,sweepwidth); ODINLOG(odinlog,normalDebug) << "subtract_duration/subtract_npoints/subtract_duration_grid=" << subtract_duration << "/" << subtract_npoints << "/" << subtract_duration_grid << STD_endl; double newconstdur=posread.get_constgrad_duration()-subtract_duration_grid; ODINLOG(odinlog,normalDebug) << "newconstdur=" << newconstdur << STD_endl; posread.set_constgrad_duration(newconstdur); negread.set_constgrad_duration(newconstdur); ODINLOG(odinlog,normalDebug) << "posread/negread.get_duration()=" << posread.get_duration() << "/" << negread.get_duration() << STD_endl; // Number of extra points we can stuff into the ramps double effective_rampdur=rampdur-minadcdelay; ramp_npoints=(unsigned int)(effective_rampdur*sweepwidth); // round down so that the duration of the ADC kernel will not exceed the duration of the gradient kernel ODINLOG(odinlog,normalDebug) << "effective_rampdur/ramp_npoints=" << effective_rampdur << "/" << ramp_npoints << STD_endl; // New number of samples in ADC nAcqPoints=nAcqPoints-subtract_npoints+2*ramp_npoints; // Shortest possible delay between ADCs adc2adc_duration=2.0*minadcdelay; ODINLOG(odinlog,normalDebug) << "adc2adc_duration(rampsampling)=" << adc2adc_duration << STD_endl; // The relative gradient strength the ramp starts with rel_gradstartval=secureDivision(minadcdelay,rampdur); ODINLOG(odinlog,normalDebug) << "rel_gradstartval=" << rel_gradstartval << STD_endl; // Additional dephasing integral to account for the part of the ramp without sampling addint4deph=0.5*minadcdelay*readstrength*rel_gradstartval; } adc=SeqAcq(object_label+"_adc",nAcqPoints,sweepwidth,1.0,nucleus,phaselist,freqlist); ODINLOG(odinlog,normalDebug) << "adc.get_duration()=" << adc.get_duration() << STD_endl; // Construct readout shape for reco readshape.resize(nAcqPoints); readshape=1.0; unsigned int i; for(i=0; iget_grad_shift_delay(); if(fabs(sysgradshift)>max_possible_shift) { ODINLOG(odinlog,warningLog) << "sysgradshift=" << sysgradshift << " exceeds max_possible_shift=" << max_possible_shift << STD_endl; if(sysgradshift<0.0) sysgradshift=-max_possible_shift; else sysgradshift= max_possible_shift; } double acqdelay_shifted_begin=begin_delaydur+sysgradshift; double acqdelay_shifted_end =end_delaydur -sysgradshift; acqdelay_begin=SeqDelay(object_label+"_acqdelay_begin",acqdelay_shifted_begin); acqdelay_end=SeqDelay(object_label+"_acqdelay_end",acqdelay_shifted_end); acqdelay_middle=SeqDelay(object_label+"_acqdelay_middle",middle_acqdelay); float blipint=secureDivision(kphase_max-kphase_min,float(phasentps)); if(phasentps<=1) blipint=0.0; // We do not need blips in this case ODINLOG(odinlog,normalDebug) << "blipint=" << blipint << STD_endl; centerindex_phase=int(secureDivision(-kphase_min,kphase_max-kphase_min)*float(phasentps)); if(echopairs>0) centerindex_phase*=(2*echopairs); // The actual phase encoding blips phaseblip1st=SeqGradTrapez(object_label+"_phaseblip1st",blipint,phaseDirection,0.0,rastime,rampmode,rampdur); phaseblip2nd=SeqGradTrapez(object_label+"_phaseblip2nd",blipint,phaseDirection,0.0,rastime,rampmode,rampdur); if(phaseblip1st.get_gradduration()!=2.0*rampdur) { ODINLOG(odinlog,warningLog) << "Timing mismatch: phaseblip1st(" << phaseblip1st.get_gradduration() << ") != 2.0*rampdur(" << 2.0*rampdur << ")" << STD_endl; } phaseblip2nd.exclude_offramp_from_timing(true); if(phaseblip2nd.get_gradduration()!=2.0*rampdur) { ODINLOG(odinlog,warningLog) << "Timing mismatch: phaseblip2nd(" << phaseblip2nd.get_gradduration() << ") != 2.0*rampdur(" << 2.0*rampdur << ")" << STD_endl; } // The padding delays double phasezerodur1=posread.get_constgrad_duration()+phaseblip2nd.get_offramp_duration(); double phasezerodur2=posread.get_constgrad_duration(); double phasezerodur_lastblip=posread.get_gradduration()+negread.get_onramp_duration()+negread.get_constgrad_duration(); phasezero1st=SeqGradDelay(object_label+"_phasezero1st",phaseDirection,phasezerodur1); phasezero2nd=SeqGradDelay(object_label+"_phasezero2nd",phaseDirection,phasezerodur2); phasezero_lastblip=SeqGradDelay(object_label+"_phasezero_lastblip",phaseDirection,phasezerodur_lastblip); lastecho=bool(phasentps%2); int n_kernels=phasentps/2; ODINLOG(odinlog,normalDebug) << "n_kernels/startindex_phase/phasentps/lastecho=" << n_kernels << "/" << startindex_phase << "/" << phasentps << "/" << lastecho << STD_endl; gradkernel.set_label(object_label+"_gradkernel"); lastgradkernel.set_label(object_label+"_lastgradkernel"); oneadckernel.set_label(object_label+"_oneadckernel"); adckernel.set_label(object_label+"_adckernel"); lastadckernel.set_label(object_label+"_lastadckernel"); kernel.set_label(object_label+"_kernel"); lastkernel.set_label(object_label+"_lastkernel"); loop.set_label(object_label+"_loop"); loop.set_times(n_kernels); build_seq(); } unsigned int SeqEpiDriverDefault::get_numof_gradechoes() const { Log odinlog(this,"get_numof_gradechoes"); unsigned int looptimes=loop.get_times(); unsigned int result=2*looptimes+int(lastecho); if(echopairs>0) result*=2*echopairs; ODINLOG(odinlog,normalDebug) << "looptimes/lastecho/echopairs/result=" << looptimes << "/" << lastecho << "/" << echopairs << "/" << result << STD_endl; return result; } SeqAcqInterface& SeqEpiDriverDefault::set_template_type(templateType type) { templtype=type; adc.set_template_type(type); if(type==phasecorr_template) { phaseblip1st.set_strength(0.0); phaseblip2nd.set_strength(0.0); gradint2center_phase=0.0; } build_seq(); return *this; } fvector SeqEpiDriverDefault::get_gradintegral() const { fvector result(3); result=0; result += loop.get_times()*kernel.get_gradintegral(); if(lastecho) result += lastkernel.get_gradintegral(); return result; } double SeqEpiDriverDefault::get_acquisition_center() const { return (double(centerindex_phase)+0.5)*posread.get_gradduration(); } double SeqEpiDriverDefault::get_acquisition_start() const { return adc.get_acquisition_start(); } void SeqEpiDriverDefault::build_seq() { Log odinlog(this,"build_seq"); gradkernel.clear(); lastgradkernel.clear(); oneadckernel.clear(); adckernel.clear(); lastadckernel.clear(); lastkernel.clear(); oneadckernel = acqdelay_begin + adc + acqdelay_middle + adc + acqdelay_end; ODINLOG(odinlog,normalDebug) << "echopairs=" << echopairs << STD_endl; if(echopairs>0) { int nkernels=2*echopairs; for(int i=0; iphase_size) segments_cache=1; reduction_cache=reduction; if(!reduction_cache || reduction_cache>phase_size) reduction_cache=1; unsigned int phase_increment=segments_cache*reduction_cache; phasesize_cache=(unsigned int)(phase_size/phase_increment)*phase_increment; // phase_size must be multiple of (segments * reduction factor) echo_pairs_cache=echo_pairs; float gamma=systemInfo->get_gamma(nucleus); float resread=secureDivision( FOVread , read_size ); float resphase=secureDivision( FOVphase , phasesize_cache ); float k_indep_read=secureDivision( 2.0*PII , gamma * resread ); float k_indep_phase=secureDivision( 2.0*PII , gamma * resphase ); float k_indep_read_min=-0.5*k_indep_read; float k_indep_read_max=0.5*k_indep_read; float kspace_part=1.0-fourier_factor; if(kspace_part<0.0) kspace_part=0.0; if(kspace_part>1.0) kspace_part=1.0; float k_indep_phase_min; float k_indep_phase_max; if (invert_partial_fourier) { k_indep_phase_min=-0.5*k_indep_phase; k_indep_phase_max=0.5*kspace_part*k_indep_phase; } else { k_indep_phase_min=-0.5*kspace_part*k_indep_phase; k_indep_phase_max=0.5*k_indep_phase; } int phasenpts=(unsigned int)(float(phasesize_cache)*(0.5*kspace_part+0.5)); int startindex_phase=phasesize_cache-phasenpts; // Achieve segmentation/GRAPPA while keeping FOV unsigned int driver_phasenpts=int(secureDivision(phasenpts,phase_increment)+0.5); unsigned int driver_startindex=int(secureDivision(startindex_phase,phase_increment)+0.5); blipint_cache=secureDivision(k_indep_phase_max-k_indep_phase_min, driver_phasenpts); // remember blip integral for dephasing segmented EPI ODINLOG(odinlog,normalDebug) << "phase_increment/driver_phasenpts/driver_startindex=" << phase_increment << "/" << driver_phasenpts << "/" << driver_startindex << STD_endl; for(int itry=0; itry<10; itry++) { // several attempts possible to get a valid setup, but avois infinite loop // Use ADC of driver to adjust sweepwidth and use it in init_driver() // do this here so we do not have to do it separately in each driver // Thereby, add overampling at this point driver->set_sweepwidth(os_factor*sweepwidth,1.0); ODINLOG(odinlog,normalDebug) << "sweepwidth/os_factor/driver->get_sweepwidth()=" << sweepwidth << "/" << os_factor << "/" << driver->get_sweepwidth() << STD_endl; // Initialize driver for only one segment (and/or GRAPPA interleave), different segments will be encoded by dephasing gradient driver->init_driver(object_label,driver->get_sweepwidth(), k_indep_read_min, k_indep_read_max,readsize_os_cache, k_indep_phase_min, k_indep_phase_max, driver_phasenpts, driver_startindex, ramp_sampling,rampmode,ramp_steepness, nucleus,phaselist,freqlist,echo_pairs); double gradfreq=secureInv(2.0*driver->get_echoduration()); double low,upp; if(systemInfo->allowed_grad_freq(gradfreq, low, upp)) { break; } else { double downscale=STD_max(0.5,1.0-secureDivision(2.0*fabs(upp-low),gradfreq)); sweepwidth*=downscale; ODINLOG(odinlog,warningLog) << "Gradient switching frequency (" << gradfreq << ODIN_FREQ_UNIT << ") not allowed, scaling sweepwidth down (factor=" << downscale << ") to " << sweepwidth << ODIN_FREQ_UNIT << STD_endl; } } // Initialize dephasers/rephasers so that consecutive calls to get_dephgrad do not have to alter them create_deph_and_reph(); } void SeqAcqEPI::create_deph_and_reph() { Log odinlog(this,"create_deph_and_reph"); float centint_read= driver->get_gradintegral2center_read(); float centint_phase=driver->get_gradintegral2center_phase(); fvector gradint_driver=driver->get_gradintegral(); ODINLOG(odinlog,normalDebug) << "centint_read/centint_phase/gradint_driver=" << centint_read << "/" << centint_phase << "/" << gradint_driver.printbody() << STD_endl; float integral_deph_read =-centint_read; float integral_deph_phase =-centint_phase; float integral_reph_read= -(gradint_driver[readDirection]- centint_read); float integral_reph_phase=-(gradint_driver[phaseDirection]-centint_phase); float maxintegral=STD_max( STD_max(fabs(integral_deph_read),fabs(integral_deph_phase)), STD_max(fabs(integral_reph_read),fabs(integral_reph_phase)) ); float dephdur=secureDivision(maxintegral,fabs(driver->get_strength())); ODINLOG(odinlog,normalDebug) << "integral_deph_read/integral_deph_phase/maxintegral/dephdur=" << integral_deph_read << "/" << integral_deph_phase << "/" << maxintegral << "/" << dephdur << STD_endl; float rampdt=driver->get_ramp_rastertime(); STD_string object_label(get_label()); // Initialize objects with the same integral to obtain synchronous switch points dephobjs->readdephgrad= SeqGradTrapez(object_label+"_readdephgrad", maxintegral,readDirection, dephdur,rampdt,ramptype_cache); dephobjs->readrephgrad= SeqGradTrapez(object_label+"_readrephgrad", maxintegral,readDirection, dephdur,rampdt,ramptype_cache); dephobjs->phasedephgrad=SeqGradTrapez(object_label+"_phasedephgrad",maxintegral,phaseDirection,dephdur,rampdt,ramptype_cache); dephobjs->phaserephgrad=SeqGradTrapez(object_label+"_phaserephgrad",maxintegral,phaseDirection,dephdur,rampdt,ramptype_cache); // Adjust amplitude dephobjs->readdephgrad.set_integral(integral_deph_read); dephobjs->readrephgrad.set_integral(integral_reph_read); dephobjs->phasedephgrad.set_integral(integral_deph_phase); dephobjs->phaserephgrad.set_integral(integral_reph_phase); unsigned int phase_increment=segments_cache*reduction_cache; if(phase_increment>1) { // Create vector even if there is no phase encoding because it used in loop // use duration of on-ramp and constant part of read gradient as duration of constant part of the gradient vector double phasevecdur=dephobjs->readdephgrad.get_constgrad_duration()+dephobjs->readdephgrad.get_onramp_duration(); fvector deph_strengthvec(phase_increment); fvector reph_strengthvec(phase_increment); for(unsigned int i=0; iphasesegdephgrad=SeqGradVector(object_label+"_phasesegdephgrad", phaseDirection, deph_maxstrength, deph_strengthvec, phasevecdur); dephobjs->phasesegrephgrad=SeqGradVector(object_label+"_phasesegrephgrad", phaseDirection, reph_maxstrength, reph_strengthvec, phasevecdur); ODINLOG(odinlog,normalDebug) << "phasesegdephgrad.get_numof_iterations()=" << dephobjs->phasesegdephgrad.get_numof_iterations() << STD_endl; // achieve GRAPPA encoding by interleavedSegmented reordering if(reduction_cache>1) { dephobjs->phasesegdephgrad.set_reorder_scheme(interleavedSegmented, reduction_cache); dephobjs->phasesegrephgrad.set_reorder_scheme(interleavedSegmented, reduction_cache); ODINLOG(odinlog,normalDebug) << "reduction_cache=" << reduction_cache << STD_endl; ODINLOG(odinlog,normalDebug) << "phasesegdephgrad.get_numof_iterations()/reorder.get_numof_iterations()=" << dephobjs->phasesegdephgrad.get_numof_iterations() << "/" << dephobjs->phasesegdephgrad.get_reorder_vector().get_numof_iterations() << STD_endl; } } } const SeqVector* SeqAcqEPI::get_dephgrad(SeqGradChanParallel& dephobj, bool rephase) const { Log odinlog(this,"get_dephgrad"); const SeqVector* result=0; if(dephobjs->phasedephgrad.get_strength()!=0.0) { if(segments_cache>1 || reduction_cache>1) { if(rephase) { dephobj += ((dephobjs->readrephgrad)/(dephobjs->phasesegrephgrad)); result=&(dephobjs->phasesegrephgrad); } else { dephobj += ((dephobjs->readdephgrad)/(dephobjs->phasesegdephgrad)); result=&(dephobjs->phasesegdephgrad); } } else { if(rephase) dephobj += ((dephobjs->readrephgrad)/(dephobjs->phaserephgrad)); else dephobj += ((dephobjs->readdephgrad)/(dephobjs->phasedephgrad)); } } else { if(rephase) dephobj += dephobjs->readrephgrad; else dephobj += dephobjs->readdephgrad; } ODINLOG(odinlog,normalDebug) << "result/dephobj.get_gradintegral()=" << (void*)result << "/" << dephobj.get_gradintegral().printbody() << STD_endl; return result; } SeqAcqInterface& SeqAcqEPI::set_template_type(templateType type) { templtype_cache=type; driver->set_template_type(type); create_deph_and_reph(); return *this; } SeqAcqEPI::SeqAcqEPI(const SeqAcqEPI& sae) : driver(sae.get_label()) { common_init(); SeqAcqEPI::operator = (sae); } SeqAcqEPI::SeqAcqEPI(const STD_string& object_label) : SeqObjBase(object_label), driver(object_label) { common_init(); } RecoValList SeqAcqEPI::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { Log odinlog(this,"get_recovallist"); int nTEs=2*echo_pairs_cache; if(nTEs<=0) nTEs=1; int nechoes=driver->get_numof_gradechoes(); int startindex_phase=int(phasesize_cache)-nechoes/nTEs*segments_cache*reduction_cache; // recalculate with actual number of grad echoes ODINLOG(odinlog,normalDebug) << "nechoes/phasesize/startindex_phase=" << nechoes << "/" << phasesize_cache << "/" << startindex_phase << STD_endl; unsigned int padded_zeroes=0; kSpaceCoord kcoord_base(driver->get_kcoord_template(padded_zeroes)); kcoord_base.oversampling=os_factor_cache; RecoValList result; int isegment=dephobjs->phasesegdephgrad.get_current_index(); if(templtype_cache==no_template) ODINLOG(odinlog,normalDebug) << "isegment=" << isegment << STD_endl; for(int iecho=0; iecho0) { kcoord.index[te]=iecho%nTEs; } coords.append_coord(kcoord); RecoValList rvl; rvl.set_value(kcoord.number); result.add_sublist(rvl); } return result; } SeqAcqInterface& SeqAcqEPI::set_sweepwidth(double sw, float os_factor) { Log odinlog(this,"set_sweepwidth"); ODINLOG(odinlog,warningLog) << "Ignoring request to change sweepwidth after construction" << STD_endl; return *this; } bool SeqAcqEPI::prep() { Log odinlog(this,"prep"); double gradfreq=secureInv(2.0*driver->get_echoduration()); double low,upp; if(!systemInfo->allowed_grad_freq(gradfreq, low, upp)) { ODINLOG(odinlog,normalDebug) << "gradient frequency " << gradfreq << ODIN_FREQ_UNIT << " not allowed" << STD_endl; return false; } fvector gread=driver->get_readout_shape(); unsigned int greadsize=gread.size(); if( greadsize != readsize_os_cache ) { // assume ramp sampling driver->set_readout_shape(gread,readsize_os_cache); } if(echo_pairs_cache>0) { // Only store TEs in a multi-TE EPI scan int nTEs=2*echo_pairs_cache; dvector TEs(nTEs); double echodur=driver->get_echoduration(); TEs.fill_linear(0.5*echodur, (0.5+double(nTEs-1))*echodur); recoInfo->set_DimValues(te,TEs); } ODINLOG(odinlog,normalDebug) << "templtype_cache=" << templtype_cache << STD_endl; if(templtype_cache==no_template) { // Only store echo time stamps for non-template EPI as they are the basis for field-map based distortion corrections unsigned int nechoes=get_numof_gradechoes(); double echodur=driver->get_echoduration(); ODINLOG(odinlog,normalDebug) << "nechoes/echodur=" << nechoes << "/" << echodur << STD_endl; if(nechoes && echodur>0.0) { // discard empty EPIs dvector echotimestamps(nechoes); echotimestamps.fill_linear(0.0, double(nechoes-1)*echodur); ODINLOG(odinlog,normalDebug) << "echotimestamps=" << echotimestamps.printbody() << STD_endl; recoInfo->set_DimValues(echo,echotimestamps); } } return true; } SeqAcqEPI& SeqAcqEPI::operator = (const SeqAcqEPI& sae) { SeqObjBase::operator = (sae); readsize_os_cache=sae.readsize_os_cache; os_factor_cache=sae.os_factor_cache; phasesize_cache=sae.phasesize_cache; segments_cache=sae.segments_cache; reduction_cache=sae.reduction_cache; echo_pairs_cache=sae.echo_pairs_cache; blipint_cache=sae.blipint_cache; templtype_cache=sae.templtype_cache; ramptype_cache=sae.ramptype_cache; driver=sae.driver; create_deph_and_reph(); // initialize dephobjs return *this; } odin-1.8.5/odinseq/seqdec.cpp0000644000175000017500000000664611322062345013023 00000000000000#include "seqdec.h" #include SeqDecoupling::SeqDecoupling(const STD_string& object_label,const STD_string& nucleus,float decpower,const dvector& freqlist, const STD_string decprog,float decpulsduration) : SeqObjList(object_label), SeqFreqChan(object_label,nucleus,freqlist), decdriver(object_label) { set_decpower(decpower); set_program(decprog); set_pulsduration(decpulsduration); } SeqDecoupling::SeqDecoupling(const SeqDecoupling& sd) { SeqDecoupling::operator = (sd); } SeqDecoupling::SeqDecoupling(const STD_string& object_label) : SeqObjList(object_label), SeqFreqChan(object_label), decdriver(object_label) { set_decpower(120.0); set_program(""); set_pulsduration(0.0); } bool SeqDecoupling::prep() { if(!SeqFreqChan::prep()) return false; return decdriver->prep_driver(SeqObjList::get_duration(),get_channel(),get_decpower(),get_program(),get_pulsduration()); } const SeqVector& SeqDecoupling::get_freqlist_vector() const { SeqSimultanVector* result=new SeqSimultanVector(STD_string(get_label())+"_instancevec"); result->set_temporary(); for(constinstiter it=get_const_inst_begin(); it!=get_const_inst_end(); ++it) (*result)+=(**it); return *result; } STD_string SeqDecoupling::get_program(programContext& context) const { STD_string result; result+=decdriver->get_preprogram(context,get_iteratorcommand(freqObj)); result+=SeqObjList::get_program(context); result+=decdriver->get_postprogram(context); return result; } SeqValList SeqDecoupling::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()); double newfreq=SeqFreqChan::get_frequency(); if(action==calcDecList) { result.set_value(newfreq); ODINLOG(odinlog,normalDebug) << "freq=" << newfreq << STD_endl; } return result; } void SeqDecoupling::clear_container() { SeqObjList::clear_container(); clear_instances(); } double SeqDecoupling::get_duration() const { double result=0.0; result+=decdriver->get_preduration(); result+=SeqObjList::get_duration(); result+=decdriver->get_postduration(); return result; } unsigned int SeqDecoupling::event(eventContext& context) const { Log odinlog(this,"event"); unsigned int result=0; double start=context.elapsed+decdriver->get_preduration(); if(context.action==seqRun) { SeqFreqChan::pre_event(context,start); decdriver->event(context,start); result+=SeqObjList::event(context); SeqFreqChan::post_event(context,start+SeqObjList::get_duration()); } if(context.event_progmeter) context.event_progmeter->increase_counter(); result++; return result; } SeqDecoupling& SeqDecoupling::operator () (const SeqObjBase& so) { SeqDecoupling& dec=set_embed_body(so); return dec; } STD_string SeqDecoupling::get_program() const {return decprogram;} void SeqDecoupling::set_program(const STD_string& p) { decprogram=p; } double SeqDecoupling::get_pulsduration() const {return pulsduration;} void SeqDecoupling::set_pulsduration(float d) { pulsduration=d; } SeqDecoupling& SeqDecoupling::operator = (const SeqDecoupling& sd) { SeqObjList::operator = (sd); SeqFreqChan::operator = (sd); decdriver=sd.decdriver; set_program(sd.get_program()); set_decpower(sd.get_decpower()); set_pulsduration(sd.get_pulsduration()); return *this; } int SeqDecoupling::set_body(const SeqObjBase& so) { clear(); (*this)+=(so); return 0; } odin-1.8.5/odinseq/seqtemplate.h0000644000175000017500000000513511322062345013540 00000000000000/*************************************************************************** seqtemplate.h - description ------------------- begin : Mon Tue 23 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQTEMPLATE_H #define SEQTEMPLATE_H #include /** * @addtogroup odinseq * @{ */ struct SeqFieldMapPars; // forward declaration struct SeqFieldMapObjects; // forward declaration /** * \brief Multi-echo module for field-map pre-scan * * In order to acquire a field-map together with the actual scan, this * sequence module employs an EPI-like readout where each shot acquires * an even number of alternating echoes (each with a different TE) * separately for each line in k-space. * */ class SeqFieldMap : public SeqObjList { // Disable copying SeqFieldMap(const SeqFieldMap& sfm) {} SeqFieldMap& operator = (const SeqFieldMap& sfm) {return *this;} void alloc_data(); SeqFieldMapPars* pars; SeqFieldMapObjects* objs; public: /** * Constructs a field-map scan */ SeqFieldMap() : pars(0), objs(0) {} ~SeqFieldMap(); /** * Initialize field-map scan with default values, sequence objects are prefixed by 'objlabel'. * This function is usually called in the sequence initialization step. */ void init(const STD_string& objlabel); /** * Builds the field-map scan using bandwidth 'sweepwidth' with oversampling factor 'os_factor', an extra preparation 'prep' prior to each excitation and minimum relaxation delay 'min_relaxdelay'. * This function is usually called in the sequence building step. */ void build_seq(double sweepwidth, float os_factor=1.0, const SeqObjList& prep=SeqObjList(), double min_relaxdelay=0.0); /** * Returns block of local parameters */ JcampDxBlock& get_parblock(); }; /** @} */ #endif odin-1.8.5/odinseq/seqgradspiral.cpp0000644000175000017500000002072711735132611014416 00000000000000#include "seqgradspiral.h" #include "seqgradramp.h" #include "odinpulse.h" // for _TRAJ_OPTIMIZE_PARLABEL_ #define TEST_NPTS 1000 float SeqGradSpiral::readout_npts() const { Log odinlog(this,"readout_npts"); if(!traj_cache) return -1.0; // make a test run to approximate the tangential step size, maximum gradient strengt and slew rate float deltaKtangential=0.0; float last_kx=0.0; float last_ky=0.0; float last_Gx=0.0; float last_Gy=0.0; float max_grad_magn=0.0; float max_grad_diff=0.0; for(unsigned int i=0; icalculate(s); if(i) { deltaKtangential=STD_max(double(deltaKtangential),norm(tds.kx-last_kx,tds.ky-last_ky)); max_grad_diff=STD_max(double(max_grad_diff),fabs(tds.Gx-last_Gx)); max_grad_diff=STD_max(double(max_grad_diff),fabs(tds.Gy-last_Gy)); } max_grad_magn=STD_max(double(max_grad_magn),fabs(tds.Gx)); max_grad_magn=STD_max(double(max_grad_magn),fabs(tds.Gy)); last_kx=tds.kx; last_ky=tds.ky; last_Gx=tds.Gx; last_Gy=tds.Gy; } ODINLOG(odinlog,normalDebug) << "deltaKtangential/max_grad_magn/max_grad_diff = " << deltaKtangential << "/" << max_grad_magn << "/" << max_grad_diff << STD_endl; if(deltaKtangential==0.0) { ODINLOG(odinlog,errorLog) << "Zero trajectory" << STD_endl; return 0; } // the desired (relative) k-space step size float deltaKdesired=secureInv(sizeRadial_cache); // calculate the total number of points to get a sufficient coverage of k-space float npts=float(TEST_NPTS)*secureDivision(deltaKtangential,deltaKdesired); float k0=secureDivision(PII,resolution_cache); float gradfactor=secureDivision(k0, gamma_cache*npts*dt_cache); // Estimate maximum gradient strength and slew rate according to the test trajectory float dt_test=dt_cache*secureDivision(npts,TEST_NPTS); float maxgrad_test = max_grad_magn * gradfactor; float maxslew_test = secureDivision(max_grad_diff * gradfactor, dt_test); ODINLOG(odinlog,normalDebug) << "dt_test/maxgrad_test/maxslew_test = " << dt_test << " / " << maxgrad_test << " / " << maxslew_test << STD_endl; // Correct npts if max grad strength or slew is exceeded float prolongfactor=1.0; if(maxgrad_test>systemInfo->get_max_grad()) { prolongfactor=STD_max(double(prolongfactor),secureDivision(maxgrad_test,systemInfo->get_max_grad())); } if(maxslew_test>systemInfo->get_max_slew_rate()) { prolongfactor=STD_max(double(prolongfactor),secureDivision(maxslew_test,systemInfo->get_max_slew_rate())); } ODINLOG(odinlog,normalDebug) << "prolongfactor = " << prolongfactor << STD_endl; if(prolongfactor>1.0) npts*=prolongfactor; return npts; } float SeqGradSpiral::evaluate(const fvector& spirpar) const { Log odinlog(this,"evaluate"); if(!traj_cache) return -1.0; ODINLOG(odinlog,normalDebug) << "spirpar=" << spirpar[0] << STD_endl; if(!traj_cache->set_parameter(_TRAJ_OPTIMIZE_PARLABEL_,ftos(spirpar[0]))) { ODINLOG(odinlog,normalDebug) << _TRAJ_OPTIMIZE_PARLABEL_ << " not available" << STD_endl; return -1.0; } float result=readout_npts(); ODINLOG(odinlog,normalDebug) << "result(" << spirpar[0] << ")=" << result << STD_endl; return result; } SeqGradSpiral::SeqGradSpiral(const STD_string& object_label, JDXtrajectory& traj, double dt, float resolution, unsigned int sizeRadial, unsigned int numofSegments, bool inwards, bool optimize, const STD_string& nucleus) : SeqGradChanParallel(object_label), predelay(0.0), dt_cache(dt), resolution_cache(resolution), sizeRadial_cache(sizeRadial), gamma_cache(systemInfo->get_gamma(nucleus)) { Log odinlog(this,"SeqGradSpiral(...)"); common_init(); unsigned int i; if(traj.get_function_mode()!=twoDeeMode) { ODINLOG(odinlog,errorLog) << "traj has wrong funcMode" << STD_endl; return; } if(!numofSegments) numofSegments=1; // set the number of cycles according to the step size in radial direction traj.set_parameter("NumCycles",itos(int(secureDivision(sizeRadial,(2*numofSegments))))); traj_cache=&traj; if(optimize && traj.set_parameter(_TRAJ_OPTIMIZE_PARLABEL_,ftos(0.0))) { // perform optimization only if appropriate parameter is available float minpar=bruteforce_minimize1d(*this, 0.0, 1.0)[0]; ODINLOG(odinlog,normalDebug) << "minpar=" << minpar << STD_endl; traj.set_parameter(_TRAJ_OPTIMIZE_PARLABEL_,ftos(minpar)); } float fnpts=readout_npts(); if(fnpts<=0.0) { ODINLOG(odinlog,errorLog) << "Cannot calculate readout length" << STD_endl; return; } unsigned int npts=(unsigned int)(fnpts+0.5); float k0=secureDivision(PII,resolution); float gradfactor=secureDivision(k0, gamma_cache*npts*dt); spiral_dur=npts*dt; ODINLOG(odinlog,normalDebug) << "npts / k0 / spiral_dur = " << npts << " / " << k0 << " / " << spiral_dur << STD_endl; if(spiral_dur==0.0) { ODINLOG(odinlog,errorLog) << "Zero duration spiral" << STD_endl; return; } fvector Gx(npts); fvector Gy(npts); denscomp.resize(npts); kx.resize(npts); ky.resize(npts); float sign=1.0; if(!inwards) sign=-1.0; // trajectory is traversed backwards // calculate the gradient arrays for (i=0; i odinlog(this,"get_ktraj"); fvector result(spiral_size()); result=0.0; if(channel==readDirection) result=kx; if(channel==phaseDirection) result=ky; return result; } void SeqGradSpiral::build_seq() { clear(); gxdelay.set_duration(predelay); gydelay.set_duration(predelay); if(predelay>0.0) { (*this) += (gxdelay+gx) / (gydelay+gy); } else { (*this) += gx / gy; } } odin-1.8.5/odinseq/seqdelay.h0000644000175000017500000000613711322062345013026 00000000000000/*************************************************************************** seqdelay.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDELAY_H #define SEQDELAY_H #include #include #include /** * @ingroup odinseq_internals * The base class for platform specific drivers of delays */ class SeqDelayDriver : public SeqDriverBase { public: SeqDelayDriver() {} virtual ~SeqDelayDriver() {} virtual STD_string get_program(programContext& context, double duration, const STD_string& cmd, const STD_string& durcmd) const = 0; virtual SeqDelayDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Timing delay * * This class represents a delay with an optional command. */ class SeqDelay : public SeqObjBase, public SeqDur { public: /** * Constructs a delay labeled 'object_label' with the following properties: * - delayduration: The duration of the delay. * - command: An optional command that will be issued during the delay in * the pulse program. * - durationVariable: If the the command that specifies the delay duration in * the pulse program should differ from the default, it can be * overwritten by this string. */ SeqDelay(const STD_string& object_label = "unnamedSeqDelay",float delayduration=0.0, const STD_string& command="",const STD_string& durationVariable="" ); /** * Constructs a delay which is a copy of 'sd' */ SeqDelay(const SeqDelay& sd); /** * This assignment operator will make this object become an exact copy of 'sd'. */ SeqDelay& operator = (const SeqDelay& sd); /** * This assignment operator can be used to specify the duration of the delay */ SeqDelay& operator = (float dur); /** * Specifies the extra command for the delay */ SeqDelay& set_command(const STD_string& command); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; private: mutable SeqDriverInterface delaydriver; STD_string cmd; STD_string durcmd; }; /** @} */ #endif odin-1.8.5/odinseq/seqdriver_paravision.cpp0000644000175000017500000000257611322062345016014 00000000000000#ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif // include Qt stuff first to avoid ambiguities with 'debug' /* #ifdef GUISUPPORT #include #endif */ #ifdef PARAVISION_PLUGIN #include "../platforms/Paravision/odinseq_paravision/seqparavision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqacq_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqacqepi_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqcounter_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqdec_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqdelay_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqfreq_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqgradchan_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqgradtrapez_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqlist_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqparallel_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqphase_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqpilot_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqpuls_paravision.cpp" #include "../platforms/Paravision/odinseq_paravision/seqtrigg_paravision.cpp" #endif odin-1.8.5/odinseq/seqtree.cpp0000644000175000017500000000352411322062345013217 00000000000000#ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #ifdef HAVE_TYPEINFO #include #endif #include "seqtree.h" SeqTreeObj::SeqTreeObj() : SeqClass() { Log odinlog("SeqTreeObj","SeqTreeObj()"); set_label("unnamedSeqTreeObj"); // this is neccessary because SeqClass is a virtual base class } void SeqTreeObj::display_event(eventContext& context) const { if(!context.event_display) return; svector columntext; columntext.resize(2); columntext[0]=ftos(context.elapsed); columntext[1]=get_label(); context.event_display->display_node(this,0,looplevel,columntext); } void SeqTreeObj::query(queryContext& context) const { if(context.action==count_acqs) context.numof_acqs=0; if(context.action==checkoccur) context.checkoccur_result=context.checkoccur_result || (context.checkoccur_sto==this); if(context.action==display_tree) { svector columntext; columntext.resize(4); const char* type="unknown"; #ifdef HAVE_TYPEINFO type=typeid(*this).name(); while( (*type) >='0' && (*type) <='9' ) type++; #endif STD_string typestr(type); // replace SeqMethod_... by SeqMethod for seqtree dump of seqtest if(typestr.find("SeqMethod_")==0) typestr="SeqMethod"; columntext[0]=get_label(); columntext[1]=typestr; columntext[2]=ftos(get_duration()); columntext[3]=get_properties(); context.tree_display->display_node(this,context.parentnode,context.treelevel,columntext); } } bool SeqTreeObj::contains(const SeqTreeObj* sto) const { queryContext qc; qc.action=checkoccur; qc.checkoccur_sto=sto; this->query(qc); return qc.checkoccur_result; } void SeqTreeObj::tree(SeqTreeCallbackAbstract* display) const { queryContext qc; qc.action=display_tree; qc.tree_display=display; qc.parentnode=this; this->query(qc); } int SeqTreeObj::looplevel=0; odin-1.8.5/odinseq/seqlist.cpp0000644000175000017500000001405511322062345013234 00000000000000#include "seqlist.h" #include "seqloop.h" #include "seqdec.h" #include "seqparallel.h" #include "seqgradobj.h" #include "seqgradchanparallel.h" #include #include SeqObjList::SeqObjList(const STD_string& object_label) : SeqObjBase(object_label), listdriver(object_label) { Log odinlog(this,"SeqObjList()"); } SeqObjList::SeqObjList(const SeqObjList& so) { SeqObjList::operator = (so); } SeqObjList::~SeqObjList() { Log odinlog(this,"~SeqObjList()"); } SeqObjList& SeqObjList::operator = (const SeqObjList& so) { SeqObjBase::operator = (so); List::operator = (so); listdriver=so.listdriver; return *this; } SeqObjList& SeqObjList::operator = (const SeqObjLoop& sl) { clear(); (*this)+=sl; return *this; } SeqObjList& SeqObjList::operator = (const SeqDecoupling& sd) { clear(); (*this)+=sd; return *this; } SeqObjList& SeqObjList::operator = (const SeqObjBase& soa) { clear(); (*this)+=soa; return *this; } SeqObjList& SeqObjList::operator += (const SeqObjBase& soa) { Log odinlog(this,"+="); if((&soa)->contains(this)) { ODINLOG(odinlog,errorLog) << "Refusing to append >" << soa.get_label() << "< to >" << get_label() << "< which would then contain itself" << STD_endl; } else append(soa); return *this; } SeqObjList& SeqObjList::operator += (SeqGradObjInterface& sgoa) { SeqParallel* par=new SeqParallel(STD_string("[")+sgoa.get_label()+"]"); par->set_temporary(); par->set_gradptr(&sgoa); (*this)+=(*par); return *this; } SeqObjList& SeqObjList::operator += (SeqGradChan& sgc) { SeqGradChanList* sgcl=new SeqGradChanList(STD_string("(")+sgc.get_label()+")"); sgcl->set_temporary(); (*sgcl)+=sgc; (*this)+=(*sgcl); return *this; } SeqObjList& SeqObjList::operator += (SeqGradChanList& sgcl) { SeqGradChanParallel* par=new SeqGradChanParallel(STD_string("{")+sgcl.get_label()+"}"); par->set_temporary(); (*par)+=sgcl; (*this)+=(*par); return *this; } unsigned int SeqObjList::event(eventContext& context) const { Log odinlog(this,"event"); unsigned int result=0; const RotMatrix* rotmatrix=0; if(gradrotmatrixvec.get_handled()) { current_gradrotmatrixvec.set_handled(gradrotmatrixvec.get_handled()); rotmatrix=&(current_gradrotmatrixvec.get_handled()->get_current_matrix()); } listdriver->pre_event(context,rotmatrix); for(constiter it=get_const_begin();it!=get_const_end();++it) { listdriver->pre_itemevent(*it,context); ODINLOG(odinlog,normalDebug) << (*it)->get_label() << "->event" << STD_endl; result+=(*it)->event(context); listdriver->post_itemevent(*it,context); } listdriver->post_event(context,rotmatrix); current_gradrotmatrixvec.clear_handledobj(); return result; } double SeqObjList::get_duration() const { Log odinlog(this,"get_duration"); double result=0.0; if(gradrotmatrixvec.get_handled()) current_gradrotmatrixvec.set_handled(gradrotmatrixvec.get_handled()); for(constiter it=get_const_begin();it!=get_const_end();++it) { result+=(*it)->get_duration(); ODINLOG(odinlog,normalDebug) << "duration(" << (*it)->get_label() << ")=" << (*it)->get_duration() << STD_endl; } current_gradrotmatrixvec.clear_handledobj(); return result; } STD_string SeqObjList::get_properties() const { return "NumOfObjects="+itos(size()); } STD_string SeqObjList::get_program(programContext& context) const { STD_string result; if(gradrotmatrixvec.get_handled()) current_gradrotmatrixvec.set_handled(gradrotmatrixvec.get_handled()); result+=listdriver->pre_program(context, gradrotmatrixvec.get_handled()); for(constiter it=get_const_begin();it!=get_const_end();++it) { result+=listdriver->get_itemprogram(*it,context); } result+=listdriver->post_program(context, gradrotmatrixvec.get_handled()); current_gradrotmatrixvec.clear_handledobj(); return result; } void SeqObjList::query(queryContext& context) const { Log odinlog(this,"query"); SeqTreeObj::query(context); // defaults context.treelevel++; unsigned int acqresult=0; for(constiter it=get_const_begin();it!=get_const_end();++it) { context.parentnode=this; // reset to this because it might changed by last query (*it)->query(context); acqresult+=context.numof_acqs; } context.treelevel--; if(context.action==count_acqs) context.numof_acqs=acqresult; } RecoValList SeqObjList::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { Log odinlog(this,"get_recovallist"); RecoValList result(get_label()); for(constiter it=get_const_begin();it!=get_const_end();++it) { ODINLOG(odinlog,normalDebug) << reptimes << "x from " << (*it)->get_label() << STD_endl; RecoValList oneiter=(*it)->get_recovallist(reptimes,coords); result.add_sublist(oneiter); } ODINLOG(odinlog,normalDebug) << "returning" << STD_endl; return result; } SeqValList SeqObjList::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()); for(constiter it=get_const_begin();it!=get_const_end();++it) { SeqValList oneiter=(*it)->get_freqvallist(action); result.add_sublist(oneiter); } return result; } SeqValList SeqObjList::get_delayvallist() const { Log odinlog(this,"get_delayvallist"); SeqValList result(get_label()); for(constiter it=get_const_begin();it!=get_const_end();++it) { SeqValList oneiter=(*it)->get_delayvallist(); result.add_sublist(oneiter); } return result; } double SeqObjList::get_rf_energy() const { double result=0.0; for(constiter it=get_const_begin();it!=get_const_end();++it) { result+=(*it)->get_rf_energy(); } return result; } bool SeqObjList::prep() { if(!SeqObjBase::prep()) return false; return listdriver->prep_driver(); } Handler SeqObjList::current_gradrotmatrixvec; // Template instantiations template class ListItem; template class List; template class Handler; odin-1.8.5/odinseq/seqmakefile.h0000644000175000017500000000507611322062345013506 00000000000000/*************************************************************************** seqmakefile.h - description ------------------- begin : Wed Apr 14 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQMAKEFILE_H #define SEQMAKEFILE_H #include #ifndef NO_CMDLINE /** * @ingroup odinseq_internals * Helper class to generate Makefiles for different platforms */ class SeqMakefile : public SeqClass { public: SeqMakefile(const STD_string& methlabel, const STD_string& odin_install_prefix="", const STD_string& compiler="", const STD_string& compiler_flags=CXXFLAGS, const STD_string& linker="", const STD_string& extra_includes="", const STD_string& extra_libs=""); STD_string get_Makefile(const STD_string& methroot) const; svector get_method_compile_chain(bool executable, bool shared_object) const; STD_string get_method_clean() const; STD_string get_method_install(const STD_string& methdir) const; svector get_odin4idea_method_compile_chain(const STD_string& in_dir, const STD_string& odindir, const STD_string& vxworks_path, const STD_string& vxworks_cxx, const STD_string& vxworks_flags, const STD_string& win_cxx, const STD_string& hostd_flags, const STD_string& host_flags) const; static STD_string get_exe_postfix(); static STD_string get_so_postfix(); static STD_string get_obj_postfix(); private: STD_string get_methlabel() const {return get_label();} STD_string get_methdefines(const STD_string& main, const STD_string& classlabel) const; JDXfileName inst_prefix; STD_string cxx; STD_string cxxflags; STD_string ld; STD_string add_includes; STD_string add_libs; }; #endif #endif odin-1.8.5/odinseq/seqgradchanparallel.h0000644000175000017500000001033311322062345015205 00000000000000/*************************************************************************** seqgradchanparallel.h - description ------------------- begin : Thu Apr 22 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADCHANPARALLEL_H #define SEQGRADCHANPARALLEL_H #include #include #include //////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of lists of simultaneous gradient objects */ class SeqGradChanParallelDriver : public SeqDriverBase { public: SeqGradChanParallelDriver() {} virtual ~SeqGradChanParallelDriver() {} virtual bool prep_driver(SeqGradChanList* chanlists[3]) const = 0; virtual STD_string get_program(programContext& context) const = 0; virtual SeqGradChanParallelDriver* clone_driver() const = 0; }; //////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq_internals * @{ */ /** * This class is a container for three SeqGradChanList's */ class SeqGradChanParallel : public SeqGradObjInterface { public: /** * Construct an empty gradient channel list with the given label */ SeqGradChanParallel(const STD_string& object_label = "unnamedSeqGradChanParallel" ); /** * Constructs a copy of 'sgcp' */ SeqGradChanParallel(const SeqGradChanParallel& sgcp); /** * Destructor */ ~SeqGradChanParallel(); /** * Assignment operator that makes this gradient sequence object become a copy of 'sgcp' */ SeqGradChanParallel& operator = (const SeqGradChanParallel& sgcp); /** * Uses 'sgc' for the corresponding channel */ SeqGradChanParallel& operator /= (SeqGradChan& sgc); /** * Uses 'sgcl' for the corresponding channel */ SeqGradChanParallel& operator /= (SeqGradChanList& sgcl); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; STD_string get_properties() const; unsigned int event(eventContext& context) const; void query(queryContext& context) const; // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; fvector get_gradintegral() const; double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); /** * Appends 'sgc' to this */ SeqGradChanParallel& operator += (SeqGradChan& sgc); /** * Appends 'sgcl' to this */ SeqGradChanParallel& operator += (SeqGradChanList& sgcl); /** * Appends 'sgcp' to this */ SeqGradChanParallel& operator += (SeqGradChanParallel& sgcp); /** * Clear all sublists */ void clear(); private: friend class SeqOperator; friend class SeqGradChan; friend class SeqGradChanList; friend class SeqGradEPI; friend class SeqEpiKernel; // overwriting virtual functions from SeqClass bool prep(); void clear_container(); // overwriting virtual functions from SeqGradObjInterface bool need_gp_terminator() const {return true;} void padd_channel_with_delay(direction chanNo, double maxdur); SeqGradChanList* get_gradchan(direction channel) const; SeqGradChanParallel& set_gradchan(direction channel, SeqGradChanList* sgcl); mutable SeqDriverInterface paralleldriver; Handler gradchan[3]; }; /** @} */ #endif odin-1.8.5/odinseq/seqmeth.cpp0000644000175000017500000005406211322062345013220 00000000000000#include "seqmeth.h" #include "seqacq.h" #include "seqdelayvec.h" #include "seqfreq.h" #include "seqpulsar.h" #include "seqcmdline.h" // for gradient intro #include "seqgradpulse.h" #include "seqdelay.h" #include #include ////////////////////////////////////////////////////////////////////// #if defined(HAVE_DL) && defined(HAVE_SIGNAL_H) && defined(HAVE_SETJMP_H) #define CATCH_SEGFAULT_ON_UNIX #endif #ifdef CATCH_SEGFAULT_ON_UNIX #include #include #include // forward declaration function which will be registered as signal handler void segfaultHandler( int ); // Class to catch segmentation faults in functions of the method plug-in. // Otherwise the whole ODIN UI would crash... class CatchSegFaultContext : public StaticHandler { public: CatchSegFaultContext(const char* contextlabel) { Log odinlog(contextlabel,"CatchSegFaultContext"); (*lastmsg)=""; (*label)=contextlabel; sa.sa_handler=segfaultHandler; // sa.sa_sigaction=0; sa.sa_flags=0; sigprocmask(SIG_SETMASK,&sa.sa_mask,0); /* #ifndef sgi sa.sa_restorer=0; #endif */ if(sigaction(SIGSEGV,&sa,0)) ODINLOG(odinlog,errorLog) << "unable to register segfaultHandler for " << (*label) << STD_endl; } ~CatchSegFaultContext() { Log odinlog(label->c_str(),"~CatchSegFaultContext"); sa.sa_handler=SIG_DFL; sigaction(SIGSEGV,&sa,0); segfault_occured=false; } bool segfault() volatile { Log odinlog(label->c_str(),"segfault"); bool result=segfault_occured; segfault_occured=false; return result; } static void catch_segfault() { Log odinlog("","catch_segfault"); if(lastmsg) { (*lastmsg)="Segmentation fault in " + (*label); ODINLOG(odinlog,errorLog) << (*lastmsg) << STD_endl; } segfault_occured=true; longjmp(CatchSegFaultContext::segfault_cont_pos, 0); } static void report_exception(const char* funcname) { Log odinlog("","report_exception"); if(lastmsg) { (*lastmsg)=STD_string("Exception in ") + funcname; ODINLOG(odinlog,errorLog) << (*lastmsg) << STD_endl; } } static const char* get_lastmsg() { if(lastmsg) return lastmsg->c_str(); return 0; } // functions to initialize/delete static members by the StaticHandler template class static void init_static() { label=new STD_string; lastmsg=new STD_string; } static void destroy_static() { if(label) delete label; label=0; if(lastmsg) delete lastmsg; lastmsg=0; } private: friend class SeqMethod; friend class SeqMethodProxy; static STD_string* label; struct sigaction sa; static bool segfault_occured; static jmp_buf segfault_cont_pos; static STD_string* lastmsg; }; STD_string* CatchSegFaultContext::label=0; bool CatchSegFaultContext::segfault_occured = false; jmp_buf CatchSegFaultContext::segfault_cont_pos; STD_string* CatchSegFaultContext::lastmsg=0; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; // function which will be registered as signal handler void segfaultHandler( int ) {CatchSegFaultContext::catch_segfault();} // macro to call functions whose segfaults will be catched #define CATCHSEGFAULT(func,func_name)\ try {\ volatile CatchSegFaultContext csfc(func_name);\ setjmp(CatchSegFaultContext::segfault_cont_pos);\ if(!csfc.segfault()) func;\ else return false;\ } catch(...) {\ CatchSegFaultContext::report_exception(func_name);\ return false;\ } #else // simply call the function if we do not have CatchSegFaultContext #define CATCHSEGFAULT(func,func_name) func; #endif ////////////////////////////////////////////////////////////////////// #ifdef USING_WIN32 #ifndef ODIN4IDEA #define METHOD_IN_DLL #endif #endif #ifdef METHOD_IN_DLL // function signature typedef void (*set_global_stuff_fptr) (SingletonMap* sol_map); #if __cplusplus extern "C" { #endif // the DLL exported function which will be called after loading the DLL __declspec(dllexport) void set_global_stuff(SingletonMap* sol_map) { // NOTE: Debug uses SingletonHandler -> do not use Debug in here SingletonBase::set_singleton_map_external(sol_map); } #if __cplusplus } // extern "C" #endif #endif ////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Fallback method */ class SeqEmpty : public SeqMethod { public: SeqEmpty() : SeqMethod("SeqEmpty") {} void method_pars_init() {} void method_seq_init() {} void method_rels() {} void method_pars_set() {} }; ////////////////////////////////////////////////////////////////////// void SeqMethodProxy::set_current_method(unsigned int index) { if(!registered_methods) return; unsigned int i=0; for(STD_list::iterator it=registered_methods->begin(); it!=registered_methods->end(); ++it) { (*it)->clear(); if(i==index) current_method->ptr=(*it); i++; } } SeqMethod* SeqMethodProxy::get_current_method() { if(get_numof_methods()) return current_method->ptr; else return empty_method; } unsigned int SeqMethodProxy::get_numof_methods() { if(!registered_methods) return 0; return registered_methods->size(); } unsigned int SeqMethodProxy::delete_methods() { Log odinlog("SeqMethodProxy","delete_methods"); unsigned int result=get_numof_methods(); ODINLOG(odinlog,normalDebug) << "deleting " << result << " method(s) ..." << STD_endl; if(result) { for(STD_list::iterator it=registered_methods->begin(); it!=registered_methods->end(); ++it) { // tmp copy of handle void* handle=(*it)->dl_handle; ODINLOG(odinlog,normalDebug) << "clearing " << (*it)->get_label() << STD_endl; (*it)->clear(); ODINLOG(odinlog,normalDebug) << "deleting " << (*it)->get_label() << STD_endl; CATCHSEGFAULT(delete (*it),("~"+STD_string((*it)->get_label())).c_str()) if(handle!=NULL) { if(dlclose(handle)) { ODINLOG(odinlog,errorLog) << "dlclose: " << dlerror() << STD_endl; } } } } registered_methods->erase(registered_methods->begin(),registered_methods->end()); // clear residual pointers to pulses which do not longer exist if(SeqPulsar::active_pulsar_pulses) SeqPulsar::active_pulsar_pulses->clear(); // clear references which might be left over SeqClass::clear_objlists(); return result; } void SeqMethodProxy::register_method(SeqMethod* meth) { Log odinlog("SeqMethodProxy","register_method"); if(!get_numof_methods()) current_method->ptr=meth; registered_methods->push_back(meth); registered_methods->sort(); registered_methods->unique(); ODINLOG(odinlog,normalDebug) << "registered " << meth->get_label() << STD_endl; } const char* SeqMethodProxy::get_method_label() {return current_method->ptr->get_label().c_str();} const char* SeqMethodProxy::get_status_string() { Log odinlog("SeqMethodProxy","get_status_string"); const char* result=0; #ifdef CATCH_SEGFAULT_ON_UNIX ODINLOG(odinlog,normalDebug) << "obtaining from CatchSegFaultContext" << STD_endl; result=CatchSegFaultContext::get_lastmsg(); #endif if(!result || (result && STD_string(result)=="")) { ODINLOG(odinlog,normalDebug) << "obtaining from current method" << STD_endl; result= get_current_method()->get_current_state_label().c_str(); } if(result) ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; else ODINLOG(odinlog,normalDebug) << "result=0" << STD_endl; return result; } SeqMethod& SeqMethodProxy::operator [] (unsigned int index) { if(!registered_methods) return *empty_method; unsigned int i=0; for(STD_list::iterator it=registered_methods->begin(); it!=registered_methods->end(); ++it) { if(i==index) return *(*it); i++; } return *empty_method; } bool SeqMethodProxy::load_method_so(const STD_string& so_filename) { Log odinlog("SeqMethodProxy","load_method_so"); int flag=0; #ifdef HAVE_DL flag=RTLD_LAZY; #endif void *handle = dlopen (so_filename.c_str(), flag); if(handle==NULL) { ODINLOG(odinlog,errorLog) << dlerror() << STD_endl; return false; } // remove methods which are still linked delete_methods(); #ifdef METHOD_IN_DLL // set global map of singleton objects in DLL before calling odinmain Profiler profdummy("dummy"); ODINLOG(odinlog,normalDebug) << "profdummy done" << STD_endl; SeqPulsar plsdummy; // create list of registered Pulsar pulses ODINLOG(odinlog,normalDebug) << "plsdummy done" << STD_endl; SeqAcq acqdummy; // create acq singletons ODINLOG(odinlog,normalDebug) << "acqdummy done" << STD_endl; // LogBase::set_log_output_function(dll_tracefunction); // Route debug output through own cerr to get output on shell set_global_stuff_fptr set_global_stuff_f=(void (*)(SingletonMap*))dlsym(handle, "set_global_stuff"); ODINLOG(odinlog,normalDebug) << "set_global_stuff_f=" << (void*)set_global_stuff_f << STD_endl; set_global_stuff_f(SingletonBase::get_singleton_map()); ODINLOG(odinlog,normalDebug) << "set_global_stuff_f called" << STD_endl; #endif // call main of the linked method to initialize it int (*odinmain)(int, char**)=(int (*)(int, char**))dlsym(handle, "main"); ODINLOG(odinlog,normalDebug) << "handle/odinmain=" << (void*)handle << "/" << (void*)odinmain << STD_endl; CATCHSEGFAULT(odinmain(0,0),(so_filename+"::odinmain").c_str()) // store handle current_method->ptr->dl_handle=handle; return true; } void SeqMethodProxy::init_static() { Log odinlog("SeqMethodProxy","init_static"); registered_methods.init("registered_methods"); ODINLOG(odinlog,normalDebug) << "registered_methods allocated" << STD_endl; empty_method=new SeqEmpty; ODINLOG(odinlog,normalDebug) << "empty_method allocated" << STD_endl; current_method.init("current_method"); current_method->ptr=empty_method; } void SeqMethodProxy::destroy_static() { Log odinlog("SeqMethodProxy","destroy_static"); current_method.destroy(); registered_methods.destroy(); // totalDuration.destroy(); delete empty_method; } ////////////////////////////////////////////////////////////////////// template class SingletonHandler; SingletonHandler SeqMethodProxy::registered_methods; template class SingletonHandler; SingletonHandler SeqMethodProxy::current_method; SeqMethod* SeqMethodProxy::empty_method=0; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; ////////////////////////////////////////////////////////////////////// SeqMethod::SeqMethod(const STD_string& method_label) : SeqObjList(method_label), StateMachine(&empty), commonPars(0),methodPars(0), dl_handle(0), protcache(0), empty (this,"Empty", 0, &SeqMethod::reset), initialised(this,"Initialised",&empty, &SeqMethod::empty2initialised), built (this,"Built", &initialised,&SeqMethod::initialised2built), prepared (this,"Prepared", &built, &SeqMethod::built2prepared) { Log odinlog(this,"SeqMethod()"); set_current_testcase(0); } SeqMethod::~SeqMethod() { Log odinlog(this,"~SeqMethod()"); clear(); if(methodPars) delete methodPars; if(commonPars) delete commonPars; if(protcache) delete protcache; } SeqMethod& SeqMethod::append_parameter(JcampDxClass& ldr,const STD_string& label,parameterMode parmode) { ldr.set_label(label); JcampDxBlock* blockdum=ldr.cast(blockdum); if(!blockdum) ldr.set_parmode(parmode); // Do not change parmode of a whole block if(methodPars) methodPars->append(ldr); return *this; } SeqMethod& SeqMethod::set_sequence(const SeqObjBase& s) { SeqObjList::clear(); if(commonPars->get_GradientIntro()) { SeqDelay* tokdelay=new SeqDelay("tokdelay",500.0); tokdelay->set_temporary(); float maxgrad=systemInfo->get_max_grad(); SeqGradConstPulse* tok1=new SeqGradConstPulse("tok1",readDirection,0.2*maxgrad,1.0); tok1->set_temporary(); SeqGradConstPulse* tok2=new SeqGradConstPulse("tok2",readDirection,0.4*maxgrad,1.0); tok2->set_temporary(); SeqGradConstPulse* tok3=new SeqGradConstPulse("tok3",readDirection,0.6*maxgrad,1.0); tok3->set_temporary(); (*this)+=(*tokdelay); (*this)+=(*tok1); (*this)+=(*tokdelay); (*this)+=(*tok2); (*this)+=(*tokdelay); (*this)+=(*tok3); (*this)+=(*tokdelay); } (*this)+=s; return *this; } int SeqMethod::process(int argc, char *argv[]) { // Debug already initialized by ODINMETHOD_ENTRY_POINT register_method(this); if(!argc) return 0; // process function is only used to register the method return SeqCmdLine::process(argc,argv); } void SeqMethod::create_protcache() const { Log odinlog(this,"create_protcache"); if(!protcache) protcache=new Protocol; (*protcache)=Protocol(PROTOCOL_BLOCK_LABEL); // start with a fresh protocol in order to avoid adding method pars multiple times, use same label as in recoInfo protcache->system=(*systemInfo); geometryInfo.copy(protcache->geometry); studyInfo.copy(protcache->study); if(commonPars) protcache->seqpars=(*commonPars); if(methodPars) protcache->methpars.create_copy(*methodPars); protcache->append_all_members(); // re-merge all parameters } int SeqMethod::load_protocol(const STD_string& filename) { Log odinlog(this,"load_protocol"); int npars=0; int result=0; int retval; retval=geometryInfo->load(filename); if(retval<0) result=retval; else npars+=retval; retval=studyInfo->load(filename); if(retval<0) result=retval; else npars+=retval; retval=SeqPlatformProxy::load_systemInfo(filename); if(retval<0) result=retval; else npars+=retval; retval=SeqMethodProxy()->load_sequencePars(filename); if(retval<0) result=retval; else npars+=retval; if(result>=0) result=npars; return result; } SeqMethod& SeqMethod::init_systemInfo(double basicfreq,double maxgrad,double slewrate) { systemInfo->set_B0_from_freq(basicfreq); systemInfo->max_grad=maxgrad; systemInfo->max_slew_rate=slewrate; return *this; } int SeqMethod::write_recoInfo(const STD_string& filename) const { create_protcache(); recoInfo->prot.clear(); // Clear and merge instead of assignment to work around bug in assignment of JDX on MinGW recoInfo->prot.merge(*protcache); return recoInfo->write(filename); } int SeqMethod::write_meas_contex(const STD_string& prefix) const { Log odinlog(this,"write_meas_contex"); Profiler prof("write_meas_contex"); int result=0; #ifndef NO_FILEHANDLING // result+=write_protocol(prefix+"protocol"); // result+=write_systemInfo(prefix+"systemInfo"); // result+=write_geometry(prefix+"geometryInfo"); // result+=write_sequencePars(prefix+"sequencePars"); result+=write_recoInfo(prefix+"recoInfo"); #endif return result; } double SeqMethod::get_totalDuration() const { if(commonPars) return commonPars->get_ExpDuration(); return 0.0; } int SeqMethod::load_sequencePars(const STD_string& filename) { Log odinlog(this,"load_sequencePars"); if(commonPars) { commonPars->load(filename); commonPars->set_Sequence(get_label()); // restore sequence label } ODINLOG(odinlog,normalDebug) << "commonPars->load(" << filename << ") done" << STD_endl; if(methodPars) methodPars->load(filename); ODINLOG(odinlog,normalDebug) << "methodPars->load(" << filename << ") done" << STD_endl; set_parblock_labels(); // Overwrite block labels of file return 0; } int SeqMethod::write_sequencePars(const STD_string& filename) const { JcampDxBlock block( (STD_string(get_label())+"_sequencePars") ); if(commonPars) block.merge(*commonPars); if(methodPars) block.merge(*methodPars); return block.write(filename); } bool SeqMethod::set_sequenceParameter(const STD_string& parameter_label, const STD_string& value) { Log odinlog(this,"set_sequenceParameter"); bool result=false; // first send it to common pars without prefix STD_string parlabel=parameter_label; if(commonPars) if(commonPars->JcampDxBlock::parseval(parlabel,value)) result=true; // then send it to method pars with prefix STD_string prefixstr=STD_string(get_label())+"_"; if(parameter_label.find(prefixstr)!=0) parlabel=prefixstr+parameter_label; if(methodPars) if(methodPars->JcampDxBlock::parseval(parlabel,value)) result=true; return result; } SeqMethod& SeqMethod::set_commonPars(const SeqPars& pars) { (*commonPars)=pars; commonPars->set_Sequence(get_label()); // restore sequence label return *this; } int SeqMethod::load_systemInfo(const STD_string& filename) { return SeqPlatformProxy::load_systemInfo(filename); } unsigned int SeqMethod::event(eventContext& context) const { Log odinlog(this,"event"); if(context.action==seqRun) { ODINLOG(odinlog,normalDebug) << "calling pre_event of " << platform->get_label() << STD_endl; platform->pre_event(context); } ODINLOG(odinlog,normalDebug) << "------------------- action=" << context.action << "-------------------" << STD_endl; unsigned int result=SeqObjList::event(context); if(context.action==seqRun) { ODINLOG(odinlog,normalDebug) << "calling post_event of " << platform->get_label() << STD_endl; platform->post_event(context); } return result; } void SeqMethod::parameter_relations(JDXeditWidget* editwidget) { #ifdef GUISUPPORT clear(); build(); editwidget->updateWidget(); #endif } STD_list SeqMethod::get_active_pulsar_pulses() const { Log odinlog(this,"get_active_pulsar_pulses"); SeqPulsar::PulsarList result; if(SeqPulsar::active_pulsar_pulses) SeqPulsar::active_pulsar_pulses.copy(result); return result;; } unsigned int SeqMethod::get_numof_acquisitions() const { Log odinlog(this,"get_numof_acquisitions"); queryContext qc; qc.action=count_acqs; SeqObjList::query(qc); return qc.numof_acqs; } bool SeqMethod::prep_acquisition() const { Log odinlog(this,"prep_acquisition",significantDebug); Profiler prof("prep_acquisition"); double totaldur=get_totalDuration(); unsigned int nacqs_total=get_numof_acquisitions(); ODINLOG(odinlog,infoLog) << "duration=" << totaldur << " min" << STD_endl; ODINLOG(odinlog,infoLog) << "numof_acquisitions=" << nacqs_total << STD_endl; if(platform->create_recoInfo()) { // do this only if really necessary, i.e. NOT on VxWorks (recoInfo->DataFormat) =platform->get_rawdatatype(); (recoInfo->RawFile) =platform->get_rawfile(); (recoInfo->RawHeaderSize) =platform->get_rawheader_size(); (recoInfo->ImageProc) =platform->get_image_proc(); for(int idir=readDirection; idir<=sliceDirection; idir++) { (recoInfo->RelativeOffset)[idir]=secureDivision(geometryInfo->get_offset(direction(idir)),geometryInfo->get_FOV(direction(idir))); } recoInfo->ChannelScaling=platform->get_acq_channel_scale_factors(); ODINLOG(odinlog,normalDebug) << "getting k-space ordering from sequence" << STD_endl; recoInfo->kSpaceCoords.clear(); recoInfo->kSpaceOrdering=SeqObjList::get_recovallist(1,recoInfo->kSpaceCoords); unsigned int nacqs_recoInfo=recoInfo->get_NumOfAdcChunks(); if(nacqs_recoInfo!=nacqs_total) { ODINLOG(odinlog,errorLog) << "Inconsistent number of acqs: " << nacqs_recoInfo << "!=" << nacqs_total << STD_endl; return false; } } // tag repetition loop queryContext qc; qc.action=tag_toplevel_reploop; qc.repetitions_prot=commonPars->get_NumOfRepetitions(); SeqObjList::query(qc); // execute platform-specific initialization platform->prepare_measurement(nacqs_total); // set current date/time studyInfo->set_timestamp(); return true; } bool SeqMethod::reset() { Log odinlog(this,"reset", significantDebug); // SeqClass::clear_messages(); clear_containers(); clear_temporary(); recoInfo->reset(); return true; } bool SeqMethod::empty2initialised() { Log odinlog(this,"empty2initialised", significantDebug); Profiler prof("empty2initialised"); STD_string method_label(get_label()); int maxmethname=platform->get_max_methodname_length(); if(maxmethname>=0 && int(method_label.length())>maxmethname) { ODINLOG(odinlog,warningLog) << "Method identifier >" << method_label << "< too long (max=" << maxmethname << " chars), will be cut" << STD_endl; STD_string cut=get_label().substr(0,maxmethname); set_label(cut); } if(!commonPars) { commonPars=new SeqPars(); commonPars->set_Sequence(get_label()); // init sequence label ODINLOG(odinlog,normalDebug) << "commonPars allocated" << STD_endl; } if(!methodPars) { methodPars=new JcampDxBlock(); CATCHSEGFAULT(method_pars_init(),"method_pars_init") methodPars->set_prefix(get_label()); ODINLOG(odinlog,normalDebug) << "methodPars allocated" << STD_endl; } set_parblock_labels(); platform->init(); return true; } bool SeqMethod::initialised2built() { Log odinlog(this,"initialised2built", significantDebug); Profiler prof("initialised2built"); ODINLOG(odinlog,significantDebug) << "calling method_seq_init()" << STD_endl; CATCHSEGFAULT(method_seq_init(),"method_seq_init") return calc_timings(); } void SeqMethod::set_parblock_labels() { commonPars->set_label("Common Sequence Parameters"); methodPars->set_label(STD_string(get_label())+" Sequence Parameters"); } bool SeqMethod::calc_timings() { Log odinlog(this,"calc_timings", significantDebug); ODINLOG(odinlog,significantDebug) << "calling method_rels()" << STD_endl; CATCHSEGFAULT(method_rels(),"method_rels") double totalDuration_sec=SeqObjList::get_duration()/1000.0; ODINLOG(odinlog,normalDebug) << "totalDuration_sec=" << totalDuration_sec << STD_endl; if(commonPars) commonPars->set_ExpDuration(totalDuration_sec/60.0); return true; } bool SeqMethod::update_timings() { Log odinlog(this,"update_timings", significantDebug); if(!build()) return false; if(!calc_timings()) return false; return true; } bool SeqMethod::built2prepared() { Log odinlog(this,"built2prepared", significantDebug); ODINLOG(odinlog,significantDebug) << "calling method_pars_set()" << STD_endl; CATCHSEGFAULT(method_pars_set(),"method_pars_set") SeqTreeObj::looplevel=0; platform->reset_before_prep(); return prep_all(); } odin-1.8.5/odinseq/seqgradphase.cpp0000644000175000017500000002002511455553540014222 00000000000000#include "seqgradphase.h" void SeqGradPhaseEnc::init_encoding(unsigned int nsteps, encodingScheme scheme, reorderScheme reorder, unsigned int nsegments, unsigned int reduction, unsigned int acl_bands, float partial_fourier) { Log odinlog(this,"init_encoding"); if(partial_fourier<0.0) partial_fourier=0.0; if(partial_fourier>1.0) partial_fourier=1.0; unsigned int startindex=(unsigned int)(partial_fourier*0.5*nsteps+0.5); // some plausibility checks if(reduction>nsteps) reduction=nsteps; // / order is important if(reduction<1) reduction=1; // \ here because nsteps might be 0 unsigned int ngaps=nsteps/reduction; if(acl_bands>ngaps) acl_bands=ngaps; // The indices covering the central part with auto-calibration lines unsigned int acl_start= (ngaps-acl_bands)/2 * reduction; unsigned int acl_end=acl_start+acl_bands*reduction; ODINLOG(odinlog,normalDebug) << "acl_start/acl_end=" << acl_start << "/" << acl_end << STD_endl; // decrease startindex so that we cover all of the ACL area if(reduction>1 && startindex>acl_start) startindex=acl_start; unsigned int ncovered=nsteps-startindex; // the number of encoding steps actually covered by partial Fourier unsigned int n_scanned=ncovered/reduction; if(ncovered%reduction) n_scanned++; // we can stuff in one more unsigned int vecsize=n_scanned+acl_bands*(reduction-1); // the number of lines actually scanned ODINLOG(odinlog,normalDebug) << "nsteps/startindex/reduction/ngaps/acl_bands/vecsize=" << nsteps << "/" << startindex << "/" << reduction << "/" << ngaps << "/" << acl_bands << "/" << vecsize << STD_endl; fvector petrims(vecsize); ivector recoindexivec(vecsize); float stepsize=secureDivision(2.0,nsteps); unsigned int ivec=0; for(unsigned int istep=0; istep=acl_start && istepget_gamma(nucleus); float resolution=secureDivision(fov,nsteps); float integral=secureDivision( PII , ( gamma * resolution ) ); float sr=systemInfo->get_max_slew_rate(); float Gmax_sr=sqrt(integral * sr); if(fabs(gradstrength)>Gmax_sr) { gradstrength=secureDivision(gradstrength,fabs(gradstrength)); //preserve sign gradstrength*=Gmax_sr; SeqGradVectorPulse::set_strength(gradstrength); ODINLOG(odinlog,warningLog) << "Reducing strength of SeqGradPhaseEnc in order satisfy integral" << STD_endl; } double dur=secureDivision( integral , gradstrength ); set_constduration(dur); } SeqGradPhaseEnc::SeqGradPhaseEnc(const STD_string& object_label, unsigned int nsteps, float fov, float gradduration, direction gradchannel, encodingScheme scheme, reorderScheme reorder, unsigned int nsegments, unsigned int reduction, unsigned int acl_bands, float partial_fourier, const STD_string& nucleus) : SeqGradVectorPulse(object_label,gradchannel,0.0,fvector(nsteps),gradduration) { Log odinlog(this,"SeqGradPhaseEnc(fov)"); init_encoding(nsteps, scheme, reorder, nsegments, reduction, acl_bands, partial_fourier); float gamma=systemInfo->get_gamma(nucleus); float resolution=secureDivision(fov,nsteps); float integral=secureDivision( PII , ( gamma * resolution ) ); float gradstrength=secureDivision( integral , gradduration ); SeqGradVectorPulse::set_strength(gradstrength); } ///////////////////////////////////////////////////////////////////////////////////////////////////////// void SeqGradPhaseEncFlowComp::calc_flowcomp_pe(float& negfact, float& tc, float Gpos, float M0, float t0, float slewrate) { Log odinlog("SeqGradPhaseEncFlowComp","calc_flowcomp_pe"); ODINLOG(odinlog,normalDebug) << "Gpos/M0/t0/slewrate=" << Gpos << "/" << M0 << "/" << t0 << "/" << slewrate << STD_endl; // ramp time float tr=secureDivision(Gpos,slewrate); ODINLOG(odinlog,normalDebug) << "tr=" << tr << STD_endl; // constant part of trapez ending at tc with ramp time tr and starting at t0 was // calculated with maxima: // solve ( Gp* ( integrate(t*(t-t0 )/tr ,t, t0, t0+tr) + integrate(t, t, t0+tr, t0+tc ) + integrate(t*(t0+tr+tc -t)/tr, t, t0+tc, t0+tr+tc ) ) - (Gp-M0/tc)*( integrate(t*(t-t0-tr-tc)/tr ,t, t0+tr+tc, t0+tc+2*tr) + integrate(t, t, t0+tc+2*tr, t0+tr+2*tc) + integrate(t*(t0+2*(tr+tc)-t)/tr, t, t0+tr+2*tc, t0+2*(tr+tc)) ), tc ); float arg= 9.0*M0*M0 + (12.0*Gpos*tr + 16.0*Gpos*t0)*M0 + 4.0*Gpos*Gpos*tr*tr; ODINLOG(odinlog,normalDebug) << "arg=" << arg << STD_endl; float tc1=0.0; float tc2=0.0; if(arg>=0) { tc1=secureDivision(-sqrt(arg) - 3.0*M0 + 2.0*Gpos*tr, 4.0*Gpos); tc2=secureDivision(+sqrt(arg) + 3.0*M0 - 2.0*Gpos*tr, 4.0*Gpos); ODINLOG(odinlog,normalDebug) << "tc1/tc2=" << tc1 << "/" << tc2 << STD_endl; } else { ODINLOG(odinlog,errorLog) << "Cannot solve equation for flow compensation" << STD_endl; } tc=STD_max(tc1,tc2); negfact=secureDivision(Gpos-secureDivision(M0,tc), Gpos); ODINLOG(odinlog,normalDebug) << "negfact=" << negfact << STD_endl; } SeqGradPhaseEncFlowComp::SeqGradPhaseEncFlowComp(const STD_string& object_label, double t0, unsigned int nsteps, float fov, direction gradchannel, float gradstrength, encodingScheme scheme, reorderScheme reorder, unsigned int nsegments, unsigned int reduction, unsigned int acl_bands, float partial_fourier, const STD_string& nucleus) : SeqGradChanList(object_label), simvec(object_label+"_simvec") { // Template for gradient trims SeqGradPhaseEnc petmp(object_label, nsteps, fov, gradchannel, gradstrength, scheme, reorder, nsegments, reduction, acl_bands, partial_fourier, nucleus); // Calculate flow-compensated bipolar gradients float negfact, tc; calc_flowcomp_pe(negfact, tc, petmp.get_strength(), petmp.get_strength()*petmp.get_constduration(), t0, systemInfo->get_max_slew_rate()); pos=SeqGradVectorPulse(object_label+"pos", gradchannel, petmp.get_strength(), petmp.get_trims(), tc); neg=SeqGradVectorPulse(object_label+"neg", gradchannel, petmp.get_strength(), -negfact*petmp.get_trims(), tc); simvec.set_indexvec(((const SeqVector&)petmp).get_indexvec()); // Preserve k-space indices build_seq(); } SeqGradPhaseEncFlowComp& SeqGradPhaseEncFlowComp::operator = (const SeqGradPhaseEncFlowComp& sgpefc) { SeqGradChanList::operator = (sgpefc); pos=sgpefc.pos; neg=sgpefc.neg; simvec=sgpefc.simvec; build_seq(); return *this; } void SeqGradPhaseEncFlowComp::build_seq() { SeqGradChanList::clear(); simvec.clear(); simvec+=pos; simvec+=neg; (*this)+=pos; (*this)+=neg; } odin-1.8.5/odinseq/seqpulsndim.h0000644000175000017500000000656611322062345013571 00000000000000/*************************************************************************** seqpulsndim.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPULSNDIM_H #define SEQPULSNDIM_H #include #include struct SeqPulsNdimObjects; // forward declaration /** * @addtogroup odinseq * @{ */ /** * * \brief RF Pulse + gradients * * This class represents a shaped n-dimesional RF-pulse, i.e. it * consists of a complex waveform and in addition three gradient * waveforms in the three spatial directions that are played out simultaneously */ class SeqPulsNdim : public SeqParallel, public virtual SeqPulsInterface, public Handled { // virtual functions of SeqPulsInterface are marshalled to sp // virtual functions of SeqFreqChanInterface are marshalled to sp public: /** * Default constructor */ SeqPulsNdim(const STD_string& object_label = "unnamedSeqPulsNdim" ); /** * Copy constructor */ SeqPulsNdim(const SeqPulsNdim& spnd); /** * Destructor */ ~SeqPulsNdim(); /** * Sets the RF waveform of the pulse */ SeqPulsNdim& set_rfwave(const cvector& waveform); /** * Sets the waveform for the gradient pulse in direction 'dir' */ SeqPulsNdim& set_gradwave(direction dir, const fvector& waveform); /** * Sets the B1 scaling for simulation */ SeqPulsNdim& set_B1max(float b1max); /** * Returns the complex RF waveform */ cvector get_rfwave() const; /** * Returns the waveform of the gradient pulse in direction 'dir' */ fvector get_gradwave(direction dir) const; /** * Specifies an extra shift between RF and the gradient channels */ SeqPulsNdim& set_grad_shift_offset(float grad_shift_offset); /** * Dimensionality of the pulse */ virtual int get_dims() const; // virtual functions of SeqPulsInterface are (mostly) marshalled to sp, except: SeqPulsInterface& set_pulsduration(float pulsduration); float get_magnetic_center() const; // forwarding virtual functions of SeqVector to sp SeqVector& set_indexvec(const ivector& iv); /** * This assignment operator will make this object become an exact copy of 'spnd'. */ SeqPulsNdim& operator = (const SeqPulsNdim& spnd); /** * Appends the gradient list sgcl to the gradient part of the pulse */ SeqPulsNdim& operator += (SeqGradChanList& sgcl); protected: SeqPulsNdim& set_system_flipangle(float angle); SeqPulsNdim& build_seq(); private: int dims; double gradshift; SeqPulsNdimObjects* objs; }; /** @} */ #endif odin-1.8.5/odinseq/seqgradpulse.h0000644000175000017500000001311411322062345013707 00000000000000/*************************************************************************** seqgradpulse.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADPULSE_H #define SEQGRADPULSE_H #include #include #include #include /** * @addtogroup odinseq * @{ */ ///////////////////////////////////////////////////////////////////////////////// /** * \brief Constant gradient pulse * * This class represents a gradient pulse with a constant gradient field */ class SeqGradConstPulse : public SeqGradChanList { public: /** * Constructs a constant gradient pulse labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradstrength: The gradient strength for this object * - gradduration: The duration of this gradient object */ SeqGradConstPulse(const STD_string& object_label,direction gradchannel, float gradstrength, float gradduration); /** * Constructs a copy of 'sgcp' */ SeqGradConstPulse(const SeqGradConstPulse& sgcp); /** * Construct an empty constant gradient pulse with the given label */ SeqGradConstPulse(const STD_string& object_label = "unnamedSeqGradConstPulse"); /** * Assignment operator that makes this constant gradient pulse object become a copy of 'sgcp' */ SeqGradConstPulse& operator = (const SeqGradConstPulse& sgcp); /** * setting duration of the constant part */ SeqGradConstPulse& set_constduration(float duration) {constgrad.set_duration(duration);return *this;}; /** * getting duration of the constant part */ double get_constduration() const {return constgrad.get_gradduration();} // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); private: SeqGradConst constgrad; SeqGradDelay offgrad; }; ///////////////////////////////////////////////////////////////////////////////// /** * \brief Vector of gradient pulses * * This class represents a gradient pulse with a constant gradient * shape with the the strength taken from a vector. This object * can be attached to a SeqLoop to iterate over the values in the * vector. */ class SeqGradVectorPulse : public SeqGradChanList { public: /** * Constructs a gradient vector pulse labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - maxgradstrength: The maximum gradient strength for this object * - trimarray: The vector of gradient strength values * - gradduration: The duration of this gradient object */ SeqGradVectorPulse(const STD_string& object_label,direction gradchannel, float maxgradstrength, const fvector& trimarray, float gradduration); /** * Constructs a copy of 'sgvp' */ SeqGradVectorPulse(const SeqGradVectorPulse& sgvp); /** * Construct an empty gradient pulse with the given label */ SeqGradVectorPulse(const STD_string& object_label = "unnamedSeqGradVectorPulse"); /** * Assignment operator that makes this constant gradient pulse object become a copy of 'sgvp' */ SeqGradVectorPulse& operator = (const SeqGradVectorPulse& sgvp); /** * Specifies the trim values that will be used */ SeqGradVectorPulse& set_trims(const fvector& trims) { vectorgrad.set_trims(trims); return *this;} /** * Returns the trim values that will be used */ fvector get_trims() const {return vectorgrad.get_trims();} /** * Sets the reordering scheme and the number of segments */ SeqGradVectorPulse& set_reorder_scheme(reorderScheme scheme,unsigned int nsegments=1) {vectorgrad.set_reorder_scheme(scheme,nsegments); return *this;} /** * Sets the phase encoding scheme and the number of phase encoding steps */ SeqGradVectorPulse& set_encoding_scheme(encodingScheme scheme) {vectorgrad.set_encoding_scheme(scheme); return *this;} /** * Returns the reordering vector (for loop insertion) */ const SeqVector& get_reorder_vector() const {return vectorgrad.get_reorder_vector();} /** * setting duration of the gradient vector part */ SeqGradVectorPulse& set_constduration(float duration){vectorgrad.set_duration(duration);return *this;}; /** * getting duration of the gradient vector part */ double get_constduration() const {return vectorgrad.get_gradduration();} /** * conversion operator for loop insertion */ operator const SeqVector& () const {return vectorgrad;} // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); private: friend class SeqGradPhaseEnc; friend class SeqGradEcho; SeqGradVector vectorgrad; SeqGradDelay offgrad; }; /** @} */ #endif odin-1.8.5/odinseq/seqcounter.cpp0000644000175000017500000000511311322062345013733 00000000000000#include "seqcounter.h" SeqCounter::SeqCounter(const STD_string& object_label) : counterdriver(object_label) { disable_counter(); set_label(object_label); } SeqCounter::SeqCounter(const SeqCounter& sc) { disable_counter(); SeqCounter::operator = (sc); } SeqCounter& SeqCounter::operator = (const SeqCounter& sc) { SeqTreeObj::operator = (sc); counterdriver=sc.counterdriver; counterdriver->outdate_cache(); clear_vectorlist(); for(veciter=sc.get_vecbegin(); veciter!=sc.get_vecend(); ++veciter) { add_vector(**veciter); } return *this; } void SeqCounter::set_vechandler_for_all() const { Log odinlog(this,"set_vechandler_for_all"); for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { ODINLOG(odinlog,normalDebug) << "veciter=" << (*veciter)->get_label() << STD_endl; (*veciter)->set_vechandler(this); } return; } bool SeqCounter::prep_veciterations() const { Log odinlog(this,"prep_veciterations"); for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { ODINLOG(odinlog,normalDebug) << "calling prep_iteration of vector " << (*veciter)->get_label() << STD_endl; if(!(*veciter)->prep_iteration()) return false; ODINLOG(odinlog,normalDebug) << "prep done" << STD_endl; } return true; } void SeqCounter::init_counter(unsigned int start) const { set_vechandler_for_all(); int niter=get_times(); if(start && niter>0) counter=start%niter; else counter=0; } void SeqCounter::add_vector(const SeqVector& seqvector) { Log odinlog(this,"add_vector"); if( get_times() && (int(seqvector.get_numof_iterations())!=get_times()) ) { ODINLOG(odinlog,errorLog) << "size mismatch: this=" << get_times() << ", " << seqvector.get_label() << "=" << seqvector.get_numof_iterations() << STD_endl; } else { vectors.append(seqvector); seqvector.set_vechandler(this); seqvector.nr_cache_up2date=false; ODINLOG(odinlog,normalDebug) << "added vector >" << seqvector.get_label() << "<" << STD_endl; } counterdriver->outdate_cache(); } int SeqCounter::get_times() const { Log odinlog(this,"get_times"); if(n_vectors()) { ODINLOG(odinlog,normalDebug) << "vectorsize(" << (*(get_vecbegin()))->get_label() << ")=" << (*(get_vecbegin()))->get_numof_iterations() << STD_endl; return (*(get_vecbegin()))->get_numof_iterations(); } return 0; } bool SeqCounter::prep() { if(!SeqTreeObj::prep()) return false; if(!counterdriver->prep_driver()) return false; return true; } void SeqCounter::clear_container() { clear_vectorlist(); counterdriver->outdate_cache(); } odin-1.8.5/odinseq/seqgradchanlist.h0000644000175000017500000000603411322062345014367 00000000000000/*************************************************************************** seqgradchanlist.h - description ------------------- begin : Thu Apr 22 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADCHANLIST_H #define SEQGRADCHANLIST_H #include /** * @addtogroup odinseq_internals * @{ */ /** * This class represents a list of gradient channel objects (i.e. those derived from SeqGradChan) * It is suitable to hold a gradient train for ONE gradient channel */ class SeqGradChanList : public List, public Handled, public virtual SeqGradInterface, public virtual SeqTreeObj { public: /** * Construct an empty gradient channel list with the given label */ SeqGradChanList(const STD_string& object_label = "unnamedSeqGradChanList" ); /** * Constructs a copy of 'sgcl' */ SeqGradChanList(const SeqGradChanList& sgcl); /** * Destructor */ ~SeqGradChanList(); /** * Assignment operator that makes this gradient sequence object become a copy of 'sgcl' */ SeqGradChanList& operator = (const SeqGradChanList& sgcl); // overloading virtual function from SeqTreeObj double get_duration() const; STD_string get_properties() const; unsigned int event(eventContext& context) const; void query(queryContext& context) const; // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; fvector get_gradintegral() const; double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); /** * Returns the occupied channel */ direction get_channel() const; /** * Appends the elements of 'sgcl' to this */ SeqGradChanList& operator += (SeqGradChanList& sgcl); /** * Appends 'sgc' to this */ SeqGradChanList& operator += (SeqGradChan& sgc); fvector get_switchpoints() const; SeqGradChanList& get_chanlist4gp(const fvector& switchpoints); private: friend class SeqGradChanParallel; // overloading virtual function from SeqClass void clear_container(); SeqGradChan* get_chan(double& chanstart, double midtime); }; /** @} */ #endif odin-1.8.5/odinseq/seqgradconst.h0000644000175000017500000000737511322062345013721 00000000000000/*************************************************************************** seqgradconst.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADCONST_H #define SEQGRADCONST_H #include /** * @addtogroup odinseq * @{ */ /** * \brief Constant gradient * * This class represents a gradient object with a constant gradient field */ class SeqGradConst : public SeqGradChan { public: /** * Constructs a constant gradient field labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradstrength: The gradient strength for this object * - gradduration: The duration of this gradient object */ SeqGradConst(const STD_string& object_label,direction gradchannel, float gradstrength, double gradduration); /** * Constructs a copy of 'sgc' */ SeqGradConst(const SeqGradConst& sgc); /** * Construct an empty gradient object with the given label */ SeqGradConst(const STD_string& object_label = "unnamedSeqGradConst" ); /** * Assignment operator that makes this gradient channel object become a copy of 'sgc' */ SeqGradConst& operator = (const SeqGradConst& sgc); private: friend class SeqGradVector; // overwriting virtual functions from SeqClass bool prep(); // overwriting virtual functions from SeqGradChan SeqGradChan& get_subchan(double starttime, double endtime) const; STD_string get_grdpart(float matrixfactor) const; float get_integral() const {return get_strength() * get_duration();} }; ////////////////////////////////////////////////////////////////////////////////// /** * \brief Gradient delay * * This class represents a gradient delay which can be inserted into a list of gradient objects */ class SeqGradDelay : public SeqGradChan { public: /** * Constructs a constant gradient field labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradduration: The duration of this gradient object */ SeqGradDelay(const STD_string& object_label, direction gradchannel, double gradduration); /** * Constructs a copy of 'sgd' */ SeqGradDelay(const SeqGradDelay& sgd); /** * Construct an empty gradient object with the given label */ SeqGradDelay(const STD_string& object_label = "unnamedSeqGradDelay" ); /** * Assignment operator that makes this gradient channel object become a copy of 'sgd' */ SeqGradDelay& operator = (const SeqGradDelay& sgd); // overwriting virtual functions from SeqGradInterface float get_strength() const {return 0.0;} // always return zero strength private: // overwriting virtual functions from SeqGradChan SeqGradChan& get_subchan(double starttime, double endtime) const; STD_string get_grdpart(float matrixfactor) const; float get_integral() const {return 0.0;} }; /** @} */ #endif odin-1.8.5/odinseq/seqgrad.cpp0000644000175000017500000000027511322062345013175 00000000000000#include "seqgrad.h" float SeqGradInterface::get_gradintegral_norm() const { fvector intgegralvec=get_gradintegral(); return norm3(intgegralvec[0],intgegralvec[1],intgegralvec[2]); } odin-1.8.5/odinseq/seqgradspiral.h0000644000175000017500000001016411735132611014055 00000000000000/*************************************************************************** seqgradspiral.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADSPIRAL_H #define SEQGRADSPIRAL_H #include #include #include #include #include #include /** * @addtogroup odinseq_internals * @{ */ /** * Spiral Gradients */ class SeqGradSpiral: public SeqGradChanParallel, public MinimizationFunction { public: /** * Constructs a spiral gradient labeled 'object_label' and the * following properties: * - traj: The spiral trajectory (will be modified, if neccessary) * - dt: The dwell time * - resolution: Spatial resolution * - sizeRadial: The number of image points in radial direction * - numofSegments : The number of spiral interleaves * - inwards: Reverse trajectory so that the spiral ends in the center of k-space, in addition, rotates trajectory by 180 deg * - optimize: Optimize trajectory for minimum readout length if trajectory has a free tunable parameter * - nucleus: The imaging nucleus */ SeqGradSpiral(const STD_string& object_label, JDXtrajectory& traj, double dt, float resolution, unsigned int sizeRadial, unsigned int numofSegments, bool inwards=false, bool optimize=false, const STD_string& nucleus=""); /** * Constructs an empty spiral gradient with the given label. */ SeqGradSpiral(const STD_string& object_label = "unnamedSeqGradSpiral" ); /** * Constructs a spiral gradient which is a copy of 'sgs' */ SeqGradSpiral(const SeqGradSpiral& sgs); /** * This assignment operator will make this object become an exact copy of 'sgs'. */ SeqGradSpiral& operator = (const SeqGradSpiral& sgs); /** * Returns the size of the spiral without ramps */ unsigned int spiral_size() const {return denscomp.size();} /** * Returns the duration of the ramp that switches the gradients off */ double get_ramp_duration() const {return (get_gradduration()-spiral_dur);} /** * Sets the delay of the gradient delays preceding the spiral gradients */ SeqGradSpiral& set_predelay_duration(double dur); /** * Returns the Jacobian determinante, i.e. the correction function * for non-uniform weighting of k-space */ const fvector& get_denscomp() const {return denscomp;} /** * Returns the k-space trajectory for the interleave 'iseg' and the given channel */ fvector get_ktraj(direction channel) const; private: void common_init() {traj_cache=0;} void build_seq(); float readout_npts() const; // implement virtual functions of MinimizationFunction to minimize readout duration float evaluate(const fvector& spirpar) const; unsigned int numof_fitpars() const {return 1;} SeqGradWave gx; SeqGradWave gy; SeqGradDelay gxdelay; SeqGradDelay gydelay; fvector kx; fvector ky; fvector denscomp; double spiral_dur; double predelay; // cache values for readout_npts/evaluate JDXtrajectory* traj_cache; double dt_cache; float resolution_cache; unsigned int sizeRadial_cache; float gamma_cache; }; ////////////////////////////////////////////////////////////////////////////////////////// /** @} */ #endif odin-1.8.5/odinseq/seqcmdline.cpp0000644000175000017500000001663011322062345013675 00000000000000#include "seqcmdline.h" #include "seqmeth.h" #include "seqplatform.h" #include #ifndef NO_CMDLINE class SeqTreeCallbackConsole : public SeqTreeCallbackAbstract { public: SeqTreeCallbackConsole() {} private: // implementing virtual function of SeqTreeCallbackAbstract void display_node(const SeqClass* thisnode, const SeqClass* parentnode, int treelevel, const svector& columntext) { STD_string space = ""; for (int i = 0; i<(treelevel-1); i++) space+="| "; if(treelevel>0) space+="|- "; STD_cout << space; for(unsigned int icol=0; icol odinlog("SeqCmdLine","process"); SeqMethodProxy method; SeqPlatformProxy platform; char value[ODIN_MAXCHAR]; bool valid_command=false; // try to find a suitable platform to switch to #ifdef STANDALONE_PLUGIN platform.set_current_platform(standalone); // default #else #ifdef PARAVISION_PLUGIN platform.set_current_platform(paravision); #else #ifdef IDEA_PLUGIN platform.set_current_platform(numaris_4); #else #ifdef EPIC_PLUGIN platform.set_current_platform(epic); #else #error No valid platform plugin available #endif #endif #endif #endif JDXfileName methlabel(argv[0]); // do we have at least one action argument ? if (argc<2) { STD_cout << usage(methlabel.get_basename(),method->get_description()) << STD_endl; return 0; } // switch on error tracing // set_tracing(Error); // setting up stuff for different test cases of seqtest // do this before anything else if(getCommandlineOption(argc,argv,"-testcase",value,ODIN_MAXCHAR)) { int testcase=atoi(value); ODINLOG(odinlog,normalDebug) << "testcase=" << testcase << STD_endl; method->set_current_testcase(testcase); if(testcase) { STD_string newlabel(method->get_label()); if(newlabel.length()) newlabel[newlabel.length()-1]=char('0'+testcase); method->set_label(newlabel); } } if(!method->init()) { ODINLOG(odinlog,errorLog) << "method->init() failed" << STD_endl; return -1; } STD_string action(argv[1]); // switch to platform which offers the requested action int pfact=platform.get_platform_for_action(action); ODINLOG(odinlog,normalDebug) << "action/pfact=" << action << "/" << pfact << STD_endl; if(pfact>=0) platform.set_current_platform(odinPlatform(pfact)); else platform.set_current_platform(standalone); // used as default for non-platform-specific actions STD_string scandir="."; if(getCommandlineOption(argc,argv,"-scandir",value,ODIN_MAXCHAR)) { scandir=value; ODINLOG(odinlog,normalDebug) << "scandir=" << scandir << STD_endl; } SystemInterface()->set_scandir(scandir); // analyze command line options and perform the requested action: if(action=="description") { STD_cout << methlabel.get_basename()<< STD_endl << justificate(method->get_description()) << STD_endl; valid_command=true; } if(action=="ntests") { STD_cout << method->numof_testcases() << STD_endl; exit(0); } if(action=="events") { if(getCommandlineOption(argc,argv,"-p",value,ODIN_MAXCHAR)) method->load_protocol(value); if(method->prepare()) { eventContext context; context.action=printEvent; SeqTreeCallbackConsole display; context.event_display=&display; STD_cout << "---------- Events: -------------------" << STD_endl; method->event(context); STD_cout << STD_endl; } else { ODINLOG(odinlog,errorLog) << "method->prepare() failed" << STD_endl; return -1; } valid_command=true; } if(action=="tree") { if(getCommandlineOption(argc,argv,"-p",value,ODIN_MAXCHAR)) method->load_protocol(value); if(method->build()) { SeqTreeCallbackConsole display; method->tree(&display); } else { ODINLOG(odinlog,errorLog) << "method->build() failed" << STD_endl; return -1; } valid_command=true; } if(!valid_command) { ODINLOG(odinlog,normalDebug) << "handind over control to platform" << STD_endl; int result=platform->process(argc,argv); ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; if(result<0) return -1; if(result>0) valid_command=true; } ODINLOG(odinlog,normalDebug) << "valid_command=" << valid_command << STD_endl; if(!valid_command) { JDXfileName methlabel(argv[0]); STD_cout << usage(methlabel.get_basename(),method->get_description()) << STD_endl; return -1; } // clean up SeqMethodProxy::delete_methods(); #endif return 0; // return 0 to shell on success } STD_string SeqCmdLine::usage(const STD_string& meth, const STD_string& description) { STD_string result; #ifndef NO_CMDLINE STD_string separator=n_times(" ",USAGE_INDENTION_FACTOR); result+="\nODIN method: "+meth+"\n\n"; result+="DESCRIPTION:\n"+justificate(description,USAGE_INDENTION_FACTOR)+"\n\n"; result+="USAGE:"+separator+meth+" action [options]"+"\n"; result+=separator+"where 'action' can be one of the following:\n\n"; SeqCmdlineActionList global_actions; SeqCmdlineAction descr("description","Prints a description of sequence."); global_actions.push_back(descr); SeqCmdlineAction ntests("ntests","Prints number of test cases. Exits immediately thereafter."); global_actions.push_back(ntests); SeqCmdlineAction events("events","Prints all events in the sequence. "); events.add_opt_arg("p","The file with the measurement protocol"); global_actions.push_back(events); SeqCmdlineAction tree("tree","Prints the tree of sequence objects. "); tree.add_opt_arg("p","The file with the measurement protocol"); global_actions.push_back(tree); result+="GLOBAL ACTIONS:\n\n"; result+=format_actions(global_actions); result+=SeqPlatformProxy::get_platforms_usage(); result+="ADDITIONAL OPTIONS:\n\n"; #ifdef ODIN_DEBUG result+=justificate(LogBase::get_usage(),USAGE_INDENTION_FACTOR)+"\n"; #endif result+=justificate("-scandir : Sets the directory where experimental data is stored.",USAGE_INDENTION_FACTOR)+"\n"; result+=justificate("-testcase : Uses the default sequence parameters from the given test case.",USAGE_INDENTION_FACTOR)+"\n"; result+="\n"; #endif return result; } STD_string SeqCmdLine::format_actions(const SeqCmdlineActionList& actions) { STD_string result; #ifndef NO_CMDLINE STD_string separator=n_times(" ",USAGE_INDENTION_FACTOR); STD_string argline; STD_map::const_iterator argit; for(STD_list::const_iterator it=actions.begin(); it!=actions.end(); ++it) { result+=separator+it->action+"\n"; result+=justificate(it->description,USAGE_INDENTION_FACTOR); if(it->req_args.size()) result+=separator+"Required arguments:\n"; for(argit=it->req_args.begin(); argit!=it->req_args.end(); ++argit) { argline=separator+"-"+argit->first+" <"+argit->second+">"; result+=separator+justificate(argline,USAGE_INDENTION_FACTOR,true); } if(it->opt_args.size()) result+=separator+"Optional arguments:\n"; for(argit=it->opt_args.begin(); argit!=it->opt_args.end(); ++argit) { argline=separator+"-"+argit->first+" <"+argit->second+">\n"; result+=separator+justificate(argline,USAGE_INDENTION_FACTOR,true); } result+="\n"; } #endif return result; } odin-1.8.5/odinseq/seqgradchan.h0000644000175000017500000001425711322062345013501 00000000000000/*************************************************************************** seqgradchan.h - description ------------------- begin : Mon Aug 19 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADCHAN_H #define SEQGRADCHAN_H #include #include #include #include #define _GRADROTMATRIX_LIMIT_ 1.0e-5 /** * @addtogroup odinseq_internals * @{ */ /** * The base class for platform specific drivers of gradient channel objects */ class SeqGradChanDriver : public SeqDriverBase { public: SeqGradChanDriver() {} virtual ~SeqGradChanDriver() {} virtual STD_string get_const_program (float strength, float matrixfactor) const = 0; virtual STD_string get_onepoint_program(float strength, float matrixfactor) const = 0; virtual STD_string get_delay_program (float strength, float matrixfactor) const = 0; virtual STD_string get_wave_program (float strength, float matrixfactor) const = 0; virtual STD_string get_trapez_program (float strength, float matrixfactor) const = 0; virtual STD_string get_vector_program (float strength, float matrixfactor, int reordercount) const = 0; virtual svector get_vector_commands(const STD_string& iterator) const = 0; virtual svector get_reord_commands() const = 0; virtual bool prep_const(float strength, const fvector& strengthfactor, double gradduration) = 0; virtual bool prep_onepoint(float strength, const fvector& strengthfactor, double gradduration) = 0; virtual bool prep_wave(float strength, const fvector& strengthfactor, double gradduration, const fvector& wave) = 0; virtual void update_wave(const fvector& wave) = 0; virtual bool prep_vector(float strength, const fvector& strengthfactor, double gradduration, const fvector& gradvec, const iarray& index_matrix, nestingRelation nr) = 0; virtual bool prep_vector_iteration(unsigned int count) = 0; virtual bool prep_trapez(float strength, const fvector& strengthfactor, double ruptime, const fvector& rupshape, double consttime, double rdowntime, const fvector& rdownshape) = 0; virtual void event(eventContext& context, double starttime) const = 0; virtual float check_strength(float strength) const = 0; virtual SeqGradChanDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////////////////////// /** * This is the base class for all objects that represent a single gradient object */ class SeqGradChan : public virtual SeqGradInterface, public ListItem, public SeqDur { public: /** * Constructs a gradient channel object labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradstrength: The gradient strength for this object * - gradduration: The duration of this gradient object */ SeqGradChan(const STD_string& object_label,direction gradchannel, float gradstrength, double gradduration); /** * Construct an empty gradient channel object with the given label */ SeqGradChan(const STD_string& object_label = "unnamedSeqGradChan" ); /** * Constructs a copy of 'sgc' */ SeqGradChan(const SeqGradChan& sgc); /** * Destructor */ virtual ~SeqGradChan() {} /** * Assignment operator that makes this gradient channel object become a copy of 'sgc' */ SeqGradChan& operator = (const SeqGradChan& sgc); /** * Returns the occupied channel */ virtual direction get_channel() const; /** * Overload this function to return the size of the used waveform, if any */ virtual int get_wavesize() const {return 0;} /** * Overload this function to resize the current waveform, if any */ virtual void resize(unsigned int newsize) {} // overwriting virtual functions from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; double get_gradduration() const {return get_duration();} SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); fvector get_gradintegral() const; // overwriting virtual functions from SeqTreeObj STD_string get_properties() const; unsigned int event(eventContext& context) const; STD_string get_grdpart_rot(direction chan) const; protected: /** * returns element [channel][chan] val. from the current rot. Matrix */ float get_grdfactor(direction chan) const; /** * returns element [channel][chan] val. from the current rot. Matrix without considering * the rotation matrix of the current event block (for IDEA) */ fvector get_grdfactors_norot() const; mutable SeqDriverInterface graddriver; private: friend class SeqGradChanList; friend class SeqGradChanParallel; /** * Overload this function to return a cut-out of this object in the interval [starttime,endtime] */ virtual SeqGradChan& get_subchan(double starttime, double endtime) const = 0; /** * Overload this function to return this objects part in the (gradient) program */ virtual STD_string get_grdpart(float matrixfactor) const = 0; /** * Overload this function to returns this objects gradient integral */ virtual float get_integral() const = 0; RotMatrix get_total_rotmat() const; float strength; direction channel; // Do not change this once it it is initialised RotMatrix gradrotmatrix; }; /** @} */ #endif odin-1.8.5/odinseq/seqsat.cpp0000644000175000017500000001253611322062345013052 00000000000000#include "seqsat.h" SeqPulsarSat::SeqPulsarSat(const STD_string& object_label,satNucleus nuc,float bandwidth) : SeqPulsar(object_label,false,false) { Log odinlog(this,"SeqPulsarSat"); double offset_ppm=0.0; if(nuc==fat) offset_ppm=-3.28; double offset_freq=systemInfo->get_nuc_freq("")*offset_ppm*1.0e-6; set_dim_mode(zeroDeeMode); ODINLOG(odinlog,normalDebug) << "offset_freq=" << offset_freq << STD_endl; set_Tp(secureDivision(3.0,bandwidth)); resize(128); SeqPulsar::set_flipangle(114.0); // flipangle determined experimentally with oil phantom (do NOT call virtual function in constructor) set_shape("Const"); set_trajectory("Const(0.0,1.0)"); set_filter("Gauss"); set_freqoffset( offset_freq ); SeqPulsar::set_pulse_type(saturation); // do NOT call virtual function in constructor refresh(); set_interactive(true); } SeqPulsarSat::SeqPulsarSat(const STD_string& object_label,float bandwidth, double freqoffset, float flipangle, float rel_filterwidth) : SeqPulsar(object_label,false,false) { Log odinlog(this,"SeqPulsarSat"); ODINLOG(odinlog,normalDebug) << "SeqPulsarSat.." << STD_endl; double effectiv_bandwidth; ODINLOG(odinlog,normalDebug) << "SeqPulsarSat bandwidth/ satoffset_freq / flipangle / rel_filterwidth" <get_max_grad(),2.0), spoiler_slice_neg(object_label+"_spoiler_slice_neg",sliceDirection,-0.6*systemInfo->get_max_grad(),2.0), spoiler_read_neg(object_label+"_spoiler_read_neg",readDirection,-0.6*systemInfo->get_max_grad(),2.0), spoiler_slice_pos(object_label+"_spoiler_slice_pos",sliceDirection,0.6*systemInfo->get_max_grad(),2.0), spoiler_phase_pos(object_label+"_spoiler_phase_pos",phaseDirection,0.6*systemInfo->get_max_grad(),2.0), npulses_cache(npulses) { SeqPulsInterface::set_marshall(&puls); SeqFreqChanInterface::set_marshall(&puls); build_seq(); } SeqSat::SeqSat(const SeqSat& spg) { SeqPulsInterface::set_marshall(&puls); SeqFreqChanInterface::set_marshall(&puls); SeqSat::operator = (spg); } SeqSat& SeqSat::operator = (const SeqSat& spg) { SeqObjList::operator = (spg); puls=spg.puls; spoiler_read_pos=spg.spoiler_read_pos; spoiler_slice_neg=spg.spoiler_slice_neg; spoiler_read_neg=spg.spoiler_read_neg; spoiler_slice_pos=spg.spoiler_slice_pos; spoiler_phase_pos=spg.spoiler_phase_pos; npulses_cache=spg.npulses_cache; build_seq(); return *this; } void SeqSat::build_seq() { clear(); (*this)+=(spoiler_read_pos/spoiler_slice_neg); for(unsigned int i=0; i #include #include #include #include #include #include struct SeqFieldMapPars { JcampDxBlock parblock; JDXint NumOfEchoes; JDXfloat Resolution; JDXdouble T1Ernst; JDXint DummyCycles; JDXint ReadSize; JDXint PhaseSize; JDXint SliceSize; JDXdouble FlashFlipAngle; JDXdouble ExtraDelay; }; struct SeqFieldMapObjects { SeqPulsar exc; SeqAcqEPI epi; SeqAcqDeph deph; SeqGradPhaseEnc pe3d; SeqGradConstPulse crusher; SeqDelay extradelay; SeqObjList pepart; SeqObjLoop peloop; SeqObjLoop peloop3d; SeqObjLoop sliceloop; SeqDelay acqdummy; SeqObjLoop dummyloop; }; void SeqFieldMap::alloc_data() { if(!pars) pars=new SeqFieldMapPars; if(!objs) objs=new SeqFieldMapObjects; } SeqFieldMap::~SeqFieldMap() { if(pars) delete pars; if(objs) delete objs; } void SeqFieldMap::init(const STD_string& objlabel) { alloc_data(); set_label(objlabel); pars->parblock.set_embedded(false).set_label(objlabel+"_parblock"); pars->parblock.clear(); pars->NumOfEchoes.set_description("Number of ecoes for fieldmap calculation").set_label("NumOfEchoes"); pars->NumOfEchoes=8; pars->parblock.append(pars->NumOfEchoes); pars->Resolution.set_description("Spatial in-plane resolution").set_unit(ODIN_SPAT_UNIT).set_label("Resolution"); pars->Resolution=3.0; pars->parblock.append(pars->Resolution); pars->T1Ernst.set_description("For optimum SNR, the flip angle will be set to the Ernst angle using this T1").set_unit(ODIN_TIME_UNIT).set_label("T1Ernst"); pars->T1Ernst=1300.0; pars->parblock.append(pars->T1Ernst); pars->DummyCycles.set_description("Number of dummy repetions").set_label("DummyCycles"); pars->DummyCycles=3; pars->parblock.append(pars->DummyCycles); pars->ExtraDelay.set_description("Extra TR delay").set_unit(ODIN_TIME_UNIT).set_label("ExtraDelay"); pars->parblock.append(pars->ExtraDelay); pars->FlashFlipAngle.set_description("Flip-angle of excitation pulse").set_parmode(noedit).set_label("FlashFlipAngle"); pars->parblock.append(pars->FlashFlipAngle); pars->ReadSize.set_description("Size in read direction").set_parmode(noedit).set_label("ReadSize"); pars->parblock.append(pars->ReadSize); pars->PhaseSize.set_description("Size in phase direction").set_parmode(noedit).set_label("PhaseSize"); pars->parblock.append(pars->PhaseSize); pars->SliceSize.set_description("Size in slice direction").set_parmode(noedit).set_label("SliceSize"); pars->parblock.append(pars->SliceSize); } void SeqFieldMap::build_seq(double sweepwidth, float os_factor, const SeqObjList& prep, double min_relaxdelay) { alloc_data(); STD_string objlabel(get_label()); if(geometryInfo->get_Mode()==voxel_3d) { // Same settings as in swi sequence float spatres=3.0; float slicethick=geometryInfo->get_FOV(sliceDirection)-2.0*spatres; if(slicethickexc=SeqPulsarSinc(objlabel+"_exc", slicethick, true, 4.0, 90.0, spatres, 512); // flip angle will be adjusted later objs->exc.set_filter("Gauss"); objs->exc.set_freqoffset(systemInfo->get_gamma() * objs->exc.get_strength() / (2.0*PII) * geometryInfo->get_offset(sliceDirection) ); } else { objs->exc=SeqPulsarSinc(objlabel+"_exc",geometryInfo->get_sliceThickness()); objs->exc.set_freqlist( systemInfo->get_gamma() * objs->exc.get_strength() / (2.0*PII) * geometryInfo->get_sliceOffsetVector() ); } objs->exc.set_pulse_type(excitation); pars->ReadSize= int(secureDivision(geometryInfo->get_FOV(readDirection) ,pars->Resolution)+0.5); pars->PhaseSize=int(secureDivision(geometryInfo->get_FOV(phaseDirection),pars->Resolution)+0.5); if(geometryInfo->get_Mode()==voxel_3d) { pars->SliceSize=int(secureDivision(geometryInfo->get_FOV(sliceDirection),pars->Resolution)+0.5); } else { pars->SliceSize=1; } if(pars->NumOfEchoes%2) pars->NumOfEchoes++; objs->epi=SeqAcqEPI(objlabel+"_epi",sweepwidth, pars->ReadSize,geometryInfo->get_FOV(readDirection), pars->PhaseSize,geometryInfo->get_FOV(phaseDirection), pars->PhaseSize,1,os_factor,"",0,0,linear,false,1.0,0.0,pars->NumOfEchoes/2); objs->epi.set_template_type(fieldmap_template); objs->deph=SeqAcqDeph(objlabel+"_deph",objs->epi,FID); // Does the phase encoding in one dimension objs->pepart=SeqObjList(objlabel+"_pepart"); if(geometryInfo->get_Mode()==voxel_3d) { objs->pe3d=SeqGradPhaseEnc(objlabel+"_pe3d",pars->SliceSize,geometryInfo->get_FOV(sliceDirection),sliceDirection,0.25*systemInfo->get_max_grad()); objs->pepart=objs->deph/objs->pe3d; } else { objs->pepart=objs->deph; } double crusher_strength=0.4*systemInfo->get_max_grad(); double crusher_integral=2.0*fabs(objs->deph.get_gradintegral().sum()); double crusher_dur=secureDivision(crusher_integral,crusher_strength); objs->crusher=SeqGradConstPulse(objlabel+"_crusher",readDirection,crusher_strength,crusher_dur); pars->ExtraDelay=STD_max(double(pars->ExtraDelay),min_relaxdelay); objs->extradelay=SeqDelay(objlabel+"_extradelay",pars->ExtraDelay); double readoutdur = objs->pepart.get_duration() + objs->epi.get_duration(); double kerneldur = prep.get_duration()+objs->exc.get_duration()+readoutdur+objs->crusher.get_duration()+objs->extradelay.get_duration(); float TR=double(geometryInfo->get_nSlices())*kerneldur; pars->FlashFlipAngle=180.0/PII * acos( exp ( -secureDivision ( TR, pars->T1Ernst) ) ); objs->exc.set_flipangle( pars->FlashFlipAngle ); objs->acqdummy=SeqDelay(objlabel+"_acqdummy",readoutdur); objs->peloop=SeqObjLoop(objlabel+"_peloop"); objs->peloop3d=SeqObjLoop(objlabel+"_peloop3d"); objs->sliceloop=SeqObjLoop(objlabel+"_sliceloop"); objs->dummyloop=SeqObjLoop(objlabel+"_dummyloop"); SeqObjList::clear(); if(pars->DummyCycles>0) { (*this)+= (objs->dummyloop) ( (objs->sliceloop) ( prep + objs->exc + objs->acqdummy + objs->crusher + objs->extradelay )[objs->exc] )[pars->DummyCycles]; } if(geometryInfo->get_Mode()==voxel_3d) { (*this)+= (objs->peloop3d) ( (objs->peloop) ( prep + objs->exc + objs->pepart + objs->epi + objs->crusher + objs->extradelay )[objs->deph.get_epi_segment_vector()] )[objs->pe3d]; objs->epi.set_reco_vector(line3d,objs->pe3d); } else { (*this)+= (objs->peloop) ( (objs->sliceloop) ( prep + objs->exc + objs->pepart + objs->epi + objs->crusher + objs->extradelay )[objs->exc] )[objs->deph.get_epi_segment_vector()]; objs->epi.set_reco_vector(slice,objs->exc); } // objs->epi.set_te_offset(objs->exc.get_duration()-objs->exc.get_magnetic_center()+objs->pepart.get_duration()); } JcampDxBlock& SeqFieldMap::get_parblock() { alloc_data(); return pars->parblock; } odin-1.8.5/odinseq/seqveciter.cpp0000644000175000017500000000557211455553540013737 00000000000000#include "seqveciter.h" #include "seqdelay.h" SeqVecIter::SeqVecIter(const STD_string& object_label, unsigned int start) : SeqCounter(object_label), SeqObjBase(object_label), startindex(start) { } SeqVecIter::SeqVecIter(const SeqVecIter& svi) : startindex(0) { SeqVecIter::operator = (svi); } SeqVecIter& SeqVecIter::operator = (const SeqVecIter& svi) { SeqCounter::operator = (svi); SeqObjBase::operator = (svi); startindex=svi.startindex; return *this; } STD_string SeqVecIter::get_program(programContext& context) const { counterdriver->outdate_cache(); counterdriver->update_driver(this,0,&vectors); return counterdriver->get_program_iterator(context); } double SeqVecIter::get_duration() const { counterdriver->update_driver(this,0,&vectors); return counterdriver->get_postduration_inloop(); } unsigned int SeqVecIter::event(eventContext& context) const { Log odinlog(this,"event"); unsigned int result=0; counterdriver->update_driver(this,0,&vectors); if(context.action==seqRun) { if(!context.seqcheck ) { // do not increment in test run increment_counter(); if(get_counter()>=get_times()) init_counter(); // cyclical iteration } // prep next iteration counterdriver->pre_vecprepevent(context); prep_veciterations(); counterdriver->post_vecprepevent(context,-1); } double iteratordur=counterdriver->get_postduration_inloop(); if(iteratordur) { SeqDelay sd("iteratordur",iteratordur); result+=sd.event(context); } return result; } STD_string SeqVecIter::get_properties() const { return "VecSize="+itos(get_times())+", NumOfVectors="+itos(n_vectors())+", "+SeqObjBase::get_properties(); } bool SeqVecIter::is_acq_iterator() const { Log odinlog(this,"is_acq_iterator"); bool result=false; for(veciter=get_vecbegin(); veciter!=get_vecend(); ++veciter) { if((*veciter)->is_acq_vector()) { result=true; ODINLOG(odinlog,normalDebug) << "detected acq iterator" << STD_endl; break; } } return result; } void SeqVecIter::query(queryContext& context) const { Log odinlog(this,"query"); SeqCounter::query(context); // default if(context.action==check_acq_iter) context.check_acq_iter_result=is_acq_iterator(); } RecoValList SeqVecIter::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { Log odinlog(this,"get_recovallist"); RecoValList dummy; if(is_acq_iterator()) { counterdriver->update_driver(this,0,&vectors); increment_counter(); if(get_counter()>=get_times()) init_counter(); // cyclical iteration // prep next iteration prep_veciterations(); } return dummy; } bool SeqVecIter::prep() { if(!SeqObjBase::prep()) return false; if(!SeqCounter::prep()) return false; init_counter(startindex); // set to first element if(!prep_veciterations()) return false;; // prep 1st iteration return true; } odin-1.8.5/odinseq/seqgradecho.h0000644000175000017500000002165311455553540013515 00000000000000/*************************************************************************** seqgradecho.h - description ------------------- begin : Mon Feb 17 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADECHO_H #define SEQGRADECHO_H #include #include #include #include #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Gradient echo module * * A gradient echo module (excitation pulse + phase encoding + frequency encoding). * This is a convenience class which groups a number of low-level sequence * objects together. All objects necessary to produce a gradient echo are part * of this class, except the excitation pulse. The latter is passed per reference * (no copy is created within the module, it uses a safe pointer to the pulse). * */ class SeqGradEcho : public SeqObjList, public virtual SeqGradInterface, public virtual SeqAcqInterface { // virtual functions of SeqFreqChanInterface are marhshalled to acqread public: /** * Constructs a 2D (i.e. multi-slice) gradient echo module labeled 'object_label' with the following properties: * - exc: The excitation pulse * - sweepwidth: The sampling frequency * - readnpts: Matrix size in frequency-encoding direction * - FOVread: The FOV in frequency-encoding direction * - phasenpts: Matrix size in phase-encoding direction * - FOVphase: The FOV in phase-encoding direction * - scheme: The phase encoding scheme * - reorder: The reordering scheme * - nsegments: The number of segments for segmented reordering * - reduction: Reduction factor for parallel imaging (sparsely sampled k-space) * - acl_bands: Number of autocalibration bands (bunch of adjacent lines between actual k-space lines) for GRAPPA * - balanced: Whether rephasers (+ exc dephaser) should be added after acquisition, suitable for SSFP sequences * - partial_fourier_phase: The amount of partial Fourier undersampling in phase encoding direction (0=no undersampling, 1=half fourier) * - partial_fourier_read: The amount of partial Fourier undersampling in readout direction (0=no undersampling, 1=half fourier) * - partial_fourier_read_at_end: If set to 'true', partial Fourier will omit data at the end of the readout * - os_factor: The oversampling factor, os_factor=1 means no oversampling * - nucleus: The nucleus to observe */ SeqGradEcho(const STD_string& object_label, SeqPulsar& exc, double sweepwidth, unsigned int readnpts, float FOVread, unsigned int phasenpts, float FOVphase, encodingScheme scheme=linearEncoding, reorderScheme reorder=noReorder, unsigned int nsegments=1, unsigned int reduction=1, unsigned int acl_bands=DEFAULT_ACL_BANDS, bool balanced=false, float partial_fourier_phase=0.0, float partial_fourier_read=0.0, bool partial_fourier_read_at_end=false, float os_factor=1.0, const STD_string& nucleus=""); /** * Constructs a gradient echo module labeled 'object_label' for 3D imaging with the following properties: * - readnpts: Matrix size in frequency-encoding direction * - FOVread: The FOV in frequency-encoding direction * - phasenpts: Matrix size in phase-encoding direction * - FOVphase: The FOV in phase-encoding direction * - slicenpts: Matrix size in the 2nd phase-encoding (slice) direction * - FOVslice: The FOV in the 2nd phase-encoding (slice) direction * - exc: The excitation pulse * - sweepwidth: The sampling frequency * - reduction: Reduction factor for parallel imaging (sparsely sampled k-space), the factor applies to both phase-encoding directions * - acl_bands: Number of autocalibration bands (bunch of adjacent lines between actual k-space lines) for GRAPPA * - balanced: Whether rephasers (+ exc dephaser) should be added after acquisition, suitable for SSFP sequences * - partial_fourier_phase: The amount of partial Fourier undersampling in phase encoding direction (0=no undersampling, 1=half fourier) * - partial_fourier_read: The amount of partial Fourier undersampling in readout direction (0=no undersampling, 1=half fourier) * - partial_fourier_read_at_end: If set to 'true', partial Fourier will omit data at the end of the readout * - os_factor: The oversampling factor, os_factor=1 means no oversampling * - nucleus: The nucleus to observe */ SeqGradEcho(const STD_string& object_label, unsigned int readnpts, float FOVread, unsigned int phasenpts, float FOVphase, unsigned int slicenpts, float FOVslice, SeqPulsar& exc, double sweepwidth, unsigned int reduction=1, unsigned int acl_bands=DEFAULT_ACL_BANDS, bool balanced=false, float partial_fourier_phase=0.0, float partial_fourier_read=0.0, bool partial_fourier_read_at_end=false, float os_factor=1.0, const STD_string& nucleus=""); /** * Constructs an empty SeqGradEcho */ SeqGradEcho(const STD_string& object_label="unnamedSeqGradEcho"); /** * Constructs a copy of 'sge' */ SeqGradEcho(const SeqGradEcho& sge); /** * Assignment operator that makes this object become a copy of 'sge' */ SeqGradEcho& operator = (const SeqGradEcho& sge); /** * Returns the phase encoding vector as a sequence object (for loop insertion) */ SeqVector& get_pe_vector(); /** * Sets the reordering scheme and the number of segments for phase encoding */ SeqGradEcho& set_pe_reorder_scheme(reorderScheme scheme,unsigned int nsegments); /** * Returns the phase encoding reordering vector (for loop insertion) */ const SeqVector& get_pe_reorder_vector() const; /** * Returns the 2nd phase encoding vector as a sequence object (for loop insertion) */ SeqVector& get_pe3d_vector(); /** * Returns the excitation pulse as a sequence object (for loop insertion) */ const SeqVector& get_exc_vector() const {return *pulsptr.get_handled();} /** * Sets the reordering scheme for the frequency list of the excitation pulse */ SeqGradEcho& set_freq_reorder_scheme(reorderScheme scheme,unsigned int nsegments=1) {(*pulsptr.get_handled()).set_reorder_scheme(scheme,nsegments); return *this;} /** * Returns the reorder vector for the frequency list of the excitation pulse (for loop insertion) */ const SeqVector& get_freq_reorder_vector() const {return (*pulsptr.get_handled()).get_reorder_vector();} /** * Returns the echo time (from the middle of excitation pulse to the middle of the acquisition window) */ double get_echo_time() const; /** * Places an additional sequence object between excitation and readout */ SeqGradEcho& set_midpart(const SeqObjBase& soa); // implementing virtual functions of SeqGradInterface SeqGradInterface& set_strength(float gradstrength) {return *this;} // nothing useful float get_strength() const {return 0.0;} // nothing useful SeqGradInterface& invert_strength(); double get_gradduration() const {return get_duration();} SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); fvector get_gradintegral() const; // marshalling virtual functions of SeqAcqInterface to acqread, except: double get_acquisition_center() const {return get_preacq()+acqread.get_acquisition_center();} double get_acquisition_start() const {return get_preacq()+acqread.get_acquisition_start();} SeqAcqInterface& set_template_type(templateType type); private: double get_preacq() const; void common_init(const STD_string& objlabel); void build_seq(); // hide these functions from the user SeqAcqInterface& set_pe_vector(const SeqVector& pevec) {return *this;} Handler pulsptr; SeqPulsarReph pls_reph; SeqGradVector phase; SeqGradVector phase3d; SeqGradVector phase_rew; SeqGradVector phase3d_rew; SeqSimultanVector phasesim; SeqSimultanVector phasesim3d; SeqSimultanVector phasereordsim; SeqAcqRead acqread; SeqGradConst readdeph; SeqParallel postexcpart; SeqParallel postacqpart; SeqObjList midpart; geometryMode mode; bool balanced_grads; }; /** @} */ #endif odin-1.8.5/odinseq/Makefile.am0000644000175000017500000000543211625224370013103 00000000000000 INCLUDES = $(all_includes) $(ODINSEQ_INCLUDES) lib_LTLIBRARIES = libodinseq.la libodinseq_la_LDFLAGS = -no-undefined -release $(VERSION) libodinseq_la_LIBADD = ../odinpara/libodinpara.la library_includedir=$(includedir)/odinseq library_include_HEADERS = \ odinpulse.h \ seqacq.h \ seqacqdeph.h \ seqacqepi.h \ seqacqread.h \ seqacqspiral.h \ seqall.h \ seqclass.h \ seqcmdline.h \ seqcounter.h \ seqdec.h \ seqdelay.h \ seqdelayvec.h \ seqdiffweight.h \ seqdriver.h \ seqdur.h \ seqfreq.h \ seqgrad.h \ seqgradchan.h \ seqgradchanlist.h \ seqgradchanparallel.h \ seqgradconst.h \ seqgradecho.h \ seqgradobj.h \ seqgradphase.h \ seqgradpulse.h \ seqgradramp.h \ seqgradspiral.h \ seqgradtrapez.h \ seqgradvec.h \ seqgradwave.h \ seqlist.h \ seqloop.h \ seqmakefile.h \ seqmeth.h \ seqobj.h \ seqobjvec.h \ seqoperator.h \ seqparallel.h \ seqphase.h \ seqplatform.h \ seqplot.h \ seqpuls.h \ seqpulsar.h \ seqpulsndim.h \ seqrotmatrixvector.h \ seqsat.h \ seqsim.h \ seqtemplate.h \ seqsimvec.h \ seqtree.h \ seqtrigg.h \ seqvec.h \ seqveciter.h \ seqblsiegprep.h libodinseq_la_SOURCES = \ 00seqtest.cpp \ odinpulse.cpp odinpulse.h odinpulse_shapes.cpp odinpulse_trajectories.cpp \ seqacq.cpp seqacq.h \ seqacqdeph.cpp seqacqdeph.h \ seqacqepi.cpp seqacqepi.h \ seqacqread.cpp seqacqread.h \ seqacqspiral.cpp seqacqspiral.h \ seqall.h \ seqblsiegprep.cpp seqblsiegprep.h \ seqclass.cpp seqclass.h \ seqcmdline.cpp seqcmdline.h \ seqcounter.cpp seqcounter.h \ seqdec.cpp seqdec.h \ seqdelay.cpp seqdelay.h \ seqdelayvec.cpp seqdelayvec.h \ seqdiffweight.cpp seqdiffweight.h \ seqdriver.cpp seqdriver.h \ seqdriver_epic.cpp seqdriver_idea.cpp seqdriver_paravision.cpp seqdriver_standalone.cpp \ seqdur.cpp seqdur.h \ seqfreq.cpp seqfreq.h \ seqgrad.cpp seqgrad.h \ seqgradchan.cpp seqgradchan.h \ seqgradchanlist.cpp seqgradchanlist.h \ seqgradchanparallel.cpp seqgradchanparallel.h \ seqgradconst.cpp seqgradconst.h \ seqgradecho.cpp seqgradecho.h \ seqgradobj.cpp seqgradobj.h \ seqgradphase.cpp seqgradphase.h \ seqgradpulse.cpp seqgradpulse.h \ seqgradramp.cpp seqgradramp.h \ seqgradspiral.cpp seqgradspiral.h \ seqgradtrapez.cpp seqgradtrapez.h \ seqgradvec.cpp seqgradvec.h \ seqgradwave.cpp seqgradwave.h \ seqlist.cpp seqlist.h \ seqloop.cpp seqloop.h \ seqmakefile.cpp seqmakefile.h \ seqmeth.cpp seqmeth.h \ seqobj.cpp seqobj.h \ seqobjvec.cpp seqobjvec.h \ seqoperator.cpp seqoperator.h \ seqparallel.cpp seqparallel.h \ seqphase.cpp seqphase.h \ seqplatform.cpp seqplatform.h \ seqplot.h \ seqpuls.cpp seqpuls.h \ seqpulsar.cpp seqpulsar.h \ seqpulsndim.cpp seqpulsndim.h \ seqrotmatrixvector.cpp seqrotmatrixvector.h \ seqsat.cpp seqsat.h \ seqsim.cpp seqsim.h \ seqtemplate.cpp seqtemplate.h \ seqsimvec.cpp seqsimvec.h \ seqtree.cpp seqtree.h \ seqtrigg.cpp seqtrigg.h \ seqvec.cpp seqvec.h \ seqveciter.cpp seqveciter.hodin-1.8.5/odinseq/Makefile.in0000644000175000017500000006357111734622602013125 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = odinseq DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(library_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libodinseq_la_DEPENDENCIES = ../odinpara/libodinpara.la am_libodinseq_la_OBJECTS = 00seqtest.lo odinpulse.lo \ odinpulse_shapes.lo odinpulse_trajectories.lo seqacq.lo \ seqacqdeph.lo seqacqepi.lo seqacqread.lo seqacqspiral.lo \ seqblsiegprep.lo seqclass.lo seqcmdline.lo seqcounter.lo \ seqdec.lo seqdelay.lo seqdelayvec.lo seqdiffweight.lo \ seqdriver.lo seqdriver_epic.lo seqdriver_idea.lo \ seqdriver_paravision.lo seqdriver_standalone.lo seqdur.lo \ seqfreq.lo seqgrad.lo seqgradchan.lo seqgradchanlist.lo \ seqgradchanparallel.lo seqgradconst.lo seqgradecho.lo \ seqgradobj.lo seqgradphase.lo seqgradpulse.lo seqgradramp.lo \ seqgradspiral.lo seqgradtrapez.lo seqgradvec.lo seqgradwave.lo \ seqlist.lo seqloop.lo seqmakefile.lo seqmeth.lo seqobj.lo \ seqobjvec.lo seqoperator.lo seqparallel.lo seqphase.lo \ seqplatform.lo seqpuls.lo seqpulsar.lo seqpulsndim.lo \ seqrotmatrixvector.lo seqsat.lo seqsim.lo seqtemplate.lo \ seqsimvec.lo seqtree.lo seqtrigg.lo seqvec.lo seqveciter.lo libodinseq_la_OBJECTS = $(am_libodinseq_la_OBJECTS) libodinseq_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libodinseq_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libodinseq_la_SOURCES) DIST_SOURCES = $(libodinseq_la_SOURCES) HEADERS = $(library_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = $(all_includes) $(ODINSEQ_INCLUDES) lib_LTLIBRARIES = libodinseq.la libodinseq_la_LDFLAGS = -no-undefined -release $(VERSION) libodinseq_la_LIBADD = ../odinpara/libodinpara.la library_includedir = $(includedir)/odinseq library_include_HEADERS = \ odinpulse.h \ seqacq.h \ seqacqdeph.h \ seqacqepi.h \ seqacqread.h \ seqacqspiral.h \ seqall.h \ seqclass.h \ seqcmdline.h \ seqcounter.h \ seqdec.h \ seqdelay.h \ seqdelayvec.h \ seqdiffweight.h \ seqdriver.h \ seqdur.h \ seqfreq.h \ seqgrad.h \ seqgradchan.h \ seqgradchanlist.h \ seqgradchanparallel.h \ seqgradconst.h \ seqgradecho.h \ seqgradobj.h \ seqgradphase.h \ seqgradpulse.h \ seqgradramp.h \ seqgradspiral.h \ seqgradtrapez.h \ seqgradvec.h \ seqgradwave.h \ seqlist.h \ seqloop.h \ seqmakefile.h \ seqmeth.h \ seqobj.h \ seqobjvec.h \ seqoperator.h \ seqparallel.h \ seqphase.h \ seqplatform.h \ seqplot.h \ seqpuls.h \ seqpulsar.h \ seqpulsndim.h \ seqrotmatrixvector.h \ seqsat.h \ seqsim.h \ seqtemplate.h \ seqsimvec.h \ seqtree.h \ seqtrigg.h \ seqvec.h \ seqveciter.h \ seqblsiegprep.h libodinseq_la_SOURCES = \ 00seqtest.cpp \ odinpulse.cpp odinpulse.h odinpulse_shapes.cpp odinpulse_trajectories.cpp \ seqacq.cpp seqacq.h \ seqacqdeph.cpp seqacqdeph.h \ seqacqepi.cpp seqacqepi.h \ seqacqread.cpp seqacqread.h \ seqacqspiral.cpp seqacqspiral.h \ seqall.h \ seqblsiegprep.cpp seqblsiegprep.h \ seqclass.cpp seqclass.h \ seqcmdline.cpp seqcmdline.h \ seqcounter.cpp seqcounter.h \ seqdec.cpp seqdec.h \ seqdelay.cpp seqdelay.h \ seqdelayvec.cpp seqdelayvec.h \ seqdiffweight.cpp seqdiffweight.h \ seqdriver.cpp seqdriver.h \ seqdriver_epic.cpp seqdriver_idea.cpp seqdriver_paravision.cpp seqdriver_standalone.cpp \ seqdur.cpp seqdur.h \ seqfreq.cpp seqfreq.h \ seqgrad.cpp seqgrad.h \ seqgradchan.cpp seqgradchan.h \ seqgradchanlist.cpp seqgradchanlist.h \ seqgradchanparallel.cpp seqgradchanparallel.h \ seqgradconst.cpp seqgradconst.h \ seqgradecho.cpp seqgradecho.h \ seqgradobj.cpp seqgradobj.h \ seqgradphase.cpp seqgradphase.h \ seqgradpulse.cpp seqgradpulse.h \ seqgradramp.cpp seqgradramp.h \ seqgradspiral.cpp seqgradspiral.h \ seqgradtrapez.cpp seqgradtrapez.h \ seqgradvec.cpp seqgradvec.h \ seqgradwave.cpp seqgradwave.h \ seqlist.cpp seqlist.h \ seqloop.cpp seqloop.h \ seqmakefile.cpp seqmakefile.h \ seqmeth.cpp seqmeth.h \ seqobj.cpp seqobj.h \ seqobjvec.cpp seqobjvec.h \ seqoperator.cpp seqoperator.h \ seqparallel.cpp seqparallel.h \ seqphase.cpp seqphase.h \ seqplatform.cpp seqplatform.h \ seqplot.h \ seqpuls.cpp seqpuls.h \ seqpulsar.cpp seqpulsar.h \ seqpulsndim.cpp seqpulsndim.h \ seqrotmatrixvector.cpp seqrotmatrixvector.h \ seqsat.cpp seqsat.h \ seqsim.cpp seqsim.h \ seqtemplate.cpp seqtemplate.h \ seqsimvec.cpp seqsimvec.h \ seqtree.cpp seqtree.h \ seqtrigg.cpp seqtrigg.h \ seqvec.cpp seqvec.h \ seqveciter.cpp seqveciter.h all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu odinseq/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu odinseq/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libodinseq.la: $(libodinseq_la_OBJECTS) $(libodinseq_la_DEPENDENCIES) $(libodinseq_la_LINK) -rpath $(libdir) $(libodinseq_la_OBJECTS) $(libodinseq_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/00seqtest.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinpulse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinpulse_shapes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinpulse_trajectories.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqacq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqacqdeph.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqacqepi.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqacqread.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqacqspiral.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqblsiegprep.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqclass.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqcmdline.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqcounter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdelay.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdelayvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdiffweight.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdriver.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdriver_epic.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdriver_idea.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdriver_paravision.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdriver_standalone.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqdur.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqfreq.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgrad.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradchan.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradchanlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradchanparallel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradconst.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradecho.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradobj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradphase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradpulse.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradramp.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradspiral.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradtrapez.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqgradwave.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqlist.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqloop.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqmakefile.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqmeth.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqobj.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqobjvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqoperator.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqparallel.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqphase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqplatform.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqpuls.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqpulsar.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqpulsndim.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqrotmatrixvector.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqsat.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqsim.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqsimvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqtemplate.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqtree.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqtrigg.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqvec.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqveciter.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-library_includeHEADERS: $(library_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(library_includedir)" || $(MKDIR_P) "$(DESTDIR)$(library_includedir)" @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(library_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(library_includedir)" || exit $$?; \ done uninstall-library_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(library_includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(library_includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-library_includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-library_includeHEADERS \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odinseq/seqpuls.cpp0000644000175000017500000001333511322062345013244 00000000000000#include "seqpuls.h" #include "seqdelay.h" #include SeqPulsInterface& SeqPulsInterface::set_flipangles(const fvector& flipangles) { float ang=get_flipangle(); fvector scales(flipangles.size()); if(ang) scales=flipangles/ang; else scales=0.0; set_flipscales(scales); return *this; } /////////////////////////////////////////////////////////////////////////////////// bool SeqFlipAngVector::prep_iteration() const { if(user) { return user->pulsdriver->prep_flipangle_iteration(get_current_index()); } return true; } svector SeqFlipAngVector::get_vector_commands(const STD_string& iterator) const { svector result; if(user) result=user->pulsdriver->get_flipvector_commands(iterator); return result; } /////////////////////////////////////////////////////////////////////////////////// SeqPuls::SeqPuls(const STD_string& object_label,const cvector& waveform,float pulsduration, float pulspower,const STD_string& nucleus, const dvector& phaselist,const dvector& freqlist,float rel_magnetic_center) : SeqObjBase(object_label), SeqFreqChan(object_label,nucleus,freqlist,phaselist), SeqDur(object_label,pulsduration), pulsdriver(object_label), flipvec(object_label+"_flipvec",this) { Log odinlog(this,"SeqPuls(...)"); wave=waveform; power=pulspower; system_flipangle=90.0; B1max_mT=0.0; relmagcent=rel_magnetic_center; } SeqPuls::SeqPuls(const STD_string& object_label) : SeqObjBase(object_label), SeqFreqChan(object_label), SeqDur(object_label), pulsdriver(object_label), flipvec(object_label+"_flipvec",this) { power=0.0; system_flipangle=90.0; B1max_mT=0.0; relmagcent=0.5; } SeqPuls::SeqPuls(const SeqPuls& sp) : flipvec(STD_string(sp.get_label())+"_flipvec",this) { SeqPuls::operator = (sp); } SeqPuls& SeqPuls::set_wave(const cvector& waveform) { wave=waveform; return *this; } double SeqPuls::get_duration() const { double result=get_pulsstart()+get_pulsduration(); result+=pulsdriver->get_postdelay(); return result; } SeqPulsInterface& SeqPuls::set_pulsduration(float pulsduration) { Log odinlog(this,"SeqPuls::set_pulsduration"); ODINLOG(odinlog,normalDebug) << "=" << pulsduration << STD_endl; SeqDur::set_duration(pulsduration); return *this; } double SeqPuls::get_pulsduration() const { Log odinlog(this,"SeqPuls::get_pulsduration"); ODINLOG(odinlog,normalDebug) << "=" << SeqDur::get_duration() << STD_endl; return SeqDur::get_duration(); } float SeqPuls::get_magnetic_center() const { Log odinlog(this,"get_magnetic_center"); ODINLOG(odinlog,normalDebug) << "relmagcent=" << relmagcent << STD_endl; ODINLOG(odinlog,normalDebug) << "get_pulsduration()=" << get_pulsduration() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_pulsstart()=" << get_pulsstart() << STD_endl; return get_pulsstart()+relmagcent*get_pulsduration(); } bool SeqPuls::prep() { Log odinlog(this,"prep"); if(!SeqFreqChan::prep()) return false; if(wave.length()==0) ODINLOG(odinlog,warningLog) << "Empty waveform" << STD_endl; if(wave.maxabs()==STD_complex(0,0)) ODINLOG(odinlog,warningLog) << "Zero filled waveform" << STD_endl; ODINLOG(odinlog,normalDebug) << "B1max_mT=" << B1max_mT << STD_endl; fvector flipscale=flipvec.flipanglescale; ODINLOG(odinlog,normalDebug) << "flipscale=" << flipscale.printbody() << STD_endl; return pulsdriver->prep_driver(wave,get_pulsduration(),get_magnetic_center(),B1max_mT,power,system_flipangle,flipscale,plstype); } STD_string SeqPuls::get_program(programContext& context) const { STD_string result=SeqFreqChan::get_pre_program(context,pulsObj,pulsdriver->get_instr_label()); result+=pulsdriver->get_program(context,get_phaselistindex(),get_channel(),get_iteratorcommand(pulsObj)); return result; } SeqPuls& SeqPuls::set_B1max(float b1max) { Log odinlog(this,"set_B1max"); B1max_mT=b1max; ODINLOG(odinlog,normalDebug) << "B1max_mT=" << B1max_mT << STD_endl; return *this; } SeqValList SeqPuls::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()); double newfreq=SeqFreqChan::get_frequency(); if(action==calcDeps) pulsdriver->new_freq(newfreq); if(action==calcList) { if(pulsdriver->has_new_freq()) result.set_value(newfreq); } return result; } SeqPuls& SeqPuls::set_system_flipangle(float angle) { system_flipangle=angle; return *this; } double SeqPuls::get_rf_energy() const { return pulsdriver->get_rf_energy(); } SeqPuls& SeqPuls::operator = (const SeqPuls& sp) { Log odinlog(this,"operator = "); SeqObjBase::operator = (sp); SeqFreqChan::operator = (sp); SeqDur::operator = (sp); pulsdriver=sp.pulsdriver; wave=sp.wave; power=sp.power; system_flipangle=sp.system_flipangle; B1max_mT=sp.B1max_mT; ODINLOG(odinlog,normalDebug) << "B1max_mT=" << B1max_mT << STD_endl; relmagcent=sp.relmagcent; plstype=sp.plstype; return *this; } STD_string SeqPuls::get_properties() const { return "Samples="+itos(wave.length())+", B1="+ftos(B1max_mT); } SeqPulsInterface& SeqPuls::set_pulse_type(pulseType type) { plstype=type; return *this; } pulseType SeqPuls::get_pulse_type() const {return plstype;} unsigned int SeqPuls::event(eventContext& context) const { Log odinlog(this,"event"); double start=context.elapsed+get_pulsstart(); SeqTreeObj::event(context); if(context.action==seqRun) { ODINLOG(odinlog,normalDebug) << "start=" << start << STD_endl; SeqFreqChan::pre_event(context,start); pulsdriver->event(context,start); SeqFreqChan::post_event(context,start+get_pulsduration()); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } odin-1.8.5/odinseq/seqpulsar.h0000644000175000017500000002252411322062345013234 00000000000000/*************************************************************************** seqpulsar.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPULSAR_H #define SEQPULSAR_H #include #include #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Pulsar pulses, combines OdinPulse and SeqPulsNdim * * This class is an interface to the Pulsar program; * It is possible to access most of the parameters of the underlying * data structure 'OdinPulse' via get/set functions */ class SeqPulsar : public SeqPulsNdim, public OdinPulse, public StaticHandler { public: /** * Constructs an empty Pulsar pulse with the given label. * If 'rephased' is true, rephasing gradient lobes will be added to null the * zero'th order gradient moment, i.e. the integral. * If 'interactive' is true, the pulse will be updated each time a parameter * was changed, otherwise update() has to be called manually. */ SeqPulsar(const STD_string& object_label = "unnamedSeqPulsar", bool rephased=false, bool interactive=true); /** * Constructs a Pulsar pulse which is a copy of 'sp' */ SeqPulsar(const SeqPulsar& sp); /** * Destructor */ ~SeqPulsar(); /** * Specifies whether an additional gradient rephasing lobe will be added to rephase * the magnetization in case of an excitation pulse. * If strength is larger than zero, this maximum strength will be used * for the rephaser gradient. */ SeqPulsar& set_rephased(bool rephased, float strength=0.0); /** * Returns the rephasers integral on all three channels */ fvector get_reph_gradintegral() const; /** * This assignment operator will make this object become an exact copy of 'sp'. */ SeqPulsar& operator = (const SeqPulsar& sp); /** * Recalculates the pulse manually, this is only required if the pulse is not interactive */ SeqPulsar& refresh(); /** * If this flag is set to true, the pulse will be recalculated each time a parameter is changed, * otherwise it must be done manually via the refresh() function */ SeqPulsar& set_interactive(bool flag); // overloading virtual function from SeqGradInterface float get_strength() const {return OdinPulse::get_G0();} // always return strength of pulse, and not that of rephasers // reimplemented virtual functions from SeqPulsNdim int get_dims() const; // reimplemented virtual functions from SeqFreqChanInterface SeqFreqChanInterface& set_nucleus(const STD_string& nucleus); // reimplemented virtual functions from SeqPulsInterface float get_flipangle() const {return OdinPulse::get_flipangle(); } SeqPulsInterface& set_flipangle(float flipangle); SeqPulsInterface& set_pulsduration(float pulsduration); SeqPulsInterface& set_power(float pulspower); SeqPulsInterface& set_pulse_type(pulseType type); pulseType get_pulse_type() const { return SeqPulsNdim::get_pulse_type();} // overloading virtual function from SeqTreeObj STD_string get_properties() const; // initialize/destroy static members via StaticHandler static void init_static(); static void destroy_static(); // Dummy operators for vector of pulsars with STL replacement bool operator == (const SeqPulsar& sp) const {return STD_string(get_label())==STD_string(sp.get_label());} bool operator < (const SeqPulsar& sp) const {return STD_string(get_label()), public Labeled {}; static SingletonHandler active_pulsar_pulses; }; //////////////////////////////////////////////////////////////////////////////// /** * * \brief Post-pulse rephaser * * This class represents a rephasing gradient pulse for SeqPulsar, i.e. it can serve as a refocusing lobe for a SeqPulsar * pulse */ class SeqPulsarReph : public SeqGradChanParallel { public: /** * Constructs a rephasing gradient pulse labeled 'object_label' with the following properties: * - puls: The puls that should be rephased */ SeqPulsarReph(const STD_string& object_label,const SeqPulsar& puls); /** * Constructs a copy of 'spr' */ SeqPulsarReph(const SeqPulsarReph& spr); /** * Construct an empty rephasing gradient pulse with the given label */ SeqPulsarReph(const STD_string& object_label = "unnamedSeqPulsarReph"); /** * Destructor */ ~SeqPulsarReph(); /** * Assignment operator that makes this object become a copy of 'spr' */ SeqPulsarReph& operator = (const SeqPulsarReph& spr); /** * Returns the duration of the ramp that switches the gradient pulse on */ float get_onramp_duration() const; /** * Returns the duration of the rephasing part of the gradient pulse */ float get_constgrad_duration() const; /** * Returns the duration of the ramp that switches the gradient pulse on */ float get_offramp_duration() const; private: void build_seq(); unsigned int dim; SeqGradTrapez gxpulse; SeqGradTrapez gypulse; SeqGradTrapez gzpulse; }; //////////////////////////////////////////////////////////////////////////////// /** * * \brief Sinc pulse * * A sinc shaped pulse * */ class SeqPulsarSinc : public SeqPulsar { public: /** * Constructs a slice selective sinc pulse labeled 'object_label' with the following properties: * - slicethickness: The thickness of the slice that will be excited * - rephased: If true, an additional gradient lobe will be added to rephase the magnetisation * - duration: The pulse duration * - flipangle: The flip angle * - resolution: The spatial resolution, i.e. the scale on which the excitation profile is smoothed * - npoints: The number of digitised (complex) points for the pulse */ SeqPulsarSinc(const STD_string& object_label="unnamedSeqPulsarSinc", float slicethickness=5.0, bool rephased=true, float duration=2.0, float flipangle=90.0, float resolution=1.5, unsigned int npoints=256); /** * Constructs a copy of 'sps' */ SeqPulsarSinc(const SeqPulsarSinc& sps); /** * Assignment operator that makes this object become a copy of 'sps' */ SeqPulsarSinc& operator = (const SeqPulsarSinc& sps); }; //////////////////////////////////////////////////////////////////////////////// /** * * \brief Gauss pulse * * A Gaussian shaped pulse * */ class SeqPulsarGauss : public SeqPulsar { public: /** * Constructs a slice selective Gauss pulse labeled 'object_label' with the following properties: * - slicethickness: The thickness of the slice (FWHM) that will be excited * - rephased: If true, an additional gradient lobe will be added to rephase the magnetisation * - duration: The pulse duration * - flipangle: The flip angle * - npoints: The number of digitised (complex) points for the pulse */ SeqPulsarGauss(const STD_string& object_label="unnamedSeqPulsarGauss", float slicethickness=5.0, bool rephased=true, float duration=1.0, float flipangle=90.0, unsigned int npoints=128); /** * Constructs a copy of 'spg' */ SeqPulsarGauss(const SeqPulsarGauss& spg); /** * Assignment operator that makes this object become a copy of 'spg' */ SeqPulsarGauss& operator = (const SeqPulsarGauss& spg); }; //////////////////////////////////////////////////////////////////////////////// /** * * \brief Const pulse * * A block shaped shaped pulse * */ class SeqPulsarBP : public SeqPulsar { public: /** * Constructs a block shaped pulse labeled 'object_label' with the following properties: * - duration: The pulse duration * - flipangle: The flip angle */ SeqPulsarBP(const STD_string& object_label="unnamedSeqPulsarBP", float duration=1.0, float flipangle=90.0, const STD_string& nucleus=""); /** * Constructs a copy of 'spb' */ SeqPulsarBP(const SeqPulsarBP& spb); /** * Assignment operator that makes this object become a copy of 'spb' */ SeqPulsarBP& operator = (const SeqPulsarBP& spb); }; /** @} */ #endif odin-1.8.5/odinseq/seqgradchan.cpp0000644000175000017500000001137611322062345014033 00000000000000#include "seqgradchan.h" #include "seqparallel.h" #include #include SeqGradChan::SeqGradChan(const STD_string& object_label,direction gradchannel, float gradstrength, double gradduration) : SeqDur(object_label), graddriver(object_label) { channel=gradchannel; SeqGradChan::set_strength(gradstrength); // perform strength checking, do NOT call virtual function in constructor set_duration(gradduration); } SeqGradChan::SeqGradChan(const STD_string& object_label) : SeqDur(object_label), graddriver(object_label) { SeqGradChan::set_strength(0.0); // perform strength checking, do NOT call virtual function in constructor channel=readDirection; } SeqGradChan::SeqGradChan(const SeqGradChan& sgc) { SeqGradChan::operator = (sgc); } SeqGradChan& SeqGradChan::operator = (const SeqGradChan& sgc) { SeqDur::operator = (sgc); graddriver=sgc.graddriver; gradrotmatrix=sgc.gradrotmatrix; channel=sgc.channel; strength=sgc.strength; return *this; } SeqGradInterface& SeqGradChan::set_strength(float gradstrength) { Log odinlog(this,"set_strength"); ODINLOG(odinlog,normalDebug) << "gradstrength(pre)=" << gradstrength << STD_endl; gradstrength=graddriver->check_strength(gradstrength); ODINLOG(odinlog,normalDebug) << "gradstrength(post)=" << gradstrength << STD_endl; float maxgrad=systemInfo->get_max_grad(); ODINLOG(odinlog,normalDebug) << "maxgrad=" << maxgrad << STD_endl; if(gradstrength>maxgrad) { float oldstrength=gradstrength; gradstrength=maxgrad; ODINLOG(odinlog,warningLog) << "Gradient strength (" << oldstrength << ") exceeds maximum, setting to " << gradstrength << STD_endl; } strength=gradstrength; return *this; } SeqGradInterface& SeqGradChan::invert_strength() { strength=-strength; return *this; } float SeqGradChan::get_strength() const { return strength; } direction SeqGradChan::get_channel() const {return channel;} SeqGradInterface& SeqGradChan::set_gradrotmatrix(const RotMatrix& matrix) { Log odinlog(this,"set_gradrotmatrix"); for(unsigned int i=0;i1.0) { gradrotmatrix[j][i]=1.0; ODINLOG(odinlog,warningLog) << "exceeded 1.0 in gradrotmatrix[" << j << "][" << i << "], setting to 1.0" << STD_endl; } if(gradrotmatrix[j][i]<-1.0) { gradrotmatrix[j][i]=-1.0; ODINLOG(odinlog,warningLog) << "exceeded -1.0 in gradrotmatrix[" << j << "][" << i << "], setting to -1.0" << STD_endl; } } } return *this; } STD_string SeqGradChan::get_grdpart_rot(direction chan) const { Log odinlog(this,"get_grdpart_rot"); STD_string result; float matrixfactor=get_grdfactor(chan); ODINLOG(odinlog,normalDebug) << "matrixfactor[" << int(chan) << "][" << int(get_channel()) << "]=" << matrixfactor << STD_endl; if(fabs(matrixfactor)>_GRADROTMATRIX_LIMIT_) { result+=get_grdpart(matrixfactor); } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } RotMatrix SeqGradChan::get_total_rotmat() const { RotMatrix result; const SeqRotMatrixVector* rotvec=SeqObjList::current_gradrotmatrixvec.get_handled(); if(rotvec) result=rotvec->get_current_matrix(); result=result*gradrotmatrix; // Multiplying the matrix coming from the vector with the local matrix return result; } float SeqGradChan::get_grdfactor(direction chan) const { return get_total_rotmat()[chan][get_channel()]; } fvector SeqGradChan::get_grdfactors_norot() const { fvector result(n_directions); for(int i=0; ievent(context,startelapsed); } context.elapsed=startelapsed+get_gradduration(); if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } // Template instantiations template class ListItem; template class List; odin-1.8.5/odinseq/seqdur.cpp0000644000175000017500000000150411322062345013046 00000000000000#include "seqdur.h" SeqDur::SeqDur(const STD_string& object_label, float duration) : SeqTreeObj() { set_label(object_label); // this is neccessary because SeqClass is a virtual base class set_duration(duration); } SeqDur::SeqDur(const STD_string& object_label) : SeqTreeObj() { set_label(object_label); // this is neccessary because SeqClass is a virtual base class set_duration(0.0); } SeqDur::SeqDur(const SeqDur& sd) { SeqDur::operator = (sd); } SeqDur& SeqDur::operator = (const SeqDur& sd) { SeqTreeObj::operator = (sd); set_duration(sd.dur); return *this; } double SeqDur::get_duration() const { return dur; } SeqDur& SeqDur::set_duration(float duration) { dur=duration; if (durationget_min_duration(delayObj)) { dur=systemInfo->get_min_duration(delayObj); } return *this; } odin-1.8.5/odinseq/seqsimvec.h0000644000175000017500000000525611322062345013217 00000000000000/*************************************************************************** seqsimvec.h - description ------------------- begin : Mon Aug 9 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQSIMVEC_H #define SEQSIMVEC_H #include /** * @ingroup odinseq_internals * This vector class is used to group other vector objects together so that * they can be updated simultaneously at each iteration. */ class SeqSimultanVector : public SeqVector, public virtual SeqClass, public List { public: /** * Construct an empty vector of sequence objects with the given label */ SeqSimultanVector(const STD_string& object_label="unnamedSeqSimultanVector") : SeqClass(), SeqVector(object_label) {set_label(object_label);} /** * Constructs a copy of 'ssv' */ SeqSimultanVector(const SeqSimultanVector& ssv); /** * Assignment operator that makes this vector object become a copy of 'ssv' */ SeqSimultanVector& operator = (const SeqSimultanVector& ssv); /** * Appends sv to the list of managed vectors */ SeqSimultanVector& operator += (const SeqVector& sv); /** * clears the list of managed vectors */ SeqSimultanVector& clear() { List::clear(); return *this;} // implemented virtual functions from SeqVector svector get_vector_commands(const STD_string& iterator) const; unsigned int get_vectorsize() const; unsigned int get_numof_iterations() const; STD_string get_loopcommand() const; nestingRelation get_nesting_relation() const; bool needs_unrolling_check() const; bool prep_iteration() const; // bool is_acq_vector() const; const SeqVector& set_vechandler(const SeqCounter* sc) const; bool is_qualvector() const; private: // implemented virtual functions from SeqClass void clear_container(); }; #endif odin-1.8.5/odinseq/seqsim.cpp0000644000175000017500000011144011712547771013063 00000000000000#include #include #include "seqsim.h" /////////////////////////////////////////////////////////////////////////// void SeqSimMagsi::common_init() { magsi=false; nthreads=1; Mamp.set_filemode(compressed); Mpha.set_filemode(compressed); Mz.set_filemode(compressed); online=true; time_intervals_cache=0; xpos_cache=0; ypos_cache=0; zpos_cache=0; freqoffset_cache=0; ppm_cache=0; spin_density_cache=0; B1map_transm_cache=0; B1map_receiv_cache=0; Dcoeff_cache=0; num_rec_channel_cache=0; r1_cache=0; r2_cache=0; has_relax_cache=0; spat_rotmatrix=0; initial_vector[0]=0.0; initial_vector[1]=0.0; initial_vector[2]=1.0; online.set_description("Perform simulation online, i.e. each time a pulse parameter has been changed"); update_now.set_description("Recalculate magnetization"); initial_vector.set_description("Magnetization at beginning of pulse"); // intra-voxel magn gradients for(unsigned int k=0; k<4; k++) { dMx[k]=0; dMy[k]=0; dMz[k]=0; if(k<3) dppm[k]=0; } // init cache, must be called after setting pointers to zero outdate_simcache(); // set defaults on axes Sample default_sample; set_axes_cache(default_sample); } void SeqSimMagsi::outdate_simcache() { if(time_intervals_cache) delete[] time_intervals_cache; time_intervals_cache=0; if(xpos_cache) delete[] xpos_cache; xpos_cache=0; if(ypos_cache) delete[] ypos_cache; ypos_cache=0; if(zpos_cache) delete[] zpos_cache; zpos_cache=0; if(freqoffset_cache) delete[] freqoffset_cache; freqoffset_cache=0; if(ppm_cache) delete[] ppm_cache; ppm_cache=0; if(spin_density_cache) delete[] spin_density_cache; spin_density_cache=0; if(B1map_transm_cache) delete[] B1map_transm_cache; B1map_transm_cache=0; if(B1map_receiv_cache) { for(unsigned int ichan=0; ichan odinlog(this,"update_axes"); unsigned int nz=Mx.size(zDim); unsigned int nfreq=Mx.size(freqDim); ODINLOG(odinlog,normalDebug) << "nz/nfreq=" << nz << "/" << nfreq << STD_endl; GuiProps gp; if(nfreq>1) { gp.scale[xPlotScale]=ArrayScale("Frequency Offset",ODIN_FREQ_UNIT,freq_low,freq_upp); } if(nz>1) { gp.scale[xPlotScale]=ArrayScale("Spatial Offset",ODIN_SPAT_UNIT,x_low,x_upp); } Mx. set_gui_props(gp); My. set_gui_props(gp); Mz. set_gui_props(gp); Mamp.set_gui_props(gp); Mpha.set_gui_props(gp); } bool SeqSimMagsi::do_simulation() { bool action=false; if(update_now) action=true; if(online) action=true; return action; } void SeqSimMagsi::set_axes_cache(const Sample& sample) { Log odinlog(this,"create_simcache"); x_low=sample.get_spatial_offset(xAxis)-0.5*sample.get_FOV(xAxis); x_upp=sample.get_spatial_offset(xAxis)+0.5*sample.get_FOV(xAxis); ODINLOG(odinlog,normalDebug) << "x_low/x_upp=" << x_low << "/" << x_upp << STD_endl; y_low=sample.get_spatial_offset(yAxis)-0.5*sample.get_FOV(yAxis); y_upp=sample.get_spatial_offset(yAxis)+0.5*sample.get_FOV(yAxis); ODINLOG(odinlog,normalDebug) << "y_low/y_upp=" << y_low << "/" << y_upp << STD_endl; z_low=sample.get_spatial_offset(zAxis)-0.5*sample.get_FOV(zAxis); z_upp=sample.get_spatial_offset(zAxis)+0.5*sample.get_FOV(zAxis); ODINLOG(odinlog,normalDebug) << "z_low/z_upp=" << z_low << "/" << z_upp << STD_endl; freq_low=sample.get_freqoffset()-0.5*sample.get_freqrange(); // in kHz freq_upp=sample.get_freqoffset()+0.5*sample.get_freqrange(); // in kHz ODINLOG(odinlog,normalDebug) << "freq_low/freq_upp=" << freq_low << "/" << freq_upp << STD_endl; } void SeqSimMagsi::prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil, CoilSensitivity* receive_coil, ProgressMeter* progmeter) { if(simcache_up2date) return; Log odinlog(this,"create_simcache"); outdate_simcache(); // delete old pointers ndim extent=sample.get_extent(); unsigned int nx=extent[xDim]; unsigned int ny=extent[yDim]; unsigned int nz=extent[zDim]; unsigned int nfreq=extent[freqDim]; // unsigned int n=extent.total(); oneframe_size_cache=nx*ny*nz*nfreq; // size of one frame ODINLOG(odinlog,normalDebug) << "extent/oneframe_size=" << (STD_string)extent << "/" << oneframe_size_cache << STD_endl; resize(nx, ny, nz, nfreq); // will call reset_magnetization() and outdate_simcache() if(progmeter) progmeter->new_task(extent.total(),"Initializing Simulation"); elapsed_time=0.0; time_index_cache=0; numof_time_intervals_cache=0; dvector ti(sample.get_frame_durations()); unsigned int nti=ti.size(); if(nti>1) { numof_time_intervals_cache=nti; ODINLOG(odinlog,normalDebug) << "numof_time_intervals_cache=" << numof_time_intervals_cache << STD_endl; time_intervals_cache=new double[numof_time_intervals_cache]; for(unsigned int iti=0; iti1) L[3]=2.0*PII*sample.get_freqrange()/float(nfreq); // in rad*kHz ODINLOG(odinlog,normalDebug) << "L=" << L[0] << "/" << L[1] << "/" << L[2] << "/" << L[3]<< STD_endl; B0_ppm=1.0e-6*systemInfo->get_B0(); if(spat_rotmatrix) ODINLOG(odinlog,normalDebug) << "spat_rotmatrix=" << spat_rotmatrix->print() << STD_endl; ODINLOG(odinlog,normalDebug) << "ppmMap.get_extent()=" << ppmMap.get_extent() << STD_endl; ODINLOG(odinlog,normalDebug) << "spinDensity.get_extent()=" << spinDensity.get_extent() << STD_endl; ODINLOG(odinlog,normalDebug) << "spinDensity.sum()=" << spinDensity.sum() << STD_endl; extent[frameDim]=1; // iterate over time dim for each map separately unsigned int iframe; for(unsigned int i=0; i1) freqoffset_cache[i] = 2.0*PII*freq_low + (float(ifreq)+0.5)*L[3]; float x=sample.get_spatial_offset(xAxis); if(nx>1) x = x_low + (float(ix)+0.5)*L[0]; float y=sample.get_spatial_offset(yAxis); if(ny>1) y = y_low + (float(iy)+0.5)*L[1]; float z=sample.get_spatial_offset(zAxis); if(nz>1) z = z_low + (float(iz)+0.5)*L[2]; if(spat_rotmatrix) { dvector srcvec(3); srcvec[0]=x; srcvec[1]=y; srcvec[2]=z; dvector targetvec=(*spat_rotmatrix)*srcvec; xpos_cache[i]=targetvec[0]; ypos_cache[i]=targetvec[1]; zpos_cache[i]=targetvec[2]; } else { xpos_cache[i]=x; ypos_cache[i]=y; zpos_cache[i]=z; } for(iframe=0; iframeget_numof_channels(); ichan++) { chansum+=transmit_coil->get_sensitivity_value(ichan,xpos_cache[i],ypos_cache[i],zpos_cache[i]); } B1map_transm_cache[i]*=chansum; } if(receive_coil) { // separate B1map for different channels of coil for(ichan=0; ichanget_sensitivity_value(ichan,xpos_cache[i],ypos_cache[i],zpos_cache[i]); } if(sim_diffusion) { for(iframe=0; iframet1) t2=t1; if(iframe==0) has_relax_cache[i]=false; // reset only in 1st frame if(t1>0.0) has_relax_cache[i]=true; r1_cache[it1]=secureDivision( 1.0 , t1 ); r2_cache[it2]=secureDivision( 1.0 , t2 ); iframe++; } if(magsi || sim_diffusion) { for(k=0; k<4; k++) { dMx[k][i]=0.0; dMy[k][i]=0.0; dMz[k][i]=0.0; } for(k=0; k<3; k++) { // iterate through 3 spat dims to calc spat grads from ppmMap dppm[k][i]=0.0; bool calc_grads=true; // if(!have_ppmMap) calc_grads=false; // if(have_spinDensity && spinDensity(indexvec)<=0.0) calc_grads=false; if(spinDensity(indexvec)<=0.0) calc_grads=false; // use only first frame if(calc_grads) { bool have_low=false; bool have_upp=false; float lowval=0.0; float uppval=0.0; float currval=ppmMap(indexvec); // use only first frame int index=indexvec[xDim-k]; if(index>0) { ndim indexvec_low(indexvec); indexvec_low[xDim-k]--; // if(!have_spinDensity) have_low=true; if(/*have_spinDensity && */ spinDensity(indexvec_low)>0.0) have_low=true; if(have_low) lowval=ppmMap(indexvec_low); } if(index0.0) have_upp=true; if(have_upp) uppval=ppmMap(indexvec_upp); } if(have_upp && have_low) dppm[k][i]=secureDivision(uppval-lowval, 2.0*L[k]); if(!have_upp && have_low) dppm[k][i]=secureDivision(currval-lowval, L[k]); if(have_upp && !have_low) dppm[k][i]=secureDivision(uppval-currval, L[k]); } } } if(progmeter) progmeter->increase_counter(); } update_axes(); if(!ThreadedLoop::init(nthreads, oneframe_size_cache)) { ODINLOG(odinlog,errorLog) << "cannot init multithreading" << STD_endl; } simcache_up2date=true; } cvector SeqSimMagsi::simulate(const SeqSimInterval& simvals, double gamma) { Log odinlog(this,"simulate"); cvector result(num_rec_channel_cache); // initialized with zeroes gamma_cache=gamma; if(numof_time_intervals_cache) { elapsed_time+=simvals.dt; while(elapsed_time>=time_intervals_cache[time_index_cache]) { elapsed_time-=time_intervals_cache[time_index_cache]; time_index_cache++; if(time_index_cache>=numof_time_intervals_cache) time_index_cache=0; ODINLOG(odinlog,normalDebug) << "Switching to time_index=" << time_index_cache << STD_endl; } } STD_vector outvec; if(!ThreadedLoop::execute(simvals, outvec)) { ODINLOG(odinlog,errorLog) << "cannot start multithreading" << STD_endl; return result; } if(simvals.rec>0.0) { for(unsigned int i=0; i odinlog(this,"kernel"); if(simvals.dt<=0.0) return true; unsigned int ichan; // doubles to sum up signal, and use local (thread-specific) storage double* reSig; double* imSig; if(simvals.rec>0.0) { reSig=new double[num_rec_channel_cache]; imSig=new double[num_rec_channel_cache]; for(ichan=0; ichan0.0) A2= exp(-Dval * bval2); // Check for round-off errors when bval2 was calculated Mxnew *= A2; Mynew *= A2; Mznew *= A1; for(k=0; k<4; k++) { dMxnew[k] *= A2; dMynew[k] *= A2; dMznew[k] *= A1; } } ////////////////// Relaxation /////////////////////////////////////////////// if ( has_relax_cache[i] ) { //with relaxation E1=exp(-simvals.dt*r1_cache[(time_index_cache%nframes_r1_cache)*oneframe_size_cache+i]); E2=exp(-simvals.dt*r2_cache[(time_index_cache%nframes_r2_cache)*oneframe_size_cache+i]); Mxnew *= E2; Mynew *= E2; Mznew = (Mznew-1.0) * E1 + 1.0; // intra-voxel deph if(sim_intravoxel_grads) { for(k=0; k<4; k++) { dMxnew[k] *= E2; dMynew[k] *= E2; dMznew[k] *= E1; } } } ////////////////// Store Results /////////////////////////////////////////////// // store new values Mx[i]=Mxnew; My[i]=Mynew; Mz[i]=Mznew; // store intra-voxel magn gradients if(sim_intravoxel_grads) { for(k=0; k<4; k++) { dMx[k][i]=dMxnew[k]; dMy[k][i]=dMynew[k]; dMz[k][i]=dMznew[k]; } } ////////////////// Calculate signal //////////////////////////////////////////// if(simvals.rec>0.0) { // create signal by accumulating transverse magnetization STD_complex Mtrans(Mxnew,Mynew); if(magsi) { weight=1.0; for(k=0; k<4; k++) { float Mabs2=Mxnew*Mxnew + Mynew*Mynew; if(Mabs2) { // check before division dphi = (dMynew[k]*Mxnew - Mynew*dMxnew[k]) / Mabs2; if(dphi && (L[k]>0.0)) { weight *= sinc(0.5*dphi*L[k]); } } } Mtrans *= STD_complex(weight); } STD_complex sigMagn=s0*conj(Mtrans); for(ichan=0; ichan0.0) } // end loop over Mx,My,.. arrays if(simvals.rec>0.0) { signal.resize(num_rec_channel_cache); for(ichan=0; ichanget_B0(); if(!ThreadedLoop::init(numof_threads, particle.size())) { ODINLOG(odinlog,errorLog) << "cannot init multithreading" << STD_endl; } } unsigned int SeqSimMonteCarlo::linear_index(const float pos[3]) const { unsigned int index[3]; for(unsigned int k=0; k<3; k++) index[k]=((unsigned int)pos[k])%size_cache[k]; // assuming periodic pattern of spatial maps unsigned int result= index[2]*size_cache[0]*size_cache[1] + index[1]*size_cache[0] + index[0]; return result; } cvector SeqSimMonteCarlo::simulate(const SeqSimInterval& simvals, double gamma) { Log odinlog(this,"simulate"); cvector result(1); if(simvals.dt<=0.0) return result; gamma_cache=gamma; STD_vector outvec; if(!ThreadedLoop::execute(simvals, outvec)) { ODINLOG(odinlog,errorLog) << "cannot start multithreading" << STD_endl; return result; } if(simvals.rec>0.0) { for(unsigned int i=0; i odinlog(this,"kernel"); if(simvals.dt<=0.0) return true; float phase_rad=simvals.phase * PII / 180.0; float d_rf[3][3]; float b = 0.0; // Uniform B1 field for all particles float B1amp=cabs(simvals.B1); if(B1amp) { // float B1phase=phase(simvals.B1); // STD_complex b1_pulse= float(gamma_cache) * B1amp * STD_complex( cos(B1phase+phase_rad), sin(B1phase+phase_rad)); STD_complex b1_pulse= float(gamma_cache) * simvals.B1 * expc(STD_complex(0.0,phase_rad)); float bx=b1_pulse.real(); float by=b1_pulse.imag(); b = norm(bx,by); // Uniform B1 rotation matrix for all particles float ax = bx / b; float ay = by / b; float ph_rf = b*simvals.dt; // the precession angle around the effective field float si_rf = sin (ph_rf); float co_rf = cos (ph_rf); float axx= ax * ax; float ayy= ay * ay; float u= ax * ay * (1 - co_rf); float v= ay * si_rf; float w= ax * si_rf; // rotation matrix d_rf[0][0]= axx + ayy * co_rf; d_rf[0][1]= u; d_rf[0][2]= -v; d_rf[1][0]= u; d_rf[1][1]= ayy + axx * co_rf; d_rf[1][2]= w; d_rf[2][0]= v; d_rf[2][1]= -w; d_rf[2][2]= co_rf; } float w0_ppm=gamma_cache*B0_ppm_cache; // Use double precision to avoid round-off error when summing up signal double reSig=0.0; double imSig=0.0; for(unsigned int i=begin; i SeqTrigger::SeqTrigger(const STD_string& object_label, double duration) : SeqObjBase(object_label), triggdriver(object_label), triggdur(duration) { } SeqTrigger::SeqTrigger(const STD_string& object_label) : SeqObjBase(object_label), triggdriver(object_label), triggdur(0.0) { } SeqTrigger& SeqTrigger::operator = (const SeqTrigger& st) { SeqObjBase::operator = (st); triggdriver=st.triggdriver; triggdur=st.triggdur; return *this; } STD_string SeqTrigger::get_program(programContext& context) const { return triggdriver->get_program(context); } double SeqTrigger::get_duration() const { return triggdur+triggdriver->get_postduration(); } unsigned int SeqTrigger::event(eventContext& context) const { Log odinlog(this,"event"); double startelapsed=context.elapsed; SeqObjBase::event(context); ODINLOG(odinlog,normalDebug) << "context.action/startelapsed=" << context.action << "/" << startelapsed << STD_endl; if(context.action==seqRun) { triggdriver->event(context,startelapsed); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } bool SeqTrigger::prep() { if(!SeqObjBase::prep()) return false; return triggdriver->prep_exttrigger(triggdur); } ///////////////////////////////////////////////////////////////////////////// SeqHalt::SeqHalt(const STD_string& object_label) : SeqObjBase(object_label), triggdriver(object_label) { } SeqHalt& SeqHalt::operator = (const SeqHalt& sh) { SeqObjBase::operator = (sh); triggdriver=sh.triggdriver; return *this; } STD_string SeqHalt::get_program(programContext& context) const { return triggdriver->get_program(context); } double SeqHalt::get_duration() const { return triggdriver->get_postduration(); } unsigned int SeqHalt::event(eventContext& context) const { Log odinlog(this,"event"); double startelapsed=context.elapsed; SeqObjBase::event(context); ODINLOG(odinlog,normalDebug) << "context.action/startelapsed=" << context.action << "/" << startelapsed << STD_endl; if(context.action==seqRun) { triggdriver->event(context,startelapsed); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } bool SeqHalt::prep() { if(!SeqObjBase::prep()) return false; return triggdriver->prep_halttrigger(); } ///////////////////////////////////////////////////////////////////////////// SeqSnapshot::SeqSnapshot(const STD_string& object_label, const STD_string& snapshot_fname) : SeqObjBase(object_label), triggdriver(object_label) { magn_fname=snapshot_fname; } SeqSnapshot::SeqSnapshot(const STD_string& object_label) : SeqObjBase(object_label), triggdriver(object_label) { } SeqSnapshot& SeqSnapshot::operator = (const SeqSnapshot& ss) { SeqObjBase::operator = (ss); triggdriver=ss.triggdriver; magn_fname=ss.magn_fname; return *this; } unsigned int SeqSnapshot::event(eventContext& context) const { double startelapsed=context.elapsed; SeqObjBase::event(context); if(context.action==seqRun) { triggdriver->event(context,startelapsed); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } bool SeqSnapshot::prep() { if(!SeqObjBase::prep()) return false; return triggdriver->prep_snaptrigger(magn_fname); } ///////////////////////////////////////////////////////////////////////////// SeqMagnReset::SeqMagnReset(const STD_string& object_label) : SeqObjBase(object_label), triggdriver(object_label) { } SeqMagnReset& SeqMagnReset::operator = (const SeqMagnReset& smr) { SeqObjBase::operator = (smr); triggdriver=smr.triggdriver; return *this; } unsigned int SeqMagnReset::event(eventContext& context) const { double startelapsed=context.elapsed; SeqObjBase::event(context); if(context.action==seqRun) { triggdriver->event(context,startelapsed); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } bool SeqMagnReset::prep() { if(!SeqObjBase::prep()) return false; return triggdriver->prep_resettrigger(); } odin-1.8.5/odinseq/seqpulsndim.cpp0000644000175000017500000001345011322062345014112 00000000000000#include "seqpulsndim.h" #include "seqgradwave.h" #include "seqgradconst.h" #include "seqdelay.h" #include "seqgradchanparallel.h" #include struct SeqPulsNdimObjects { SeqPulsNdimObjects() {} SeqPulsNdimObjects(const STD_string& object_label, double gradshift_delay) : gx(object_label+"_Gx",readDirection,0.0,0.0,fvector()), gy(object_label+"_Gy",phaseDirection,0.0,0.0,fvector()), gz(object_label+"_Gz",sliceDirection,0.0,0.0,fvector()), sgh(object_label+"_handler"), rftrain(object_label+"_rftrain"), sp(object_label+"_rf"), dgs(object_label+"_shift_delay",gradshift_delay-sp.get_pulsstart()) {} SeqGradWave gx; SeqGradWave gy; SeqGradWave gz; SeqGradDelay gx_delay; SeqGradDelay gy_delay; SeqGradDelay gz_delay; SeqGradChanParallel sgh; SeqObjList rftrain; SeqPuls sp; SeqDelay dgs; }; ///////////////////////////////////////////////////////////////// SeqPulsNdim::SeqPulsNdim(const STD_string& object_label ) : SeqParallel(object_label), objs(new SeqPulsNdimObjects(object_label,systemInfo->get_grad_shift_delay())) { SeqPulsInterface::set_marshall(&(objs->sp)); SeqFreqChanInterface::set_marshall(&(objs->sp)); dims=0; gradshift=0.0; build_seq(); } SeqPulsNdim::SeqPulsNdim(const SeqPulsNdim& spnd) : objs(new SeqPulsNdimObjects) { SeqPulsInterface::set_marshall(&(objs->sp)); SeqFreqChanInterface::set_marshall(&(objs->sp)); SeqPulsNdim::operator = (spnd); } SeqPulsNdim::~SeqPulsNdim() { Log odinlog(this,"~SeqPulsNdim()"); delete objs; } SeqPulsNdim& SeqPulsNdim::set_rfwave(const cvector& waveform) { objs->sp.set_wave(waveform); return *this; } SeqPulsNdim& SeqPulsNdim::set_gradwave(direction dir, const fvector& waveform) { if(dir==readDirection) objs->gx.set_wave(waveform); if(dir==phaseDirection) objs->gy.set_wave(waveform); if(dir==sliceDirection) objs->gz.set_wave(waveform); return *this; } SeqPulsNdim& SeqPulsNdim::set_B1max(float b1max) { objs->sp.set_B1max(b1max); return *this; } cvector SeqPulsNdim::get_rfwave() const {return objs->sp.get_wave();} fvector SeqPulsNdim::get_gradwave(direction dir) const { if(dir==readDirection) return objs->gx.get_wave(); if(dir==phaseDirection) return objs->gy.get_wave(); if(dir==sliceDirection) return objs->gz.get_wave(); return fvector(); } int SeqPulsNdim::get_dims() const {return dims;} SeqPulsInterface& SeqPulsNdim::set_pulsduration(float pulsduration) { Log odinlog(this,"SeqPulsNdim::set_pulsduration"); ODINLOG(odinlog,normalDebug) << "=" << pulsduration << STD_endl; objs->sp.set_pulsduration(pulsduration); objs->gx.set_duration(pulsduration); objs->gy.set_duration(pulsduration); objs->gz.set_duration(pulsduration); return *this; } float SeqPulsNdim::get_magnetic_center() const { Log odinlog(this,"get_magnetic_center"); ODINLOG(odinlog,normalDebug) << "dgs.get_duration()=" << objs->dgs.get_duration() << STD_endl; ODINLOG(odinlog,normalDebug) << "sp.get_magnetic_center()=" << objs->sp.get_magnetic_center() << STD_endl; if(get_dims()) return objs->sgh.get_pulprogduration()+objs->dgs.get_duration()+objs->sp.get_magnetic_center(); else return objs->sp.get_magnetic_center(); } SeqVector& SeqPulsNdim::set_indexvec(const ivector& iv) {objs->sp.set_indexvec(iv); return objs->sp;} SeqPulsNdim& SeqPulsNdim::operator += (SeqGradChanList& sgcl) {objs->sgh+=sgcl; return *this;} SeqPulsNdim& SeqPulsNdim::set_system_flipangle(float angle) {objs->sp.set_system_flipangle(angle); return *this;} SeqPulsNdim& SeqPulsNdim::set_grad_shift_offset(float grad_shift_offset) { gradshift=grad_shift_offset; return *this; } SeqPulsNdim& SeqPulsNdim::operator = (const SeqPulsNdim& spnd) { Log odinlog(this,"operator = (...)"); SeqParallel::operator = (spnd); dims=spnd.get_dims(); gradshift=spnd.gradshift; objs->gx=spnd.objs->gx; objs->gy=spnd.objs->gy; objs->gz=spnd.objs->gz; objs->gx_delay=spnd.objs->gx_delay; objs->gy_delay=spnd.objs->gy_delay; objs->gz_delay=spnd.objs->gz_delay; objs->sgh=spnd.objs->sgh; objs->rftrain=spnd.objs->rftrain; objs->dgs=spnd.objs->dgs; objs->sp=spnd.objs->sp; build_seq(); return *this; } SeqPulsNdim& SeqPulsNdim::build_seq() { Log odinlog(this,"build_seq"); int dimensionality=get_dims(); ODINLOG(odinlog,normalDebug) << "dimensionality=" << dimensionality << STD_endl; objs->sgh.clear(); objs->rftrain.clear(); clear_gradptr(); double shift=systemInfo->get_grad_shift_delay()+gradshift-objs->sp.get_pulsstart(); bool have_dgs=false; bool have_grad_delays=false; if(shift>0.0) { have_dgs=true; objs->dgs.set_duration(shift); } if(shift<0.0) { have_grad_delays=true; objs->gx_delay=SeqGradDelay("gx_delay",readDirection,-shift); objs->gy_delay=SeqGradDelay("gy_delay",phaseDirection,-shift); objs->gz_delay=SeqGradDelay("gz_delay",sliceDirection,-shift); } if(dimensionality==3) { if(have_grad_delays) objs->sgh+=((objs->gx_delay+objs->gx)/(objs->gy_delay+objs->gy)/(objs->gz_delay+objs->gz)); else objs->sgh+=(objs->gx/objs->gy/objs->gz); } if(dimensionality==2) { if(have_grad_delays) objs->sgh+=((objs->gx_delay+objs->gx)/(objs->gy_delay+objs->gy)/(objs->gz_delay)); else objs->sgh+=(objs->gx/objs->gy); } if(dimensionality==1) { if(have_grad_delays) objs->sgh+=((objs->gx_delay)/(objs->gy_delay)/(objs->gz_delay+objs->gz)); else objs->sgh+=(objs->gz); double dummydur=objs->gz.get_gradduration(); ODINLOG(odinlog,normalDebug) << "dummydur=" << dummydur << STD_endl; } if(dimensionality) { if(have_dgs) objs->rftrain.append(objs->dgs); set_gradptr((SeqGradObjInterface*)&(objs->sgh)); } objs->rftrain.append(objs->sp); set_pulsptr(&(objs->rftrain)); return *this; } template class Handled; template class Handler; odin-1.8.5/odinseq/seqacqdeph.cpp0000644000175000017500000000312311322062345013660 00000000000000#include "seqacqdeph.h" #include "seqacq.h" void SeqAcqDeph::common_init() { dummyvec=SeqVector("dummyvec",1); // make one iteration the default, for dephasing of non-segmented EPI } SeqAcqDeph::SeqAcqDeph(const STD_string& object_label,const SeqAcqInterface& acq, dephaseMode mode) : SeqGradChanParallel(object_label) { Log odinlog(this,"SeqAcqDeph(...)"); common_init(); SeqGradChanParallel::clear(); const SeqVector* vec=acq.get_dephgrad(*this, mode==rephase); segvec.clear_handledobj(); if(vec) segvec.set_handled(vec); if(mode==spinEcho) { SeqGradChanParallel::invert_strength(); } ODINLOG(odinlog,normalDebug) << "integral(" << acq.get_label() << ")=" << SeqGradChanParallel::get_gradintegral().printbody() << STD_endl; } SeqAcqDeph::SeqAcqDeph(const SeqAcqDeph& sad) { common_init(); SeqAcqDeph::operator = (sad); } SeqAcqDeph::SeqAcqDeph(const STD_string& object_label) : SeqGradChanParallel(object_label) { common_init(); } SeqAcqDeph& SeqAcqDeph::operator = (const SeqAcqDeph& sad) { SeqGradInterface::operator = (sad); SeqGradChanParallel::operator = (sad); segvec=sad.segvec; return *this; } const SeqVector& SeqAcqDeph::get_epi_segment_vector() const { Log odinlog(this,"get_epi_segment_vector"); ODINLOG(odinlog,normalDebug) << "segvec.get_handled()=" << (void*)segvec.get_handled() << STD_endl; if(segvec.get_handled()) return *(segvec.get_handled()); return dummyvec; } const SeqVector& SeqAcqDeph::get_epi_reduction_vector() const { if(segvec.get_handled()) return segvec.get_handled()->get_reorder_vector(); return dummyvec; } odin-1.8.5/odinseq/seqgradramp.h0000644000175000017500000001451111322062345013520 00000000000000/*************************************************************************** seqgradramp.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADRAMP_H #define SEQGRADRAMP_H #include /** * @addtogroup odinseq * @{ */ /** * This enum is used to specify the shape of gradient ramp: * - linear: A ramp that linearly increases/decreases the gradient field. * The first ramp point has the initial gradient strength, the last point * the final gradient strength. With this selection, the integral over the * ramp is the same as that over a continuous triangular function, i.e * Integral = 1/2 * strength_difference * duration. * - sinusoidal: The sinus between -pi/2 and pi/2 is used for the gradient shape * - half_sinusoidal: The sinus between 0 and pi/2 is used for the gradient shape */ enum rampType {linear, sinusoidal, half_sinusoidal}; /////////////////////////////////////////////////////////// /** * \brief Gradient Ramp * * This class represents a digitized gradient ramp. */ class SeqGradRamp : public SeqGradWave { public: /** * Constructs a gradient ramp labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - initgradstrength: The initial gradient strength, i.e. the strength at the beginning of the ramp * - finalgradstrength: The final gradient strength, i.e. the strength at the end of the ramp * - timestep: The time between adjecent points of the ramp * - type: The shape for the ramp * - steepnessfactor: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible * - reverse: Reverse ramp calculation (only relevant for asymmetric ramps) */ SeqGradRamp(const STD_string& object_label,direction gradchannel, float initgradstrength, float finalgradstrength, double timestep,rampType type = linear, float steepnessfactor=1.0, bool reverse = false); /** * Constructs a gradient ramp labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradduration: The duration of this gradient object * - initgradstrength: The initial gradient strength, i.e. the strength at the beginning of the ramp * - finalgradstrength: The final gradient strength, i.e. the strength at the end of the ramp * - timestep: The time between adjecent points of the ramp * - type: The shape for the ramp * - reverse: Reverse ramp calculation (only relevant for asymmetric ramps) */ SeqGradRamp(const STD_string& object_label,direction gradchannel,double gradduration, float initgradstrength, float finalgradstrength, double timestep, rampType type = linear, bool reverse = false); /** * Constructs a copy of 'sgr' */ SeqGradRamp(const SeqGradRamp& sgr); /** * Construct an empty gradient object with the given label */ SeqGradRamp(const STD_string& object_label = "unnamedSeqGradRamp"); /** * Sets the ramp according to the following parameters: * - initgradstrength: The initial gradient strength, i.e. the strength at the beginning of the ramp * - finalgradstrength: The final gradient strength, i.e. the strength at the end of the ramp * - timestep: The time between adjecent points of the ramp * - type: The shape for the ramp * - steepnessfactor: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible * - reverse: Reverse ramp calculation (only relevant for asymmetric ramps) */ SeqGradRamp& set_ramp(float initgradstrength, float finalgradstrength, double timestep,rampType type = linear,float steepnessfactor=1.0, bool reverse = false); /** * Sets the ramp according to the following parameters: * - gradduration: The duration of this gradient object * - initgradstrength: The initial gradient strength, i.e. the strength at the beginning of the ramp * - finalgradstrength: The final gradient strength, i.e. the strength at the end of the ramp * - timestep: The time between adjecent points of the ramp * - type: The shape for the ramp * - reverse: Reverse ramp calculation (only relevant for asymmetric ramps) */ SeqGradRamp& set_ramp(double gradduration,float initgradstrength, float finalgradstrength, double timestep,rampType type = linear, bool reverse = false); /** * Returns the shape for the ramp */ rampType get_ramptype() const {return ramptype;} /** * Assignment operator that makes this gradient channel object become a copy of 'sgr' */ SeqGradRamp& operator = (const SeqGradRamp& sgr); // helper functions static fvector makeGradRamp(rampType type, float beginVal, float endVal, unsigned int n_vals, bool reverseramp); static unsigned int npts4ramp(rampType type, float beginVal, float endVal, float maxIncrement); static unsigned int npts4ramp(double totaldur, double timestep); // overloading functions from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); private: void generate_ramp(); float initstrength; float finalstrength; double dt; float steepness; bool steepcontrol; rampType ramptype; bool reverseramp; }; /** @} */ #endif odin-1.8.5/odinseq/seqplatform.h0000644000175000017500000001725211625224370013560 00000000000000/*************************************************************************** seqplatform.h - description ------------------- begin : Sat Apr 3 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPLATFORM_H #define SEQPLATFORM_H #include #include #include #include // Global Bruker stuff #define REFGAIN_FILE "odin_refgain" #define MAINNUC_FILE "odin_mainnuc" // forward declarations for hardware drivers class SeqAcqDriver; class SeqEpiDriver; class SeqDecouplingDriver; class SeqDelayDriver; class SeqDelayVecDriver; class SeqFreqChanDriver; class SeqGradChanDriver; class SeqGradChanParallelDriver; class SeqGradTrapezDriver; class SeqListDriver; class SeqCounterDriver; class SeqParallelDriver; class SeqPhaseDriver; class SeqPulsDriver; class SeqTriggerDriver; class eventContext; // forward declaration class ProgressMeter; // forward declaration ///////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Enum to specify data processing on the platform: * - odinReco: Store raw data on disk and call odinreco * - rawData: Store raw data on disk * - recoInfoOnly: Story only recoInfo file. Raw data has to be copied manually using Twix */ enum recoMode {odinReco=0, rawData, recoInfoOnly}; ///////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This class is used only for resolving ambiguities in constructors * of other classes during platform registration */ class PlatformRegistration {}; ///////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Virtual base class for all classes that represent an ODIN platform, * i.e. that deal with platform specific peculiarities */ class SeqPlatform : public virtual SeqClass { public: enum eventLogging {noLogging=0,loggEvent}; /** * Initialize platform, is called whenever a method is initialized. */ virtual void init() = 0; /** * This function is overloaded to clean up the platform interface before a new sequence is prepared. */ virtual void reset_before_prep() = 0; /** * This function is overloaded to prepare all the global stuff which is needed to start an experiment. * 'nacqs_total' must contain the total number of acqusition events in the the sequence. */ virtual void prepare_measurement(unsigned int nacqs_total) = 0; // functions for driver factory virtual SeqAcqDriver* create_driver(SeqAcqDriver*) const = 0; virtual SeqEpiDriver* create_driver(SeqEpiDriver*) const = 0; virtual SeqDecouplingDriver* create_driver(SeqDecouplingDriver*) const = 0; virtual SeqDelayDriver* create_driver(SeqDelayDriver*) const = 0; virtual SeqDelayVecDriver* create_driver(SeqDelayVecDriver*) const = 0; virtual SeqFreqChanDriver* create_driver(SeqFreqChanDriver*) const = 0; virtual SeqGradChanDriver* create_driver(SeqGradChanDriver*) const = 0; virtual SeqGradChanParallelDriver* create_driver(SeqGradChanParallelDriver*) const = 0; virtual SeqGradTrapezDriver* create_driver(SeqGradTrapezDriver*) const = 0; virtual SeqListDriver* create_driver(SeqListDriver*) const = 0; virtual SeqCounterDriver* create_driver(SeqCounterDriver*) const = 0; virtual SeqParallelDriver* create_driver(SeqParallelDriver*) const = 0; virtual SeqPhaseDriver* create_driver(SeqPhaseDriver*) const = 0; virtual SeqPulsDriver* create_driver(SeqPulsDriver*) const = 0; virtual SeqTriggerDriver* create_driver(SeqTriggerDriver*) const = 0; virtual int process(int argc, char *argv[]) = 0; virtual SeqCmdlineActionList get_actions_usage() const = 0; virtual void pre_event (eventContext& context) const = 0; virtual void post_event(eventContext& context) const = 0; virtual fvector get_acq_channel_scale_factors() const = 0; virtual STD_string get_program(programContext& context) const = 0; virtual STD_string get_rawfile() const = 0; virtual STD_string get_rawdatatype() const = 0; virtual unsigned int get_rawheader_size() const = 0; virtual STD_string get_image_proc() const = 0; virtual bool create_recoInfo() const = 0; virtual int write_rf_waveform (const STD_string& filename, const cvector& waveform) const = 0; virtual int load_rf_waveform (const STD_string& filename, cvector& result) const = 0; virtual int get_max_methodname_length() const = 0; virtual void set_eventlogging(eventLogging loggflag) = 0; // Paravision specific virtual bool pv_pilot(ProgressMeter* progmeter) {return true;} virtual STD_string pv_pilot_scan() const {return "";} virtual bool pv_gop(bool autorg, ProgressMeter* progmeter) {return true;} virtual bool pv_stop() {return true;} // IDEA specific virtual void set_idea_pars(void* pMrProt,void* pSeqLim,void* pSeqExpo, recoMode reco_mode) {} // StandAlone specific virtual SeqPlotDataAbstract* get_plot_data() {return 0;} virtual bool create_plot_events(ProgressMeter* progmeter) {return true;} virtual ~SeqPlatform() {} protected: SeqPlatform() {} }; ///////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Singleton to hold platform instances (driver factories) */ class SeqPlatformInstances : public SeqClass { public: SeqPlatformInstances(); ~SeqPlatformInstances(); bool set_current(odinPlatform pf); SeqPlatform* get_current() {return instance[get_current_platform_id()];} odinPlatform get_current_platform_id() {return SystemInterface::get_current_pf();} private: friend class SeqPlatformProxy; SeqPlatform* instance[numof_platforms]; static odinPlatform pf_during_platform_construction; }; //////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The proxy class for platform specific classes */ class SeqPlatformProxy : public virtual SeqClass, public StaticHandler { public: SeqPlatformProxy() {set_label("SeqPlatformProxy");} static void set_current_platform(odinPlatform pF); static odinPlatform get_current_platform(); static int load_systemInfo(const STD_string& filename); static STD_string get_platform_str(odinPlatform pF); static svector get_possible_platforms(); static STD_string get_platforms_usage(); static int get_platform_for_action(const STD_string& action); SeqPlatform& operator * () {return *get_platform_ptr();} SeqPlatform* operator -> () {return get_platform_ptr();} // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); private: friend class SeqPlatform; // manually allocate of platform instances static void create_platform_instances(); static SeqPlatform* get_platform_ptr(); // manage platform instances (driver factories) static SingletonHandler platforms; }; #endif odin-1.8.5/odinseq/seqgradchanparallel.cpp0000644000175000017500000002263311322062345015546 00000000000000#include "seqgradchanparallel.h" #include "seqgradconst.h" SeqGradChanParallel::SeqGradChanParallel(const STD_string& object_label) : SeqGradObjInterface(object_label), paralleldriver(object_label) { } SeqGradChanParallel::SeqGradChanParallel(const SeqGradChanParallel& sgcp) : paralleldriver(sgcp.get_label()) { Log odinlog(this,"SeqGradChanParallel"); SeqGradChanParallel::operator = (sgcp); } SeqGradChanParallel::~SeqGradChanParallel() { Log odinlog(this,"~SeqGradChanParallel"); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) get_gradchan(chanNo)->clear(); } } SeqGradChanParallel& SeqGradChanParallel::operator = (const SeqGradChanParallel& sgcp) { Log odinlog(this,"operator = (...)"); SeqGradObjInterface::operator = (sgcp); paralleldriver=sgcp.paralleldriver; clear(); // create deep copy for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); SeqGradChanList* sgcl=sgcp.get_gradchan(chanNo); if(sgcl) { SeqGradChanList* my_sgcl=get_gradchan(chanNo); if(my_sgcl) (*my_sgcl)=(*sgcl); else { ODINLOG(odinlog,normalDebug) << "creating copy of " << sgcl->get_label() << STD_endl; SeqGradChanList* sgcl_copy=new SeqGradChanList(*sgcl); sgcl_copy->set_temporary(); set_gradchan(chanNo,sgcl_copy); } } } return *this; } SeqGradChanParallel& SeqGradChanParallel::operator /= (SeqGradChan& sgc) { Log odinlog(this,"operator /= (SeqGradChan&)"); direction chanNo=sgc.get_channel(); SeqGradChanList* sgcl=get_gradchan(chanNo); if(sgcl) { sgcl->clear(); } else { sgcl=new SeqGradChanList("("+sgc.get_label()+")"); sgcl->set_temporary(); set_gradchan(chanNo,sgcl); } (*sgcl)+=sgc; return *this; } SeqGradChanParallel& SeqGradChanParallel::operator /= (SeqGradChanList& sgcl) { Log odinlog(this,"operator /= (SeqGradChanList&)"); set_gradchan(sgcl.get_channel(),&sgcl); return *this; } STD_string SeqGradChanParallel::get_program(programContext& context) const { return paralleldriver->get_program(context); } bool SeqGradChanParallel::prep() { Log odinlog(this,"prep"); if(!SeqGradObjInterface::prep()) return false; SeqGradChanList* chanlists[3]; for(unsigned int i=0; i<3; i++) chanlists[i]=get_gradchan(direction(i)); return paralleldriver->prep_driver(chanlists); } SeqGradInterface& SeqGradChanParallel::set_strength(float gradstrength) { Log odinlog(this,"set_strength"); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) get_gradchan(chanNo)->set_strength(gradstrength); } return *this; } SeqGradInterface& SeqGradChanParallel::invert_strength() { Log odinlog(this,"invert_strength"); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) get_gradchan(chanNo)->invert_strength(); } return *this; } float SeqGradChanParallel::get_strength() const { Log odinlog(this,"get_strength"); float result=0.0; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); float tmp=0.0; if(get_gradchan(chanNo)) tmp=get_gradchan(chanNo)->get_strength(); if(fabs(tmp)>fabs(result)) result=tmp; } return result; } double SeqGradChanParallel::get_gradduration() const { Log odinlog(this,"get_gradduration"); double result=0.0; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); double chandur=0.0; if(get_gradchan(chanNo)) chandur=fabs(get_gradchan(chanNo)->get_gradduration()); if( chandur > result) result=chandur; } return result; } SeqGradInterface& SeqGradChanParallel::set_gradrotmatrix(const RotMatrix& matrix) { Log odinlog(this,"set_gradrotmatrix"); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) get_gradchan(chanNo)->set_gradrotmatrix(matrix); } return *this; } fvector SeqGradChanParallel::get_gradintegral() const { Log odinlog(this,"get_gradintegral"); fvector result(3); result=0.0; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) result=result+(get_gradchan(chanNo)->get_gradintegral()); } ODINLOG(odinlog,normalDebug) << "result=" << result.printbody() << STD_endl; return result; } SeqGradChanParallel& SeqGradChanParallel::operator += (SeqGradChan& sgc) { Log odinlog(this,"SeqGradChanParallel::operator += (SeqGradChan)"); ODINLOG(odinlog,normalDebug) << "appending " << sgc.get_label() << STD_endl; direction chanNo=sgc.get_channel(); padd_channel_with_delay(chanNo, get_gradduration()); if(get_gradchan(chanNo)) { (*get_gradchan(chanNo))+=sgc; } else { SeqGradChanList* sgcl=new SeqGradChanList(STD_string("(")+get_label()+")"); sgcl->set_temporary(); (*sgcl)+=sgc; set_gradchan(chanNo,sgcl); } return *this; } SeqGradChanParallel& SeqGradChanParallel::operator += (SeqGradChanList& sgcl) { Log odinlog(this,"SeqGradChanParallel::operator += (SeqGradChanList)"); direction chanNo=sgcl.get_channel(); padd_channel_with_delay(chanNo, get_gradduration()); if(get_gradchan(chanNo)) { ODINLOG(odinlog,normalDebug) << "appending " << sgcl.get_label() << STD_endl; (*get_gradchan(chanNo))+=sgcl; } else { ODINLOG(odinlog,normalDebug) << "creating copy of " << sgcl.get_label() << STD_endl; SeqGradChanList* sgcl_copy=new SeqGradChanList(sgcl); sgcl_copy->set_temporary(); set_gradchan(chanNo,sgcl_copy); } return *this; } SeqGradChanParallel& SeqGradChanParallel::operator += (SeqGradChanParallel& sgcp) { Log odinlog(this,"operator += (SeqGradChanParallel)"); ODINLOG(odinlog,normalDebug) << "appending " << sgcp.get_label() << STD_endl; double maxdur=get_gradduration(); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(sgcp.get_gradchan(chanNo)) { padd_channel_with_delay(chanNo,maxdur); if(get_gradchan(chanNo)) (*get_gradchan(chanNo))+=(*sgcp.get_gradchan(chanNo)); else { ODINLOG(odinlog,normalDebug) << "creating copy of " << sgcp.get_label() << STD_endl; SeqGradChanList* sgcl_copy=new SeqGradChanList(*(sgcp.get_gradchan(chanNo))); sgcl_copy->set_temporary(); set_gradchan(chanNo,sgcl_copy); } } } return *this; } void SeqGradChanParallel::clear() { Log odinlog(this,"clear"); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { gradchan[cn].clear_handledobj(); } } unsigned int SeqGradChanParallel::event(eventContext& context) const { unsigned int result=0; double startelapsed=context.elapsed; double maxelapsed=context.elapsed; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { context.elapsed=startelapsed; direction chanNo=direction(cn); if(get_gradchan(chanNo)) { result+=get_gradchan(chanNo)->event(context); if(context.elapsed>maxelapsed) maxelapsed=context.elapsed; } } context.elapsed=maxelapsed; return result; } void SeqGradChanParallel::clear_container() {clear();} void SeqGradChanParallel::query(queryContext& context) const { SeqTreeObj::query(context); // defaults if(context.action==count_acqs) return; // nothing to do context.treelevel++; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { context.parentnode=this; // reset to this because it might changed by last query SeqGradChanList* sgcl=get_gradchan(direction(cn)); if(sgcl) sgcl->query(context); } context.treelevel--; } STD_string SeqGradChanParallel::get_properties() const { STD_string result="ChanListSize="; for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(get_gradchan(chanNo)) result+=itos(get_gradchan(chanNo)->size()); else result+="-"; if(cn!=sliceDirection) result+="/"; } return result; } void SeqGradChanParallel::padd_channel_with_delay(direction chanNo, double maxdur) { Log odinlog(this,"padd_channel_with_delay"); ODINLOG(odinlog,normalDebug) << "maxdur=" << maxdur << STD_endl; if(!maxdur) return; double chandur=0.0; if(get_gradchan(chanNo)) chandur=fabs(get_gradchan(chanNo)->get_gradduration()); if( chandur < maxdur) { ODINLOG(odinlog,normalDebug) << "chandur[" << chanNo << "]=" << chandur << STD_endl; SeqGradDelay* graddelay=new SeqGradDelay(STD_string(get_label())+"_paddelay",chanNo,maxdur-chandur); graddelay->set_temporary(); if(get_gradchan(chanNo)) { ODINLOG(odinlog,normalDebug) << "appending to existing SeqGradChanList" << STD_endl; (*get_gradchan(chanNo))+=(*graddelay); } else { ODINLOG(odinlog,normalDebug) << "creating new SeqGradChanList" << STD_endl; SeqGradChanList* sgcl=new SeqGradChanList(STD_string("(")+graddelay->get_label()+")"); sgcl->set_temporary(); (*sgcl)+=(*graddelay); set_gradchan(chanNo,sgcl); } } } SeqGradChanList* SeqGradChanParallel::get_gradchan(direction channel) const { return (gradchan[channel]).get_handled(); } SeqGradChanParallel& SeqGradChanParallel::set_gradchan(direction channel, SeqGradChanList* sgcl) { if(sgcl) (gradchan[channel]).set_handled(sgcl); return *this; } odin-1.8.5/odinseq/seqdelayvec.h0000644000175000017500000000662511322062345013526 00000000000000/*************************************************************************** seqdelayvec.h - description ------------------- begin : Mon Oct 7 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDELAYVEC_H #define SEQDELAYVEC_H #include #include #include /** * @ingroup odinseq_internals * The base class for platform specific drivers of delay vectors */ class SeqDelayVecDriver : public SeqDriverBase { public: SeqDelayVecDriver() {} virtual ~SeqDelayVecDriver() {} virtual bool prep_driver() = 0; virtual STD_string get_program(programContext& context, double duration) const = 0; virtual bool unroll_program() const = 0; virtual SeqDelayVecDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Vector of variable timing delays * * This class represents a vector of delay (delay list) that can be attached to a loop. */ class SeqDelayVector : public SeqObjBase, public SeqVector { public: /** * Constructs a delay vector labeled 'object_label' with the following properties: * - delaylist: The list of delays that will be played out subsequently when looping * over this object */ SeqDelayVector(const STD_string& object_label,const dvector& delaylist); /** * Constructs an empty delay vector labeled 'object_label' */ SeqDelayVector(const STD_string& object_label = "unnamedSeqDelayVector"); /** * Constructs a delay which is a copy of 'sdv' */ SeqDelayVector(const SeqDelayVector& sdv); /** * This assignment operator will make this object become an exact copy of 'sdv'. */ SeqDelayVector& operator = (const SeqDelayVector& sdv); /** * Specifies the list of delays that will be played out subsequently when looping * over this object */ SeqDelayVector& set_delayvector(const dvector& delaylist); /** * Returns the list of delays that will be played out subsequently when looping * over this object */ dvector get_delayvector() const; // overloading virtual function from SeqTreeObj double get_duration() const; STD_string get_program(programContext& context) const; SeqValList get_delayvallist() const; private: // overwriting virtual functions from SeqClass bool prep(); // overloading virtual function from SeqVector unsigned int get_vectorsize() const; bool needs_unrolling_check() const {return delayvecdriver->unroll_program();} mutable SeqDriverInterface delayvecdriver; dvector delayvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqacq.h0000644000175000017500000002707511455553540012511 00000000000000/*************************************************************************** seqacq.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQ_H #define SEQACQ_H #include #include #include #include #include class SeqGradChanParallel; // forward declaration //////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This is the abstract base class for all objects that have the * property of acquiring a signal */ class SeqAcqInterface : public virtual SeqFreqChanInterface { public: /** * Returns the duration of the acquisition window without padding delays. */ virtual double get_acquisition_duration() const {if(marshall) return marshall->get_acquisition_duration(); else marshall_error(); return 0.0;} /** * Returns the the duration from the the beginnig of the acquisition * object to the middle of the acquisition window. */ virtual double get_acquisition_center() const {if(marshall) return marshall->get_acquisition_center(); else marshall_error(); return 0.0;} /** * Returns the the duration from the the beginnig of the acquisition * object to the beginnig of the acquisition window (the point * of time where data starts to be acquired). */ virtual double get_acquisition_start() const {if(marshall) return marshall->get_acquisition_start(); else marshall_error(); return 0.0;} /** * Returns the total number of sampling points, without oversampling */ virtual unsigned int get_npts() const {if(marshall) return marshall->get_npts(); else marshall_error(); return 0;} /** * Sets the sweepwidth 'sw' without oversampling and oversampling factor 'os_factor' for this acquisition object, os_factor=1 means no oversampling. */ virtual SeqAcqInterface& set_sweepwidth(double sw, float os_factor) {if(marshall) marshall->set_sweepwidth(sw,os_factor); else marshall_error(); return *this;} /** * Returns the sweepwidth factor */ virtual double get_sweepwidth() const {if(marshall) return marshall->get_sweepwidth(); else marshall_error(); return 0.0;} /** * Returns the oversampling factor */ virtual float get_oversampling() const {if(marshall) return marshall->get_oversampling(); else marshall_error(); return 0.0;} /** * Specifies a regridding matrix for this ADC (for automatic reconstruction) */ virtual SeqAcqInterface& set_readout_shape(const fvector& shape, unsigned int dstsize) {if(marshall) marshall->set_readout_shape(shape, dstsize); else marshall_error(); return *this;} /** * Specifies a vector 'vec' which indexes the data dimension 'dim'. * The current index for each acquisition is retrieved from the vector. * This is relevant for automatic reconstruction. * An additional vector 'valvec' of double values can be given, * which is attached to this dimension, e.g. different TEs in the echo * dimension. */ virtual SeqAcqInterface& set_reco_vector(recoDim dim, const SeqVector& vec, const dvector& valvec=dvector()) {if(marshall) marshall->set_reco_vector(dim, vec, valvec); else marshall_error(); return *this;} /** * Sets the default value 'index' for the reco index in dimension 'dim'. * This is relevant for automatic reconstruction. */ virtual SeqAcqInterface& set_default_reco_index(recoDim dim, unsigned int index) {if(marshall) marshall->set_default_reco_index(dim, index); else marshall_error(); return *this;} /** * Sets the template mode of this acquisition object. * This is also relevant for automatic reconstruction. */ virtual SeqAcqInterface& set_template_type(templateType type) {if(marshall) marshall->set_template_type(type); return set_default_reco_index(templtype,type);} /** * Specifies whether the data points should be reversed, only relevant * for automatic reconstruction */ virtual SeqAcqInterface& set_reflect_flag(bool flag) {if(marshall) marshall->set_reflect_flag(flag); else marshall_error(); return *this;} protected: SeqAcqInterface() : marshall(0) {} virtual ~SeqAcqInterface() {} void set_marshall(SeqAcqInterface* mymarshall) {marshall=mymarshall;} // to be used in constructor code private: friend class SeqAcqDeph; // to be used by SeqAcqDeph to retrieve pre-dephasing gradients from acquisition object. // Overload this function if your acq needs pre-dephasers, return them by appending them to 'dephobj'. // Returns any possible vector object as the return value. virtual const SeqVector* get_dephgrad(SeqGradChanParallel& dephobj, bool rephase) const {if(marshall) return marshall->get_dephgrad(dephobj,rephase); return 0;} SeqAcqInterface* marshall; // for marshalling member functions to a sub-object }; ///////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of acquisition windows */ class SeqAcqDriver : public SeqDriverBase { public: SeqAcqDriver() {} virtual ~SeqAcqDriver() {} /** * Returns possible sweepwidth closest to 'desired_sweep_widht' */ virtual double adjust_sweepwidth(double desired_sweep_widht) const = 0; /** * Prepare driver, let driver adjust reco coordinate 'recoindex' */ virtual bool prep_driver(kSpaceCoord& recoindex, double sweepwidth, unsigned int nAcqPoints, double acqcenter, int freqchannel) = 0; /** * Delay prior to actual acquisition */ virtual double get_predelay() const = 0; /** * Delay following actual acquisition depending on 'sweepwidth' */ virtual double get_postdelay(double sweepwidth) const = 0; virtual void event(eventContext& context, double start) const = 0; virtual STD_string get_program(programContext& context, unsigned int phaselistindex) const = 0; virtual STD_string get_instr_label() const = 0; virtual unsigned int get_numof_channels() const = 0; virtual SeqAcqDriver* clone_driver() const = 0; }; ///////////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Acquisition * * This class represents an acquisition window */ class SeqAcq : public virtual SeqAcqInterface, public SeqObjBase, public SeqFreqChan { public: /** * Constructs an acquisition window labeled 'object_label' with the following properties: * - nAcqPoints: The number of sampling points that will be acquired during the acquisition * - sweepwidth: The sampling frequency without oversampling * - os_factor: The oversampling factor, os_factor=1 means no oversampling * - nucleus: The nucleus for which the acquisition should be performed. The default * is to acquire on the protons resonance freuency. * - phaselist: This is an array of phases at which the acquired signal will be * demodulated. The actual phase for each acquisition is determined * by cycling through this array of phases which are represented * in degree. * - freqlist: This is an array of frequency offsets at which the acquired signal * will be demodulated. */ SeqAcq(const STD_string& object_label, unsigned int nAcqPoints, double sweepwidth, float os_factor=1.0, const STD_string& nucleus="", const dvector& phaselist=0,const dvector& freqlist=0); /** * Constructs an acquisition window which is a copy of 'sa' */ SeqAcq(const SeqAcq& sa); /** * Constructs an empty acquisition window with the given label. */ SeqAcq(const STD_string& object_label="unnamedSeqAcq"); /** * Destructor */ ~SeqAcq(); /** * Sets the number of sampling points that will be acquired during the acquisition */ SeqAcq& set_npts(unsigned int nAcqPoints); /** * Returns the sweep width */ double get_sweep_width() const {return sweep_width;} /** * This assignment operator will make this object become an exact copy of 'sa'. */ SeqAcq& operator = (const SeqAcq& sa); /** * Specifies a an explicit k-space Trajectory for this ADC (for automatic reconstruction) */ void set_kspace_traj(const farray& kspaceTraj); /** * Specifies a complex vector which is is used to weight each point in this ADC (for automatic reconstruction) */ void set_weight_vec(const cvector& weightVec); /** * Sets the relative point in time (between 0 and 1) when k-space center is passed, the default is 0.5. * Will be used in get_acquisition_center(). */ SeqAcq& set_rel_center(double relative_kspace_center) {rel_center=relative_kspace_center; return *this;} /** * Returns the k-space index of this ADCs */ const kSpaceCoord& get_kcoord() const; // overwriting virtual functions of SeqAcqInterface double get_acquisition_duration() const {return secureDivision(npts,sweep_width);} double get_acquisition_center() const; double get_acquisition_start() const {return acqdriver->get_predelay();} unsigned int get_npts() const {return npts;} SeqAcqInterface& set_sweepwidth(double sw, float os_factor); double get_sweepwidth() const {return sweep_width;} float get_oversampling() const {return oversampl;} SeqAcqInterface& set_readout_shape(const fvector& shape, unsigned int dstsize); SeqAcqInterface& set_reco_vector(recoDim dim, const SeqVector& vec, const dvector& valvec=dvector()); SeqAcqInterface& set_default_reco_index(recoDim dim, unsigned int index); SeqAcqInterface& set_reflect_flag(bool flag) {reflect_flag=flag; return *this;} // overwriting virtual functions of SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; SeqValList get_freqvallist(freqlistAction action) const; void query(queryContext& context) const {SeqTreeObj::query(context); context.numof_acqs=1;} RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; unsigned int event(eventContext& context) const; STD_string get_properties() const; private: friend class SeqMethod; friend class SeqEpiDriverParavision; friend class SeqEpiDriverEpic; void common_init(); // overwriting virtual functions of SeqFreqChan double get_freqchan_duration() const {return get_acquisition_duration();} STD_string get_driver_instr_label() const {return acqdriver->get_instr_label();} // overwriting virtual functions of SeqClass bool prep(); mutable kSpaceCoord kcoord; mutable SeqDriverInterface acqdriver; double sweep_width; unsigned int npts; float oversampl; double rel_center; bool reflect_flag; int readoutIndex; int trajIndex; int weightIndex; // safe pointers to vectors to create indices for the ADC // pointer to pointer is used here to avoid delete[] bug in GCC2.9 Handler** dimvec; int default_recoindex[n_recoIndexDims]; }; /** @} */ #endif odin-1.8.5/odinseq/seqall.h0000644000175000017500000000211411625224370012473 00000000000000#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include odin-1.8.5/odinseq/seqdec.h0000644000175000017500000001220111322062345012450 00000000000000/*************************************************************************** seqdec.h - description ------------------- begin : Fri Sep 7 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDEC_H #define SEQDEC_H #include #include #include #include #include /** * @ingroup odinseq_internals * The base class for platform specific drivers of decoupling periods */ class SeqDecouplingDriver : public SeqDriverBase { public: SeqDecouplingDriver() {} virtual ~SeqDecouplingDriver() {} virtual bool prep_driver(double decdur, int channel, float decpower, const STD_string& program, double pulsedur) = 0; virtual void event(eventContext& context, double start) const = 0; virtual double get_preduration() const = 0; virtual double get_postduration() const = 0; virtual STD_string get_preprogram(programContext& context, const STD_string& iteratorcommand) const = 0; virtual STD_string get_postprogram(programContext& context) const = 0; virtual SeqDecouplingDriver* clone_driver() const = 0; }; //////////////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Decoupling period * * This class represents a decoupling container which can hold a part * of the sequence where decoupling is switched on. */ class SeqDecoupling : public SeqObjList, public Embed, public SeqFreqChan { public: /** * Constructs a container for a sequence part at which decoupling will be switched on * with the following properties: * - nucleus: The nucleus for which the decoupling should be performed. * - decpower: The maximum power for the decoupling program. * - freqlist: Frequency list for the decoupler. * - decprog: The file name of the decoupling program which will be used. If none * is specified, continuous wave decouling will be used. * - decpulsduration: If a decoupling program is given, this parameter determines * the pulse duration of each single pulse in a composite pulse * decoupling scheme. */ SeqDecoupling(const STD_string& object_label,const STD_string& nucleus,float decpower,const dvector& freqlist=0, const STD_string decprog="",float decpulsduration=0.0); /** * Constructs a decoupling container which is a copy of 'sd' */ SeqDecoupling(const SeqDecoupling& sd); /** * Constructs an empty decoupling container with the given label. */ SeqDecoupling(const STD_string& object_label="unnamedSeqDecoupling"); /** * This function specifies that during the sequence part 'so' decoupling * will be switched on. */ SeqDecoupling& operator () (const SeqObjBase& so); /** * Returns the decoupling power */ float get_decpower() const {return power;} /** * Sets the decoupling power */ void set_decpower(float p) {power=p;} /** * Returns the decoupling program */ STD_string get_program() const; /** * Sets the decoupling program */ void set_program(const STD_string& p); /** * Returns the decoupling pulse duration for Composite Pulse Decoupling */ double get_pulsduration() const; /** * Sets the decoupling pulse duration for Composite Pulse Decoupling */ void set_pulsduration(float d); /** * This assignment operator will make this object become an exact copy of 'sd'. */ SeqDecoupling& operator = (const SeqDecoupling& sd); // implementing virtual functions of SeqTreeObj double get_duration() const; unsigned int event(eventContext& context) const; // overwriting virtual function from SeqFreqChan STD_string get_program(programContext& context) const; double get_freqchan_duration() const {return get_duration();} unsigned int get_freqlistindex() const {return 2;} const SeqVector& get_freqlist_vector() const; SeqValList get_freqvallist(freqlistAction action) const; void clear_container(); private: friend class Embed; int set_body(const SeqObjBase& so); // overwriting virtual functions from SeqClass bool prep(); float power; STD_string decprogram; double pulsduration; mutable SeqDriverInterface decdriver; SeqSimultanVector instvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqdur.h0000644000175000017500000000432611322062345012520 00000000000000/*************************************************************************** seqdur.h - description ------------------- begin : Wed Aug 14 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDUR_H #define SEQDUR_H #include /** * @addtogroup odinseq_internals * @{ */ /** * This is the base class for all objects which have a certain * duration. This is one of the base classes for all 'sequence atoms' * i.e. those classes which cannot be devided further (e.g. SeqPuls, SeqAcq, SeqDelay, ...). * In contrast, the duration of composite objects (e.g. SeqObjList) * is calculated from their elements. */ class SeqDur : public virtual SeqTreeObj { public: /** * Construct a duration object with the given 'object_label' and the specified 'duration' */ SeqDur(const STD_string& object_label, float duration); /** * Construct an empty duration object with the given label */ SeqDur(const STD_string& object_label="unnamedSeqDur"); /** * Construct a duration object which is a copy of 'sd' */ SeqDur(const SeqDur& sd); /** * Sets the duration */ SeqDur& set_duration(float duration); // implementing virtual functions of SeqTreeObj double get_duration() const; /** * Assignment operator that makes this duration object become a copy of 'sd' */ SeqDur& operator = (const SeqDur& sd); private: double dur; }; /** @} */ #endif odin-1.8.5/odinseq/seqgradramp.cpp0000644000175000017500000001727711322062345014067 00000000000000#include "seqgradramp.h" fvector SeqGradRamp::makeGradRamp(rampType type, float beginVal, float endVal, unsigned int n_vals, bool reverseramp) { unsigned int i; fvector result(n_vals); if(n_vals==1) { result[0]=0.5*(beginVal+endVal); return result; } if(type==linear) result.fill_linear(beginVal,endVal); if(type==sinusoidal) { for(i=0; i odinlog(this,"SeqGradRamp(1...)"); initstrength=initgradstrength; finalstrength=finalgradstrength; dt=timestep; steepness=steepnessfactor; steepcontrol=true; ramptype=type; reverseramp=reverse; generate_ramp(); } SeqGradRamp::SeqGradRamp(const STD_string& object_label,direction gradchannel,double gradduration, float initgradstrength, float finalgradstrength, double timestep, rampType type, bool reverse) : SeqGradWave(object_label,gradchannel,gradduration,0.0,JDXfloatArr()) { Log odinlog(this,"SeqGradRamp(2...)"); initstrength=initgradstrength; finalstrength=finalgradstrength; dt=timestep; steepness=secureDivision(fabs(finalgradstrength-initgradstrength), gradduration*systemInfo->get_max_slew_rate()); ODINLOG(odinlog,normalDebug) << "steepness=" << steepness << STD_endl; steepcontrol=false; ramptype=type; reverseramp=reverse; generate_ramp(); } SeqGradRamp::SeqGradRamp(const SeqGradRamp& sgr) { SeqGradRamp::operator = (sgr); } SeqGradRamp::SeqGradRamp(const STD_string& object_label) : SeqGradWave(object_label) { Log odinlog(this,"SeqGradRamp(const STD_string&)"); initstrength=0.0; finalstrength=0.0; dt=0.0; steepness=1.0; steepcontrol=false; ramptype=linear; reverseramp=false; } SeqGradRamp& SeqGradRamp::set_ramp(float initgradstrength, float finalgradstrength, double timestep,rampType type,float steepnessfactor, bool reverse) { initstrength=initgradstrength; finalstrength=finalgradstrength; dt=timestep; steepness=steepnessfactor; if(steepness==0.0) steepcontrol=false; else steepcontrol=true; ramptype=type; reverseramp=reverse; generate_ramp(); return *this; } SeqGradRamp& SeqGradRamp::set_ramp(double gradduration,float initgradstrength, float finalgradstrength, double timestep,rampType type, bool reverse) { Log odinlog(this,"set_ramp"); set_duration(gradduration); initstrength=initgradstrength; finalstrength=finalgradstrength; dt=timestep; steepness=secureDivision(fabs(finalgradstrength-initgradstrength), gradduration*systemInfo->get_max_slew_rate()); ODINLOG(odinlog,normalDebug) << "steepness=" << steepness << STD_endl; steepcontrol=false; ramptype=type; reverseramp=reverse; generate_ramp(); return *this; } SeqGradRamp& SeqGradRamp::operator = (const SeqGradRamp& sgr) { SeqGradWave::operator = (sgr); initstrength=sgr.initstrength; finalstrength=sgr.finalstrength; dt=sgr.dt; steepness=sgr.steepness; steepcontrol=sgr.steepcontrol; ramptype=sgr.ramptype; reverseramp=sgr.reverseramp; return *this; } SeqGradInterface& SeqGradRamp::set_strength(float gradstrength) { Log odinlog(this,"set_strength"); float oldstrength=SeqGradWave::get_strength(); float maxstrength=secureDivision(fabs(oldstrength), steepness); float val=gradstrength; ODINLOG(odinlog,normalDebug) << "old/max/val/steepness=" << oldstrength << "/" << maxstrength << "/" << val << "/" << steepness << STD_endl; float sign=secureDivision(gradstrength, fabs(gradstrength)); if(fabs(gradstrength) > fabs(maxstrength)) { val=sign*maxstrength; ODINLOG(odinlog,warningLog) << "limiting strength to " << val << STD_endl; } SeqGradWave::set_strength(val); return *this; } void SeqGradRamp::generate_ramp() { Log odinlog(this,"generate_ramp"); if(steepness<=0.0) { steepness=1.0; } if(steepness>1.0) { ODINLOG(odinlog,warningLog) << "steepness(" << steepness << ")>1, setting to 1" << STD_endl; steepness=1.0; } float gradstrength=0.0; bool init_is_max=false; if(fabs(initstrength) > fabs(gradstrength)) {init_is_max=true; gradstrength=initstrength;} if(fabs(finalstrength) > fabs(gradstrength)) gradstrength=finalstrength; SeqGradWave::set_strength(gradstrength); ODINLOG(odinlog,normalDebug) << "get_duration()/dt=" << get_duration() << "/" << dt << STD_endl; unsigned int npts; if (steepcontrol) { ODINLOG(odinlog,normalDebug) << "in steepcontrol mode" << STD_endl; double maxIncr=steepness*dt*systemInfo->get_max_slew_rate(); ODINLOG(odinlog,normalDebug) << "maxIncr=" << maxIncr << STD_endl; npts=npts4ramp(ramptype,initstrength,finalstrength,maxIncr); ODINLOG(odinlog,normalDebug) << "npts=" << npts << STD_endl; set_duration(npts*dt); } else { ODINLOG(odinlog,normalDebug) << "NOT in steepcontrol mode" << STD_endl; npts=npts4ramp(get_duration(),dt); double maxIncr=dt*systemInfo->get_max_slew_rate(); unsigned int npts_ramp=npts4ramp(ramptype,initstrength,finalstrength,maxIncr); ODINLOG(odinlog,normalDebug) << "initstrength/finalstrength=" << initstrength << "/" << finalstrength << STD_endl; ODINLOG(odinlog,normalDebug) << "npts/maxIncr/npts_ramp=" << npts << "/" << maxIncr << "/" << npts_ramp << STD_endl; if(npts_ramp>npts) { ODINLOG(odinlog,warningLog) << "ramp too short (" << (npts*dt) << "), setting to " << (npts_ramp*dt) << STD_endl; npts=npts_ramp; set_duration(npts*dt); } } fvector rampwav(npts); float rel_initstrength=secureDivision(initstrength,gradstrength); float rel_finalstrength=secureDivision(finalstrength,gradstrength); if(init_is_max) { if(rel_initstrength<0.0) { rel_initstrength=-rel_initstrength; rel_finalstrength=-rel_finalstrength; } } else { if(rel_finalstrength<0.0) { rel_initstrength=-rel_initstrength; rel_finalstrength=-rel_finalstrength; } } ODINLOG(odinlog,normalDebug) << "rel_initstrength/rel_finalstrength=" << rel_initstrength << "/" << rel_finalstrength << STD_endl; rampwav=makeGradRamp(ramptype,rel_initstrength,rel_finalstrength,npts,reverseramp); ODINLOG(odinlog,normalDebug) << "max/minvalue=" << rampwav.maxvalue() << "/" << rampwav.minvalue() << STD_endl; set_wave(rampwav); } odin-1.8.5/odinseq/seqobj.h0000644000175000017500000000304311322062345012473 00000000000000/*************************************************************************** seqobj.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQOBJ_H #define SEQOBJ_H #include #include #include /** * @addtogroup odinseq_internals * @{ */ /** * Base class for elements in a list of sequence objects. */ class SeqObjBase : public ListItem, public virtual SeqTreeObj, public Handled { protected: SeqObjBase(const STD_string& object_label="unnamedSeqObjBase"); SeqObjBase(const SeqObjBase& soa); SeqObjBase& operator = (const SeqObjBase& soa); }; /** @} */ #endif odin-1.8.5/odinseq/seqdriver_epic.cpp0000644000175000017500000000167111322062345014554 00000000000000#ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #ifdef EPIC_PLUGIN #include "../platforms/EPIC/odinseq_epic/seqepic.cpp" #include "../platforms/EPIC/odinseq_epic/seqacq_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqacqepi_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqcounter_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqdec_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqdelay_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqfreq_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqgradchan_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqgradtrapez_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqlist_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqparallel_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqphase_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqpuls_epic.cpp" #include "../platforms/EPIC/odinseq_epic/seqtrigg_epic.cpp" #endif odin-1.8.5/odinseq/seqsat.h0000644000175000017500000000776211322062345012524 00000000000000/*************************************************************************** seqsat.h - description ------------------- begin : Tue Oct 19 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQSAT_H #define SEQSAT_H #include #include /** * @addtogroup odinseq * @{ */ /** * * Enum to specifiy saturation component: * - fat: lipid protons will be saturated * - water: water protons will be saturated */ enum satNucleus {fat=0,water}; //////////////////////////////////////////////////////////////////////////// /** * * \brief Saturation pulse * * A 90deg Gaussian shaped saturation pulse * */ class SeqPulsarSat : public SeqPulsar { public: /** * Constructs saturation pulse labeled 'object_label' with the following properties: * - nuc: the nucleus to saturate * - bandwidth: The bandwidth in kHz */ SeqPulsarSat(const STD_string& object_label="unnamedSeqPulsarSat", satNucleus nuc=fat,float bandwidth=0.3); /** * Constructs a saturation pulse labeled 'object_label' with the following properties: * - bandwidth: The bandwidth in kHz * - freqoffset: Frequency offset relative to the base frequency * - flipangle: The flipangle * - rel_filterwidth: Pulse width */ SeqPulsarSat(const STD_string& object_label,float bandwidth, double freqoffset=0.0, float flipangle=90.0, float rel_filterwidth=0.3); /** * Constructs a copy of 'spg' */ SeqPulsarSat(const SeqPulsarSat& spg); /** * Assignment operator that makes this object become a copy of 'spg' */ SeqPulsarSat& operator = (const SeqPulsarSat& spg); }; //////////////////////////////////////////////////////////////////////////// /** * * \brief Saturation pulse + spoilers * * A saturation pulse + spoiler gradient pulse * */ class SeqSat : public SeqObjList, public virtual SeqPulsInterface, public virtual SeqGradInterface { // virtual functions of SeqPulsInterface are marshalled to puls // virtual functions of SeqFreqChanInterface are marshalled to puls public: /** * Constructs saturation pulse labeled 'object_label' with the following properties: * - nuc: the nucleus to saturate * - bandwidth: The bandwidth in kHz * - npulses: The number of consecutive pulses */ SeqSat(const STD_string& object_label="unnamedSeqSat",satNucleus nuc=fat,float bandwidth=0.3, unsigned int npulses=1); /** * Constructs a copy of 'spg' */ SeqSat(const SeqSat& spg); /** * Assignment operator that makes this object become a copy of 'spg' */ SeqSat& operator = (const SeqSat& spg); // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; fvector get_gradintegral() const; double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); private: void build_seq(); SeqPulsarSat puls; SeqGradConstPulse spoiler_read_pos; SeqGradConstPulse spoiler_slice_neg; SeqGradConstPulse spoiler_read_neg; SeqGradConstPulse spoiler_slice_pos; SeqGradConstPulse spoiler_phase_pos; unsigned int npulses_cache; }; /** @} */ #endif odin-1.8.5/odinseq/seqsim.h0000644000175000017500000002464111712547771012536 00000000000000/*************************************************************************** seqsim.h - description ------------------- begin : Tue Jun 11 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQSIM_H #define SEQSIM_H #include #include // for RandomDist #include #include /** * @ingroup odinseq * \brief Time interval for simulation * * Data structure to hold the values for a single interval with constant fields * - dt: Duration of the interval * - B1: Complex RF field * - freq: Transmit/receive frequency * - phase: Transmit/receive phase in deg * - rec: Receiver (>0 means on) * - Gx: Gradient in read direction * - Gy: Gradient in phase direction * - Gz: Gradient in slice direction */ struct SeqSimInterval { SeqSimInterval() : dt(0.0), B1(0.0), freq(0.0), phase(0.0), rec(0.0), Gx(0.0), Gy(0.0), Gz(0.0) {} float dt; STD_complex B1; float freq; float phase; float rec; float Gx; float Gy; float Gz; }; ///////////////////////////////////////////////////////////////////// class ProgressMeter; // forward declaration /** * @ingroup odinseq_internals * Interface for Simulators */ class SeqSimAbstract : public virtual SeqClass { public: virtual ~SeqSimAbstract() {} /** * Prepare a simulation (i.e. before successive calls to simulate() ) with the parameters: * - sample: The virtual sample * - transmit_coil: Transmitter coil, 0 for none * - receive_coil: Receiver coil, 0 for none * - progmeter: Status indicator to trace progress, 0 for none */ virtual void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0) = 0; /** * Simulation with * - simvals: The magnetic fields during a time interval * - gamma: Gyromagnetic ration of the nucleus observed * Return value: Signal in each receiver channel */ virtual cvector simulate(const SeqSimInterval& simvals, double gamma) = 0; /** * Call this function after a simulation (i.e. after successive calls to simulate() ) */ virtual void finalize_simulation() = 0; }; ///////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief MAGSI-based Magnetization Simulator * * This is a simulator to calculate the time evolution of a magnetization grid * in 4 dimension (frequency and three spatial dimensions). This simulation of the * Bloch-Torrey equations is performed by means of the MAGSI algorith * (c.f. Journal of Magnetic Resonance 180:29-38, 2006). * Simulation usually involves the following steps: * - Initialize the simulator by prepare_simulation() using a virtual sample. * - Iterative simulation by simulate() using a structure with piece-wise constant fields. * - Finish simulation by calling finalize_simulation(). */ class SeqSimMagsi : public JcampDxBlock, public ThreadedLoop, public virtual SeqSimAbstract { public: /** * Constructs a simulator labeled 'object_label'. */ SeqSimMagsi(const STD_string& label="unnamedSeqSimMagsi"); /** * Copy constructor */ SeqSimMagsi(const SeqSimMagsi& ssm); /** * Destructor */ ~SeqSimMagsi(); /** * Assignment operator */ SeqSimMagsi& operator = (const SeqSimMagsi& ssm); /** * Returns the overall size of the array */ unsigned int get_total_size() const {return Mx.total();} /** * Set each magnetization to initial state 'initial_vector', which is (0,0,1) by default */ SeqSimMagsi& reset_magnetization(); /** * Set the vector for the initial magnetization */ SeqSimMagsi& set_initial_vector(float Mx, float My, float Mz); /** * Returns the real part of the transverse magnetisation */ const farray& get_Mx() const {return Mx;} /** * Returns the imaginary part of the transverse magnetisation */ const farray& get_My() const {return My;} /** * Returns the longitudinal magnetisation */ const farray& get_Mz() const {return Mz;} /** * Returns the amplitude of the transverse magnetisation */ const farray& get_Mamp() const {return Mamp;} /** * Returns the phase of the transverse magnetisation */ const farray& get_Mpha() const {return Mpha;} /** * Updates all parameter relations */ SeqSimMagsi& update(); /** * Specifies whether simulation should be performed everytime update() is called */ SeqSimMagsi& set_online_simulation(bool onlineflag) { online=onlineflag; return *this;} /** * Specifies whether intra-voxel magnetzation gradients are considered during simulation */ SeqSimMagsi& set_intravoxel_simulation(bool ivflag) { magsi=ivflag; return *this;} /** * Specifies the number of threads used during simulation */ SeqSimMagsi& set_numof_threads(unsigned int n) { nthreads=n; return *this;} /** * Specifies a rotation matrix for the spatial domain, i.e. the magnetization * array will be rotated in space using the specified rotation matrix. */ SeqSimMagsi& set_spat_rotmatrix(const RotMatrix& rotmatrix); /** * Returns whether simulation should be performed, i.e. whether the 'online' flag * is true or 'update' was activated. */ bool do_simulation(); // implementing virtual functions of SeqSimAbstract void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0); cvector simulate(const SeqSimInterval& simvals, double gamma); void finalize_simulation(); // implementing virtual functions of ThreadedLoop bool kernel(const SeqSimInterval& simvals, cvector& signal, int&, unsigned int begin, unsigned int end); private: friend class SeqTimecourse; /** * Resize the array in the four dimensions according to the given sizes */ SeqSimMagsi& resize(unsigned int xsize, unsigned int ysize, unsigned int zsize, unsigned int freqsize=1); void common_init(); int append_all_members(); SeqSimMagsi& MampMpha2MxMy(); SeqSimMagsi& MxMy2MampMpha(); void update_axes(); void set_axes_cache(const Sample& sample); JDXfloatArr Mx; JDXfloatArr My; JDXfloatArr Mz; JDXfloatArr Mamp; JDXfloatArr Mpha; JDXbool online; JDXaction update_now; JDXtriple initial_vector; bool iactive; bool magsi; unsigned int nthreads; RotMatrix* spat_rotmatrix; double gamma_cache; double elapsed_time; // within current time frame unsigned int time_index_cache; unsigned int numof_time_intervals_cache; double* time_intervals_cache; // cache for update_axes() float x_low; float x_upp; float y_low; float y_upp; float z_low; float z_upp; float freq_low; // in rad/s float freq_upp; // in rad/s // intra-voxel magn gradients float *dMx[4]; float *dMy[4]; float *dMz[4]; float *dppm[3]; // readonly // use raw pointers to avoid slower []-operator of STD_vector unsigned int oneframe_size_cache; // size of one frame float* xpos_cache; float* ypos_cache; float* zpos_cache; float* freqoffset_cache; // in rad*kHz unsigned int nframes_ppm_cache; float* ppm_cache; unsigned int nframes_spin_density_cache; float* spin_density_cache; STD_complex* B1map_transm_cache; unsigned int num_rec_channel_cache; STD_complex** B1map_receiv_cache; unsigned int nframes_Dcoeff_cache; float* Dcoeff_cache; bool sim_diffusion; unsigned int nframes_r1_cache; float* r1_cache; unsigned int nframes_r2_cache; float* r2_cache; bool* has_relax_cache; float L[4]; float B0_ppm; bool simcache_up2date; void outdate_simcache(); }; ///////////////////////////////////////////////////////////////////// #ifdef STANDALONE_PLUGIN // exclude from Siemens DLLs /** * \brief Monte-Carlo-based Magnetization Simulator * * Monte-Carlo Simulator for diffusional averaging */ class SeqSimMonteCarlo : public ThreadedLoop, public virtual SeqSimAbstract { public: /** * Constructs a simulator labeled 'object_label' to simulate 'nparticles' diffusion trajectories using 'nthreads' threads. */ SeqSimMonteCarlo(const STD_string& label="unnamedSeqSimMonteCarlo", unsigned int nparticles=10000, unsigned int nthreads=1); /** * Copy constructor */ SeqSimMonteCarlo(const SeqSimMonteCarlo& ssmc) {common_init(); SeqSimMonteCarlo::operator = (ssmc);} /** * Assignment operator */ SeqSimMonteCarlo& operator = (const SeqSimMonteCarlo& ssmc); /** * Get spatial distribution of particles after simulation */ farray get_spatial_dist() const; // implementing virtual functions of SeqSimAbstract void prepare_simulation(const Sample& sample, CoilSensitivity* transmit_coil=0, CoilSensitivity* receive_coil=0, ProgressMeter* progmeter=0); cvector simulate(const SeqSimInterval& simvals, double gamma); void finalize_simulation(); // implementing virtual functions of ThreadedLoop bool kernel(const SeqSimInterval& simvals, cvector& signal, RandomDist& local_rng, unsigned int begin, unsigned int end); private: struct Particle { float pos[3]; float Mx, My, Mz; }; void common_init(); void clear_cache(); unsigned int linear_index(const float pos[3]) const; STD_vector particle; unsigned int numof_threads; RandomDist rng; // seed only once per simulator double gamma_cache; unsigned int size_cache[3]; // use raw pointers to avoid slower []-operator of STD_vector float* Dcoeff_cache; float* ppmMap_cache; float* R1map_cache; float* R2map_cache; float* spinDensity_cache; float pixelspacing_cache[3]; float B0_ppm_cache; }; #endif ///////////////////////////////////////////////////////////////////// /** @} */ #endif odin-1.8.5/odinseq/odinpulse.cpp0000644000175000017500000010464711322062345013561 00000000000000#include "odinpulse.h" #include "seqsim.h" #include "seqdriver.h" #include "seqplatform.h" /////////////////////////////////////////////////////////////////////// const kspace_coord& JDXtrajectory::calculate(float s) const { JDXfunctionPlugIn::coord_retval=kspace_coord(); if(allocated_function) return allocated_function->calculate_traj(s); else return JDXfunctionPlugIn::coord_retval; } const traj_info& JDXtrajectory::get_traj_info() const { JDXfunctionPlugIn::traj_info_retval=traj_info(); if(allocated_function) return allocated_function->get_traj_properties(); else return JDXfunctionPlugIn::traj_info_retval; } /////////////////////////////////////////////////////////////////////// STD_complex JDXshape::calculate(const kspace_coord& coord ) const { if(allocated_function) return allocated_function->calculate_shape(coord); return STD_complex(0.0); } STD_complex JDXshape::calculate(float s, float Tp) const { if(allocated_function) return allocated_function->calculate_shape(s,Tp); return STD_complex(0.0); } const shape_info& JDXshape::get_shape_info() const { JDXfunctionPlugIn::shape_info_retval=shape_info(); if(allocated_function) return allocated_function->get_shape_properties(); else return JDXfunctionPlugIn::shape_info_retval; } /////////////////////////////////////////////////////////////////////// struct OdinPulseData { bool intactive; JDXenum dim_mode; JDXenum nucleus; JDXshape shape; JDXtrajectory trajectory; JDXfilter filter; JDXint npts; JDXdouble Tp; JDXcomplexArr B1; JDXfloatArr Gr; JDXfloatArr Gp; JDXfloatArr Gs; JDXdouble B10; JDXdouble G0; JDXbool consider_system_cond_flag; JDXbool consider_Nyquist_cond_flag; JDXbool take_min_smoothing_kernel; JDXdouble smoothing_kernel_size; JDXtriple spatial_offset; JDXdouble field_of_excitation; JDXenum pulse_type; JDXformula composite_pulse; JDXint npts_1pulse; JDXdouble Tp_1pulse; JDXdouble pulse_gain; JDXdouble pulse_power; JDXdouble flipangle; float flip_corr; funcMode old_mode; bool ready; }; /////////////////////////////////////////////////////////////////////// // Calculate maximum possible gradient strengt which is either given by the slew rate or max gradient strength float OdinPulse::gradient_system_max (const fvector& Gvec, float Gmax, float maxslew, float Tp) { Log odinlog("","gradient_system_max"); float dGmax = 0.0; int npuls=Gvec.size(); for (int i = 1; i < npuls; i++) dGmax=STD_max(dGmax, float(fabs(Gvec[i - 1] - Gvec[i]))); if(dGmax>0.0 && npuls>0 ) { float Gmax_slew = maxslew * Tp / (float(npuls) * dGmax); // Gradient strength which would have to be used in order to stay within slew-rate limits return STD_min(Gmax_slew, Gmax); } else { return Gmax; } } float OdinPulse::max_kspace_step (const fvector& Gz,float gamma,float Tp,float G0) { float kz = 0.0, kzold = 0.0, maxstep = 0.0; int npuls=Gz.size(); for (int i = npuls - 1; i >= 0; i--) { kz -= gamma * Tp * G0 / float(npuls) * Gz[i]; maxstep = STD_max(maxstep, float(fabs(kz - kzold))); kzold = kz; } return maxstep; } float OdinPulse::max_kspace_step2 (const fvector& Gx, const fvector& Gy, float gamma,float Tp,float G0) { float kx = 0.0, ky = 0.0, kxold = 0.0, kyold = 0.0, maxstep = 0.0; int npuls=Gx.size(); for (int i = npuls - 1; i >= 0; i--) { kx -= gamma * Tp * G0 / float(npuls) * Gx[i]; ky -= gamma * Tp * G0 / float(npuls) * Gy[i]; maxstep = STD_max(maxstep, float(norm(kx - kxold, ky - kyold))); kxold = kx; kyold = ky; } return maxstep; } ////////////////////////////////////////////////////////////////////////////////////////// OdinPulse::OdinPulse(const STD_string& pulse_label,bool interactive) : JcampDxBlock(pulse_label), data(new OdinPulseData) { set_label(pulse_label); // because SeqClass is a virtual base class Log odinlog(this,"OdinPulse(...)"); data->shape.set_label("shape"); data->trajectory.set_label("trajectory"); data->filter.set_label("filter"); data->ready=false; data->intactive=interactive; data->flip_corr=1.0; data->dim_mode.add_item("0D"); data->dim_mode.add_item("1D"); data->dim_mode.add_item("2D"); data->dim_mode.set_actual(oneDeeMode); data->old_mode=funcMode(int(data->dim_mode)); ODINLOG(odinlog,normalDebug) << "old_mode=" << int(data->old_mode) << STD_endl; data->nucleus=systemInfo->get_nuc_enum(); data->nucleus.set_actual(0); data->shape.set_function_mode(funcMode(int(data->dim_mode))); data->trajectory.set_function_mode(funcMode(int(data->dim_mode))); data->npts_1pulse=256; data->npts_1pulse.set_minmaxval(1,systemInfo->get_max_rf_samples()); data->npts=data->npts_1pulse; resize_noupdate(data->npts); data->Tp_1pulse=2.0; data->Tp_1pulse.set_minmaxval(0.001,30.0); data->Tp_1pulse.set_unit(ODIN_TIME_UNIT); data->Tp=data->Tp_1pulse; data->take_min_smoothing_kernel=true; data->smoothing_kernel_size=0.001;// smoothing_kernel_size.set_minmaxval(0.001,20.0); data->smoothing_kernel_size.set_unit(ODIN_SPAT_UNIT); data->field_of_excitation=200.0; data->field_of_excitation.set_unit(ODIN_SPAT_UNIT); data->flipangle=90.0; data->flipangle.set_minmaxval(0.0,360.0); data->flipangle.set_unit(ODIN_ANGLE_UNIT); data->consider_system_cond_flag=true; data->consider_Nyquist_cond_flag=true; data->spatial_offset.set_unit(ODIN_SPAT_UNIT); for(int i=0; ipulse_type.add_item(pulseTypeLabel[i],i); data->pulse_type.set_actual(0); data->composite_pulse.set_syntax("A composite pulse can be specified by a string of the form a1(x2) a2(x2) ... where a1,a2,... are the flipangles in degree and x1,x2,... are the axes, .e.g. X,-X,Y or -Y"); data->pulse_gain=0.0; data->pulse_gain.set_parmode(noedit); data->pulse_gain.set_unit("dB"); data->pulse_power=0.0; data->pulse_power.set_parmode(noedit); data->pulse_power.set_unit(STD_string(ODIN_FIELD_UNIT)+"^2*"+ODIN_TIME_UNIT); data->B10=0.0; data->B10.set_parmode(noedit); data->B10.set_unit(ODIN_FIELD_UNIT); data->G0=0.0; data->G0.set_parmode(noedit); data->G0.set_unit(ODIN_GRAD_UNIT); data->B1.set_filemode(exclude); GuiProps gp; gp.scale[xPlotScale]=ArrayScale("time",ODIN_TIME_UNIT,0.0,data->Tp); data->B1.set_gui_props(gp); data->Gr.set_filemode(exclude); data->Gp.set_filemode(exclude); data->Gs.set_filemode(exclude); data->shape.set_function(0); data->trajectory.set_function(0); data->filter.set_function(0); unsigned int capacity=systemInfo->get_max_rf_samples(); data->B1.reserve(capacity); data->Gr.reserve(capacity); data->Gp.reserve(capacity); data->Gs.reserve(capacity); append_all_members(); data->ready=true; OdinPulse::update(); } OdinPulse::OdinPulse(const OdinPulse& pulse) : data(new OdinPulseData) { OdinPulse::operator = (pulse); } OdinPulse::~OdinPulse() { Log odinlog(this,"~OdinPulse()"); delete data; } int OdinPulse::append_all_members() { clear(); append_member(data->dim_mode,"Mode"); append_member(data->nucleus,"Nucleus"); append_member(data->shape,"Shape"); append_member(data->trajectory,"Trajectory"); append_member(data->filter,"Filter"); append_member(data->npts_1pulse,"NumberOfPoints"); append_member(data->Tp_1pulse,"PulseDuration"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->take_min_smoothing_kernel,"TakeMinSmoothingKernel"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->smoothing_kernel_size,"SmoothingKernelSize"); append_member(data->flipangle,"FlipAngle"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->consider_system_cond_flag,"ConsiderSystem"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->consider_Nyquist_cond_flag,"ConsiderNyquist"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->spatial_offset,"SpatialOffset"); if(int(data->dim_mode)>zeroDeeMode) append_member(data->field_of_excitation,"FieldOfExcitation"); if(int(data->dim_mode)pulse_type,"PulseType"); append_member(data->composite_pulse,"CompositePulse"); append_member(data->B1,"B1"); if(int(data->dim_mode)==twoDeeMode) append_member(data->Gr,"x_Gradient"); if(int(data->dim_mode)==twoDeeMode) append_member(data->Gp,"y_Gradient"); if(int(data->dim_mode)==oneDeeMode) append_member(data->Gs,"z_Gradient"); append_member(data->pulse_gain,"PulseGain"); append_member(data->pulse_power,"PulsePower"); append_member(data->B10,"B1_Max"); append_member(data->G0,"GradientMax"); return 0; } OdinPulse& OdinPulse::operator = (const OdinPulse& pulse) { Log odinlog(this,"operator = (...)"); SeqClass::operator = (pulse); JcampDxBlock::operator = (pulse); ODINLOG(odinlog,normalDebug) << "operator of base classes called" << STD_endl; (*data)=(*(pulse.data)); OdinPulse::append_all_members(); update(); return *this; } OdinPulse& OdinPulse::set_dim_mode(funcMode dmode) { Log odinlog(this,"set_dim_mode"); data->old_mode=funcMode(int(data->dim_mode)); ODINLOG(odinlog,normalDebug) << "old_mode/dmode=" << int(data->old_mode) << "/" << int(dmode) << STD_endl; data->dim_mode.set_actual(dmode); data->shape.set_function_mode(funcMode(int(data->dim_mode))); data->trajectory.set_function_mode(funcMode(int(data->dim_mode))); update(); return *this; } funcMode OdinPulse::get_dim_mode() const { return funcMode(int(data->dim_mode)); } unsigned int OdinPulse::get_size() const {return data->npts;} OdinPulse& OdinPulse::resize(unsigned int newsize) { data->npts_1pulse=newsize; resize_noupdate(newsize); return update(); } OdinPulse& OdinPulse::resize_noupdate(unsigned int newsize) { data->B1.resize(newsize); data->Gr.resize(newsize); data->Gp.resize(newsize); data->Gs.resize(newsize); return *this; } OdinPulse& OdinPulse::set_Tp(double duration) { data->Tp_1pulse=duration; data->Tp=duration; return update(); } double OdinPulse::get_Tp() const { return data->Tp; } double OdinPulse::get_Tp_1pulse() const { return data->Tp_1pulse; } OdinPulse& OdinPulse::set_consider_system_cond(bool flag) { data->consider_system_cond_flag=flag; update(); return *this; } bool OdinPulse::get_consider_system_cond() const {return data->consider_system_cond_flag;} OdinPulse& OdinPulse::set_consider_Nyquist_cond(bool flag) { data->consider_Nyquist_cond_flag=flag; update(); return *this; } bool OdinPulse::get_consider_Nyquist_cond() const { return data->consider_Nyquist_cond_flag;} OdinPulse& OdinPulse::set_spat_resolution(double sigma) { data->smoothing_kernel_size=sigma; data->take_min_smoothing_kernel=false; update(); return *this; } double OdinPulse::get_spat_resolution() const {return data->smoothing_kernel_size;} OdinPulse& OdinPulse::use_min_spat_resolution(bool flag) { data->take_min_smoothing_kernel=flag; update(); return *this; } OdinPulse& OdinPulse::set_field_of_excitation(double fox) { data->field_of_excitation=fox; update(); return *this; } double OdinPulse::get_field_of_excitation() const {return data->field_of_excitation;} OdinPulse& OdinPulse::set_spatial_offset(direction direction, double offset) { data->spatial_offset[direction]=offset; update(); return *this; } double OdinPulse::get_spatial_offset(direction direction) const {return data->spatial_offset[direction];} OdinPulse& OdinPulse::set_nucleus(const STD_string& nucleusname) { data->nucleus.set_actual(nucleusname); update(); return *this; } STD_string OdinPulse::get_nucleus() const { return data->nucleus; } OdinPulse& OdinPulse::set_pulse_type(pulseType type) { data->pulse_type.set_actual(type); update(); return *this; } pulseType OdinPulse::get_pulse_type() const {return pulseType(int(data->pulse_type));} OdinPulse& OdinPulse::set_composite_pulse(const STD_string& cpstring) { Log odinlog(this,"set_composite_pulse"); data->composite_pulse=cpstring; ODINLOG(odinlog,normalDebug) << "composite_pulse=>" << STD_string(data->composite_pulse) << "<" << STD_endl; update(); return *this; } farray OdinPulse::get_composite_pulse_parameters() const { Log odinlog(this,"get_composite_pulse_parameters"); if(!is_composite_pulse()) return farray(); ODINLOG(odinlog,normalDebug) << "composite_pulse=>" << STD_string(data->composite_pulse) << "<" << STD_endl; svector subpulses=tokens(data->composite_pulse); unsigned int n_pulses=subpulses.size(); ODINLOG(odinlog,normalDebug) << "n_pulses=" << n_pulses << STD_endl; farray result(n_pulses,2); for(unsigned int i=0;i" << subpulses[i] << "<" << STD_endl; result(i,0)=atof(rmblock(subpulses[i],"(",")",true,true).c_str()); } return result; } bool OdinPulse::is_composite_pulse() const { Log odinlog(this,"is_composite_pulse"); bool result=true; if(data->composite_pulse=="") result=false; ODINLOG(odinlog,normalDebug) << "composite_pulse/result=" << STD_string(data->composite_pulse) << "/" << result << STD_endl; return result; } OdinPulse& OdinPulse::set_flipangle(double angle) { data->flipangle=angle; update_B10andPower(); return *this; } double OdinPulse::get_flipangle() const {return data->flipangle;} int OdinPulse::load(const STD_string& filename) { Log odinlog(this,"load"); // determine the dim mode first and set the functions accordingly data->dim_mode.load(filename); ODINLOG(odinlog,normalDebug) << "dim_mode/old_mode=" << int(data->dim_mode) << "/" << int(data->old_mode) << STD_endl; // switch before loading so that plugin parameters can be assigned properly data->shape.set_function_mode(funcMode(int(data->dim_mode))); data->trajectory.set_function_mode(funcMode(int(data->dim_mode))); // then load the whole set of parameters and update the pulse int result=JcampDxBlock::load(filename); update(); return result; } int OdinPulse::write(const STD_string& filename) const {return JcampDxBlock::write(filename);} float OdinPulse::ensure_unit_range(float x) { x=STD_min(float(1.0),x); x=STD_max(float(-1.0),x); return x; } OdinPulse& OdinPulse::generate() { Log odinlog(this,"generate"); if(!data->ready) { ODINLOG(odinlog,normalDebug) << "not ready" << STD_endl; return *this; } int i; float knew; float dkmax=0.0; if(data->take_min_smoothing_kernel) data->smoothing_kernel_size=0.001; // Reset so that it will be increased to min in a later step data->smoothing_kernel_size=STD_max(0.001, double(data->smoothing_kernel_size)); data->shape.init_shape(); data->trajectory.init_trajectory(this); // For loaded pulses int fixedsize=data->shape.get_shape_info().fixed_size; if(fixedsize>=0) data->npts_1pulse=fixedsize; // Calculate pulse using fixed rastertime, if necessary double rastime=systemInfo->get_rastertime(pulsObj); if(rastime) { data->npts_1pulse=int(secureDivision(data->Tp_1pulse,rastime)+0.5); data->Tp_1pulse=double(data->npts_1pulse)*rastime; } // reset to the size of one pulse data->npts=data->npts_1pulse; data->Tp=data->Tp_1pulse; resize_noupdate(data->npts_1pulse); ODINLOG(odinlog,normalDebug) << "resize done" << STD_endl; float gamma=systemInfo->get_gamma(data->nucleus); funcMode mode=funcMode(int(data->dim_mode)); // Zero gradients before calculating the selectively data->Gr=JDXfloat(0.0); data->Gp=JDXfloat(0.0); data->Gs=JDXfloat(0.0); data->G0=0.0; float g0=0.0; // The scaling factor for the time-strength-independent gradient shape bool spatsel_mode=(mode>=oneDeeMode) && (mode<=twoDeeMode); if(spatsel_mode) { // generate gradients if in spatial-selective mode if(mode==oneDeeMode) { // calculate gradient: for(i=0; inpts_1pulse; i++) { const kspace_coord& tds=data->trajectory.calculate (float(i)/float(data->npts_1pulse-1)); data->Gs[i] = tds.Gz; } // normalize_gradient: g0 = data->Gs.normalize(); } // end oneDeeMode if(mode==twoDeeMode) { // calculate gradient: for(i=0; inpts_1pulse; i++) { const kspace_coord& tds=data->trajectory.calculate (float(i)/float(data->npts_1pulse-1)); data->Gr[i] = tds.Gx; data->Gp[i] = tds.Gy; } // normalize_gradient: g0 = STD_max (data->Gr.maxabs(), data->Gp.maxabs()); if (g0) { data->Gr/=g0; data->Gp/=g0; } } } // The following calculations are based on these notations: // // k(t) = kr * f(t/Tp) = gamma * integral{ G(t') dt'} = gamma * G0 * integral{ G(t')/G0 dt'} = gamma * G0 * Tp * integral{ g(s)/g0 ds} = gamma * G0/g0 * Tp * f(s) // // => kr = gamma * Tp * G0/g0 // // with // k(t): Physical k-space trajectory // kr: Maximum k-space radius (distance from center) // f(s): Trajectory as provided by plugin // G(t): Physical gradient shape // G0: Scaling factor for physical gradient strength // g(s): Gradient shape as provided by plugin, f(s) = integral{ g(s) ds} // g0: Scaling factor for gradient shape as provided by plugin // // Please note: the vectors G(t)/G0 and g(s)/g0 have the same normalized values. double nyquist_factor = sqrt (-2.0 * log (_BOUNDARY_VALUE_)) * 2.0; // TODO: replace this by PII // double nyquist_factor = PII; // set_gradient_max_scale: if(spatsel_mode) { // set G0 according to smoothing scale: float kr = secureDivision(nyquist_factor , data->smoothing_kernel_size); data->G0 = secureDivision(kr * g0 , gamma * data->Tp_1pulse); } ODINLOG(odinlog,normalDebug) << "set_gradient_max_scale done" << STD_endl; // calculate the maximum gradient strength of the pulse according to the system constrains float Gmax_system=systemInfo->get_max_grad(); float maxslew_system=systemInfo->get_max_slew_rate(); ODINLOG(odinlog,normalDebug) << "systemInfo stuff done" << STD_endl; float Gsystem=0.0; if(mode==oneDeeMode) { ODINLOG(odinlog,normalDebug) << "calling gradient_system_max in 1D mode" << STD_endl; Gsystem = gradient_system_max (data->Gs, Gmax_system, maxslew_system, data->Tp_1pulse); } if(mode==twoDeeMode) { ODINLOG(odinlog,normalDebug) << "calling gradient_system_max in 2D mode" << STD_endl; Gsystem = STD_min(gradient_system_max (data->Gr, Gmax_system, maxslew_system, data->Tp_1pulse), gradient_system_max (data->Gp, Gmax_system, maxslew_system, data->Tp_1pulse)); } ODINLOG(odinlog,normalDebug) << "gradient scaling done" << STD_endl; // check to above calculated max gradient strength against the actual and correct if neccessary if (data->G0 >= Gsystem) { if (data->consider_system_cond_flag) { data->G0 = Gsystem; if(spatsel_mode) { knew = secureDivision(gamma * data->G0 * data->Tp_1pulse , g0); data->smoothing_kernel_size = STD_max( double(data->smoothing_kernel_size), nyquist_factor / knew); } } else ODINLOG(odinlog,warningLog) << "system conditions violated !" << STD_endl; } ODINLOG(odinlog,normalDebug) << "system constraints done" << STD_endl; // precalculations for Nyquist check float max_spatial_extension=0.5*data->field_of_excitation; // Assume single point as the excitation shape, so that, in contrast to a shape that fills the whole FOX, aliases would appear at (+/- FOX). Therefore, we can effectively use half the FOX without aliasing. max_spatial_extension*=sqrt(mode); // extend to diagonal direction square-shaped alias-free FOX max_spatial_extension+=data->shape.get_shape_info().spatial_extent; // If shape is not single point, add the total extent of the shape. Otherwise it aliases into the FOX. if(mode==oneDeeMode) { dkmax=max_kspace_step(data->Gs, gamma, data->Tp_1pulse, data->G0); max_spatial_extension += fabs(data->spatial_offset[zAxis]); } if(mode==twoDeeMode) { dkmax=max_kspace_step2(data->Gr, data->Gp, gamma, data->Tp_1pulse,data->G0); // max k-space step in tangential direction max_spatial_extension += norm (data->spatial_offset[xAxis], data->spatial_offset[yAxis]); // add spatial offset } float kr0 = secureDivision(gamma * data->G0 * data->Tp_1pulse , g0); // k-space radius float dkmax_trajectory=2.0*kr0*data->trajectory.get_traj_info().max_kspace_step; // max k-space step in radial direction ODINLOG(odinlog,normalDebug) << "dkmax_trajectory/dkmax=" << dkmax_trajectory << "/" << dkmax << STD_endl; dkmax=STD_max(dkmax, dkmax_trajectory); // max of both // consider Nyquist condition and correct if neccessary if(spatsel_mode) { float phase_product=dkmax * max_spatial_extension; if (phase_product > 2.0*PII) { // Nyquist condition if (data->consider_Nyquist_cond_flag) { // rescale k-space to fulfill Nyquist condition data->G0 = secureDivision( 2.0*PII * data->G0 , phase_product ); knew = secureDivision( gamma * data->G0 * data->Tp_1pulse , g0 ); data->smoothing_kernel_size = STD_max( double(data->smoothing_kernel_size), nyquist_factor / knew); } else ODINLOG(odinlog,warningLog) << "Nyquist condition violated !" << STD_endl; } } ODINLOG(odinlog,normalDebug) << "Nyquist constraints done" << STD_endl; // float kernel0D=sqrt(-32*log(_BOUNDARY_VALUE_)); //generate RF waveform: kr0 = secureDivision(gamma * data->G0 * data->Tp_1pulse , g0); ODINLOG(odinlog,normalDebug) << "dim_mode/g0/G0/kr0 = " << data->dim_mode.printvalstring() << "/" << g0 << "/" << double(data->G0) << "/" << kr0 << STD_endl; ODINLOG(odinlog,normalDebug) << "adiabatic = " << is_adiabatic() << STD_endl; kspace_coord tds; for (i=0; inpts_1pulse; i++) { float s=float(i)/float(data->npts_1pulse-1); tds=data->trajectory.calculate(s); tds.index=i; tds.kx=tds.kx*kr0; tds.ky=tds.ky*kr0; tds.kz=tds.kz*kr0; STD_complex Wk; if (mode==zeroDeeMode) Wk=data->shape.calculate(tds.traj_s,data->Tp_1pulse); else Wk=data->shape.calculate(tds); if ( !is_adiabatic() ) { if(mode==zeroDeeMode) { Wk*=data->filter.calculate(fabs(tds.traj_s-0.5)*2.0); } else { float kr = secureDivision( nyquist_factor , data->smoothing_kernel_size); float krad = sqrt(tds.kx*tds.kx+tds.ky*tds.ky+tds.kz*tds.kz); Wk*=data->filter.calculate(secureDivision( krad , kr ) ); } } if(mode==oneDeeMode) { Wk *= tds.denscomp; if (data->spatial_offset[zAxis] != 0.0) { float argument = float(data->spatial_offset[zAxis]) * tds.kz; Wk*=exp(STD_complex(0.0,-argument)); } } if(mode==twoDeeMode) { Wk *= tds.denscomp; if ((data->spatial_offset[xAxis] != 0.0) || (data->spatial_offset[yAxis] != 0.0)) { float argument = float(data->spatial_offset[xAxis]) * tds.kx + float(data->spatial_offset[yAxis]) * tds.ky; Wk*=exp(STD_complex(0.0,-argument)); } } data->B1[i]=Wk; } ODINLOG(odinlog,normalDebug) << "generate RF done" << STD_endl; // final scaling float Bmax = amplitude(data->B1).maxvalue(); ODINLOG(odinlog,normalDebug) << "Bmax=" << Bmax << STD_endl; if (Bmax <= 0.0) ODINLOG(odinlog,warningLog) << "RF-amplitude array=0.0 !" << STD_endl; for (i = 0; inpts_1pulse; i++) data->B1[i]*= secureInv(Bmax); ODINLOG(odinlog,normalDebug) << "final scaling done" << STD_endl; ODINLOG(odinlog,normalDebug) << "all done" << STD_endl; return *this; } unsigned int OdinPulse::get_numof_composite_pulse() const { return get_composite_pulse_parameters().size(0); } bool OdinPulse::is_adiabatic() const {return data->shape.get_shape_info().adiabatic;} float OdinPulse::get_rel_center() const {return data->trajectory.get_traj_info().rel_center;} double OdinPulse::get_pulse_gain() const {return data->pulse_gain;} float OdinPulse::get_flipangle_corr_factor() const {return data->flip_corr;} OdinPulse& OdinPulse::make_composite_pulse() { Log odinlog(this,"make_composite_pulse"); // reset to the size of one pulse data->npts=data->npts_1pulse; data->Tp=data->Tp_1pulse; if(!is_composite_pulse()) { ODINLOG(odinlog,normalDebug) << "no composite pulse" << STD_endl; return *this; } ODINLOG(odinlog,normalDebug) << "is composite pulse" << STD_endl; OdinPulseData datacopy(*data); farray pars=get_composite_pulse_parameters(); unsigned int npulses=pars.size(0); ODINLOG(odinlog,normalDebug) << "sdcopy & pars done" << STD_endl; unsigned int oldsize=datacopy.npts_1pulse; unsigned int newsize=npulses*oldsize; ODINLOG(odinlog,normalDebug) << "oldsize/newsize=" << oldsize << "/" << newsize << STD_endl; resize_noupdate(newsize); data->npts=newsize; data->Tp=double(data->Tp_1pulse)*double(npulses); ODINLOG(odinlog,normalDebug) << "Tp_1pulse/npulses/Tp=" << data->Tp_1pulse << "/" << npulses << "/" << data->Tp << STD_endl; unsigned int ipulse; float maxflip=0.0; for(ipulse=0; ipulsemaxflip) maxflip=flipang; } unsigned int index=0; for(ipulse=0; ipulseB1[index]=flipscale*phasefactor*datacopy.B1[i]; data->Gr[index]=datacopy.Gr[i]; data->Gp[index]=datacopy.Gp[i]; data->Gs[index]=datacopy.Gs[i]; index++; } } ODINLOG(odinlog,normalDebug) << "assignment done" << STD_endl; data->flipangle=maxflip; update_B10andPower(); ODINLOG(odinlog,normalDebug) << "B10/power done" << STD_endl; float gamma=systemInfo->get_gamma(data->nucleus); float flip_formfactor= 180.0/PII * gamma * data->B10 * abs(data->B1.sum()) * secureDivision(data->Tp,double(data->npts)); data->flip_corr=secureDivision(flip_formfactor,data->flipangle); ODINLOG(odinlog,normalDebug) << "flip_formfactor/flip_corr=" << flip_formfactor << "/" << data->flip_corr << STD_endl; return *this; } OdinPulse& OdinPulse::set_pulse_gain() { Log odinlog(this,"set_pulse_gain"); if(!data->ready) return *this; unsigned int i; SeqSimMagsi mag; //("set_pulse_gain::mag"); // mag.resize(1,1,1,1); float gamma=systemInfo->get_gamma(data->nucleus); ODINLOG(odinlog,normalDebug) << "gamma=" << gamma << STD_endl; // Field-Strength of 90,Tp BP-Pulse as starting value data->B10 = secureDivision( 0.5 * PII , (gamma * data->Tp_1pulse) ); ODINLOG(odinlog,normalDebug) << "B10=" << data->B10 << STD_endl; Sample sample; sample.set_spatial_offset(xAxis,0.0); sample.set_spatial_offset(yAxis,0.0); sample.set_spatial_offset(zAxis,0.0); if(int(data->dim_mode) == oneDeeMode) { sample.set_spatial_offset(zAxis,data->spatial_offset[zAxis]+ data->shape.get_shape_info().ref_z_pos); } if(int(data->dim_mode) == twoDeeMode) { float x_offset=data->spatial_offset[xAxis] + data->shape.get_shape_info().ref_x_pos; float y_offset=data->spatial_offset[yAxis] + data->shape.get_shape_info().ref_y_pos; ODINLOG(odinlog,normalDebug) << "x_offset=" << x_offset << STD_endl; ODINLOG(odinlog,normalDebug) << "y_offset=" << y_offset << STD_endl; sample.set_spatial_offset(xAxis,x_offset); sample.set_spatial_offset(yAxis,y_offset); } // deal with adiabatic mode first if(is_adiabatic()) { i=0; float Mzdes=-1.0+_SETREFGAIN_ADIABATIC_INTERVAL_; // inversion is default if(get_pulse_type()==saturation) Mzdes= 0.0+_SETREFGAIN_ADIABATIC_INTERVAL_; while( /* i Mzdes) { simulate_pulse(mag,sample); data->B10 = _SETREFGAIN_ADIABATIC_INCR_FACTOR_*data->B10; i++; } } // adjust 90deg pulse if(!is_adiabatic()) { for (i = 0; i < _SETREFGAIN_ITERATIONS_; i++) { simulate_pulse(mag,sample); ODINLOG(odinlog,normalDebug) << "B10(pre) [" << i << "]=" << data->B10 << STD_endl; ODINLOG(odinlog,normalDebug) << "Mz=" << (mag.get_Mz())[0] << STD_endl; data->B10 = secureDivision(0.5 * PII * data->B10 , acos ((mag.get_Mz())[0])); ODINLOG(odinlog,normalDebug) << "B10(post)[" << i << "]=" << data->B10 << STD_endl; } } float formfactor=secureDivision(abs(data->B1.sum()),double(data->npts_1pulse)); ODINLOG(odinlog,normalDebug) << "formfactor=" << formfactor << STD_endl; float B10_formfactor=secureDivision( 0.5 * PII , (formfactor * gamma * data->Tp_1pulse)); ODINLOG(odinlog,normalDebug) << "B10_formfactor=" << B10_formfactor << STD_endl; data->flip_corr=secureDivision(data->B10,B10_formfactor); ODINLOG(odinlog,normalDebug) << "flip_corr=" << data->flip_corr << STD_endl; // calculate pulse gain (formfactor) of the pulse data->pulse_gain = 20.0 * log10 (secureDivision( 0.5 * PII , (gamma * data->B10 * data->Tp_1pulse))); ODINLOG(odinlog,normalDebug) << "pulse_gain=" << float(data->pulse_gain) << STD_endl; update_B10andPower(); ODINLOG(odinlog,normalDebug) << "pulse_power=" << float(data->pulse_power) << STD_endl; return *this; } void OdinPulse::update_B10andPower() { Log odinlog(this,"update_B10andPower"); if(!is_adiabatic()) { ODINLOG(odinlog,normalDebug) << "flipangle=" << data->flipangle << STD_endl; ODINLOG(odinlog,normalDebug) << "Tp_1pulse=" << double(data->Tp_1pulse) << STD_endl; ODINLOG(odinlog,normalDebug) << "gamma=" << double(systemInfo->get_gamma(data->nucleus)) << STD_endl; ODINLOG(odinlog,normalDebug) << "pulse_gain=" << data->pulse_gain << STD_endl; data->B10 = data->flipangle / 90.0 / data->Tp_1pulse * 0.5 * PII / (systemInfo->get_gamma(data->nucleus) * pow (10.0, data->pulse_gain / 20.0)); ODINLOG(odinlog,normalDebug) << "B10=" << data->B10 << STD_endl; } data->pulse_power = get_power_depos(); } OdinPulse& OdinPulse::update() { Log odinlog(this,"update"); ODINLOG(odinlog,normalDebug) << "dim_mode/old_mode=" << int(data->dim_mode) << "/" << int(data->old_mode) << STD_endl; if(int(data->dim_mode)!=int(data->old_mode)) { data->shape.set_function_mode(funcMode(int(data->dim_mode))); data->trajectory.set_function_mode(funcMode(int(data->dim_mode))); data->old_mode=funcMode(int(data->dim_mode)); ODINLOG(odinlog,normalDebug) << "old_mode=" << int(data->old_mode) << STD_endl; append_all_members(); // append only members which are useful in the current dim_mode } if(data->intactive) recalc_pulse(); // axis range may have changed GuiProps gp; gp.scale[xPlotScale]=ArrayScale("time",ODIN_TIME_UNIT,0.0,data->Tp); data->B1.set_gui_props(gp); data->Gr.set_gui_props(gp); data->Gp.set_gui_props(gp); data->Gs.set_gui_props(gp); return *this; } OdinPulse& OdinPulse::recalc_pulse() { generate(); set_pulse_gain(); make_composite_pulse(); return *this; } float OdinPulse::get_power_depos() const { Log odinlog(this,"get_power_depos"); unsigned int n=data->B1.length(); // may differ from npts float result=0.0; float dt = secureDivision(data->Tp , n); float B1amp; for (unsigned int i=0; iB10) * cabs(data->B1[i]); result+= B1amp*B1amp * dt; } return result; // To get values in reasonable range } OdinPulse& OdinPulse::set_shape(const STD_string& shapeval) { data->shape.set_funcpars(shapeval); update(); return *this; } OdinPulse& OdinPulse::set_trajectory(const STD_string& trajval) { data->trajectory.set_funcpars(trajval); update(); return *this; } OdinPulse& OdinPulse::set_filter(const STD_string& filterval) { data->filter.set_funcpars(filterval); update(); return *this; } OdinPulse& OdinPulse::set_shape_parameter(const STD_string& parameter_label, const STD_string& value) {data->shape.set_parameter(parameter_label,value); return *this;} OdinPulse& OdinPulse::set_trajectory_parameter(const STD_string& parameter_label, const STD_string& value) {data->trajectory.set_parameter(parameter_label,value); return *this;} OdinPulse& OdinPulse::set_filter_parameter(const STD_string& parameter_label, const STD_string& value) {data->filter.set_parameter(parameter_label,value); return *this;} STD_string OdinPulse::get_shape_parameter(const STD_string& parameter_label) const {return data->shape.get_parameter(parameter_label);} STD_string OdinPulse::get_trajectory_parameter(const STD_string& parameter_label) const {return data->trajectory.get_parameter(parameter_label);} STD_string OdinPulse::get_filter_parameter(const STD_string& parameter_label) const {return data->filter.get_parameter(parameter_label);} STD_string OdinPulse::get_shape() const {return data->shape.get_function_name();} STD_string OdinPulse::get_trajectory() const {return data->trajectory.get_function_name();} STD_string OdinPulse::get_filter() const {return data->filter.get_function_name();} const fvector& OdinPulse::get_Grad(direction channel) const { if(channel==readDirection) return data->Gr; if(channel==phaseDirection) return data->Gp; if(channel==sliceDirection) return data->Gs; return data->Gr; } double OdinPulse::get_G0() const {return data->G0;} const cvector& OdinPulse::get_B1() const {return data->B1;} double OdinPulse::get_B10() const {return data->B10;} void OdinPulse::simulate_pulse(SeqSimAbstract& sim, const Sample& sample) const { Log odinlog(this,"simulate_pulse"); // sim.reset_magnetization(); // will be called in prepare_simulation unsigned int n=get_size(); double dt=secureDivision(get_Tp(),n); float gamma=systemInfo->get_gamma(data->nucleus); ODINLOG(odinlog,normalDebug) << "n/dt/gamma=" << n << "/" << dt << "/" << gamma << STD_endl; SeqSimInterval simvals; simvals.dt=dt; simvals.freq=0.0; simvals.phase=0.0; simvals.rec=0.0; sim.prepare_simulation(sample); for(unsigned int i=0; iB10)*data->B1[i]; simvals.Gx= data->G0*data->Gr[i]; simvals.Gy= data->G0*data->Gp[i]; simvals.Gz= data->G0*data->Gs[i]; sim.simulate(simvals,gamma); } sim.finalize_simulation(); } int OdinPulse::write_rf_waveform (const STD_string& filename) const { Log odinlog(this,"write_rf_waveform"); int result=SeqPlatformProxy()->write_rf_waveform(filename,data->B1); if(result<0) ODINLOG(odinlog,errorLog) << " failed" << STD_endl; return result; } int OdinPulse::load_rf_waveform (const STD_string& filename) { Log odinlog(this,"load_rf_waveform"); cvector B1load; B1load.reserve(systemInfo->get_max_rf_samples()); int n=SeqPlatformProxy()->load_rf_waveform(filename,B1load); if(n>0) { resize(n); data->B1=B1load; } if(n>=0) n=0; if(n<0) ODINLOG(odinlog,errorLog) << " failed" << STD_endl; return n; } odin-1.8.5/odinseq/seqvec.h0000644000175000017500000002430111322062345012476 00000000000000/*************************************************************************** seqvec.h - description ------------------- begin : Mon Aug 19 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQVEC_H #define SEQVEC_H #include class SeqCounter; // forward declaration class SeqReorderVector; // forward declaration /////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq * This enum can be used to determine the encoding scheme of a list of values: * - linearEncoding : values are played out in the same order as specified * - reverseEncoding : values are played out in the reverse order as specified * - centerOutEncoding : encoding start in the center of values and moves outwards alternatingly in positive/negative direction * - centerInEncoding : encoding starts outwards and moves inwards alternatingly in positive/negative direction * - maxDistEncoding : Maximum distance between consecutive elements */ enum encodingScheme {linearEncoding=0, reverseEncoding, centerOutEncoding, centerInEncoding, maxDistEncoding}; /** * @ingroup odinseq * This enum can be used to determine the reordering scheme of a list of values: * - noReorder : No reordering is performed, the number of reorderings is then equal one * - rotateReorder : The values will be rotated, the number of reorderings is then the number of values * - blockedSegmented : The values will be divided into segments, preserving their order * - interleavedSegmented : The values will be divided into segments like distributing game cards */ enum reorderScheme {noReorder=0,rotateReorder,blockedSegmented,interleavedSegmented}; /** * @ingroup odinseq_internals * This enum holds information about how a certain vector and its reordering * are nested in the sequence tree: * - noRelation : They are not nested * - reorderInner : The reorder vector is attached to an inner loop * - vecInner : The reorder vector is attached to an outer loop * - unrolledLoop : The loop which uses the vector will be unrolled in the program */ enum nestingRelation {noRelation=0, reorderInner, vecInner, unrolledLoop}; /////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This is the base class for all vector objects, i.e. objects that can * can take different values while looping over them. */ class SeqVector : public ListItem, public Handled, public virtual SeqClass { public: /** * Default Constructor */ SeqVector(const STD_string& object_label="unnamedSeqVector"); /** * Constructs an index vector labeled 'object_label' with the following properties: * - nindices: the total number of iterations * - slope: the number of indices per iteration * - offset: the offset of the indices, i.e. the index of the first iteration */ SeqVector(const STD_string& object_label, unsigned int nindices, int slope=1, int offset=0 ); /** * Copy Constructor */ SeqVector(const SeqVector& sv); /** * Destructor */ virtual ~SeqVector(); /** * Assignment operator that makes this vector become a copy of 'sv' */ SeqVector& operator = (const SeqVector& sv); /** * Overload this function to return the number of elements in the vector * (regardless of reordering) */ virtual unsigned int get_vectorsize() const {return indexvec.size();} /** * Returns the number of iterations with proper * consideration of reordering, e.g. if the vector has N values distributed * over M reordering segments, this function will return N/M. */ virtual unsigned int get_numof_iterations() const; /** * Overload this function to trigger a check whether the loop must possibly be unrolled * in pulse or gradient program */ virtual bool needs_unrolling_check() const {return false;} /** * Overload this function to prepare objects at run-time before the execution of a loop repetition * return 'false' when preparation fails */ virtual bool prep_iteration() const {return true;} /** * Overload this function to return the current index, intended to use it in * combination with reordering of phase encoding steps or slices */ virtual int get_current_index() const; /** * Returns the current index relevant for acquisition (reco dimensions). * This is the value of the index vector (set_indexvec) at the position * returned by 'get_current_index'. */ int get_acq_index() const; /** * Overload this function to tell whether the vector qualitatively alters the * sequence concerning timings and RF power deposition. * This is useful for accelerating duration and SAR calculations (Siemens). */ virtual bool is_qualvector() const; /** * Returns whether this vector is used to specify an acquisition dimension through the * set_*_vector(...) functions of all classes derived from SeqAcqInterface */ virtual bool is_acq_vector() const; /** * Returns whether this vector uses a different set of sequence objects at each repetition */ virtual bool is_obj_vector() const {return false;} /** * If the vector is used as a variable in the code-generated pulse program, * overload this function to return a unique label/command for the vector * which is either attached to the loop (Bruker), or executed at the beginning * of the loop (EPIC). */ virtual svector get_vector_commands(const STD_string& iterator) const {return svector();} /** * Overload this function to return the command to iterate to the next item at the end of the loop */ virtual STD_string get_loopcommand() const {return "";} /** * Sets the vector of indices 'iv' which will be returned by get_acq_index, * i.e. the assign reco indices (positions in k-space) */ SeqVector& set_indexvec(const ivector& iv) {indexvec=iv; return *this;} /** * Returns the vector of indices 'iv' which will be returned by get_acq_index, * i.e. the assign reco indices (positions in k-space) */ ivector get_indexvec() const {return indexvec;} /** * Sets the reordering scheme and the number of segments */ SeqVector& set_reorder_scheme(reorderScheme scheme, unsigned int nsegments=1); /** * Sets the encoding scheme */ SeqVector& set_encoding_scheme(encodingScheme scheme); /** * Returns the reordering vector (for loop insertion) */ const SeqVector& get_reorder_vector() const; /** * Returns the nesting relation between the vector and its reordering vector */ virtual nestingRelation get_nesting_relation() const; /** * Returns a matrix whereby the elements of rows (second dimension) * contain the reordered index for each iteration. The other * dimension (first dimension) represents reordering iterations. */ iarray get_index_matrix() const; /** * Returns the current index of the reordering vector */ int get_current_reord_index() const; /** * Returns the iterator as modified by the reorder vector as C code */ STD_string get_reord_iterator(const STD_string& iterator) const; protected: /** * Tell reorder vector what to do within a loop */ virtual svector get_reord_vector_commands(const STD_string& iterator) const {return svector();} /** * Returns true if vector is actually handled by a loop */ bool is_handled() const {return vechandler.get_handled();} private: friend class SeqReorderVector; friend class SeqCounter; friend class SeqObjLoop; friend class SeqSimultanVector; #ifdef SELF_FRIEND_CLASS friend class SeqVector; // making the class itself a friend is required for MSVC6 !! #endif /** * Returns whether the loop that controls this vector is currently iterating */ bool loopcounter_is_active() const; /** * Returns the current iteration */ int get_loopcounter() const; void common_int(); virtual const SeqVector& set_vechandler(const SeqCounter *sc) const; ivector indexvec; Handler vechandler; Handler simhandler; mutable SeqReorderVector* reordvec; mutable nestingRelation nr_cache; mutable bool nr_cache_up2date; }; /////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This vector class is used to change the order of a list of values, e.g. * to change the order of frequencies to reorder slice selection */ class SeqReorderVector : public SeqVector { public: SeqReorderVector(const SeqVector* user, const SeqReorderVector* copy_templ=0); unsigned int get_reordered_size(unsigned int vecsize) const; int get_reordered_index(int counter) const {return get_reordered_index(counter,get_current_index());} private: friend class SeqVector; // implemented virtual functions of SeqVector unsigned int get_vectorsize() const; bool needs_unrolling_check() const {return reord_scheme!=noReorder;} bool prep_iteration() const {return reorder_user->prep_iteration();} bool is_qualvector() const {return reorder_user->is_qualvector();} bool is_acq_vector() const {return reorder_user->is_acq_vector();} svector get_vector_commands(const STD_string& iterator) const; int get_reordered_index(int counter, int reord_iteration) const; STD_string get_reordered_iterator(const STD_string& iterator) const; void clear_cache() {reord_iterator_cache="";} reorderScheme reord_scheme; unsigned int n_reord_segments; encodingScheme encoding_scheme; const SeqVector* reorder_user; mutable STD_string reord_iterator_cache; }; #endif odin-1.8.5/odinseq/seqgradtrapez.cpp0000644000175000017500000003513111455553540014433 00000000000000#include "seqgradtrapez.h" SeqGradTrapezDefault::SeqGradTrapezDefault() { const_dur=0.0; exclude_offramp=false; } SeqGradTrapezDefault::SeqGradTrapezDefault(const SeqGradTrapezDefault& sgtd) : SeqGradTrapezDriver(sgtd), SeqGradChan(sgtd) { graddriver->set_label(STD_string(sgtd.get_label())); onramp_cache=sgtd.onramp_cache; offramp_cache=sgtd.offramp_cache; const_dur=sgtd.const_dur; exclude_offramp=sgtd.exclude_offramp; } bool SeqGradTrapezDefault::update_driver(direction channel, double onrampdur, double constdur, double offrampdur, float strength, double timestep, rampType type, bool exclude_offramp_from_timing) { Log odinlog(this,"update_driver"); STD_string objlabel(get_label()); set_duration(onrampdur+constdur+offrampdur); // Store redundant info, e.g. for correct display in sequence tree double mingraddur=0.0; if(constdurset_label(get_label()); return graddriver->prep_trapez(get_strength(),get_grdfactors_norot(), onramp_cache.get_gradduration(), onramp_cache.get_wave(), const_dur, offramp_cache.get_gradduration(), offramp_cache.get_wave()); } STD_string SeqGradTrapezDefault::get_properties() const { return SeqGradChan::get_properties()+", up/const/down="+ftos(onramp_cache.get_gradduration())+"/"+ftos(const_dur)+"/"+ftos(offramp_cache.get_gradduration()); } SeqGradInterface& SeqGradTrapezDefault::set_strength(float gradstrength) { SeqGradChan::set_strength(gradstrength); onramp_cache.set_strength(gradstrength); offramp_cache.set_strength(gradstrength); return *this; } SeqGradInterface& SeqGradTrapezDefault::invert_strength() { SeqGradChan::invert_strength(); onramp_cache.invert_strength(); offramp_cache.invert_strength(); return *this; } float SeqGradTrapezDefault::get_integral() const { return onramp_cache.get_gradintegral().sum() + get_strength()*const_dur + offramp_cache.get_gradintegral().sum(); } double SeqGradTrapezDefault::get_gradduration() const { double result=onramp_cache.get_gradduration()+const_dur; if(!exclude_offramp) result+=offramp_cache.get_gradduration(); return result; } SeqGradInterface& SeqGradTrapezDefault::set_gradrotmatrix(const RotMatrix& matrix) { SeqGradChan::set_gradrotmatrix(matrix); onramp_cache.set_gradrotmatrix(matrix); offramp_cache.set_gradrotmatrix(matrix); return *this; } SeqGradChan& SeqGradTrapezDefault::get_subchan(double starttime, double endtime) const { SeqGradTrapezDefault* sgti= new SeqGradTrapezDefault(*this); sgti->set_temporary(); return *sgti; } /////////////////////////////////////////////////////////////// void SeqGradTrapez::common_init() { rampMode=linear; dt=0.0; steepnessfactor=1.0; exclude_offramp_timing=false; trapezchannel=readDirection; onrampdur=0.0; constdur=0.0; offrampdur=0.0; trapezstrength=0.0; } SeqGradTrapez::SeqGradTrapez(const STD_string& object_label, direction gradchannel,float gradstrength, double constgradduration, double timestep,rampType type, double minrampduration, float steepness) : SeqGradChanList(object_label), trapezdriver(object_label) { Log odinlog(this,"SeqGradTrapez"); ODINLOG(odinlog,normalDebug) << "gradstrength/constgradduration=" << gradstrength << "/" << constgradduration << STD_endl; common_init(); rampMode=type; dt=timestep; steepnessfactor=steepness; trapezchannel=gradchannel; constdur=constgradduration; trapezstrength=gradstrength; check_platform(); float rampintegral; get_ramps(get_label(), rampintegral, onrampdur, offrampdur, trapezstrength, dt, rampMode, steepnessfactor, minrampduration); update_driver(); build_seq(); } SeqGradTrapez::SeqGradTrapez(const STD_string& object_label, float gradintegral, direction gradchannel, double constgradduration, double timestep,rampType type, double minrampduration, float steepness) : SeqGradChanList(object_label), trapezdriver(object_label) { Log odinlog(this,"SeqGradTrapez"); common_init(); rampMode=type; dt=timestep; steepnessfactor=steepness; trapezchannel=gradchannel; if(constgradduration<=0.0) { // ramp-only gradient constdur=0.0; float sign=secureDivision(gradintegral,fabs(gradintegral)); trapezstrength=sign*sqrt(fabs(gradintegral)*systemInfo->get_max_slew_rate()); // Assume linear ramps } else { constdur=constgradduration; trapezstrength=secureDivision(gradintegral,constgradduration); } check_platform(); float rampintegral; get_ramps(get_label(), rampintegral, onrampdur, offrampdur, trapezstrength, dt, rampMode, steepnessfactor, minrampduration); // Fine-tune gradient integral float oldintegral=rampintegral+trapezstrength*constdur; trapezstrength*=secureDivision( gradintegral, oldintegral ); update_driver(); build_seq(); } SeqGradTrapez::SeqGradTrapez(const STD_string& object_label,float gradintegral, float gradstrength, direction gradchannel, double timestep, rampType type, double minrampduration, float steepness) : SeqGradChanList(object_label), trapezdriver(object_label) { Log odinlog(this,"SeqGradTrapez"); common_init(); rampMode=type; dt=timestep; steepnessfactor=steepness; trapezchannel=gradchannel; check_platform(); // Take note of sign of integral, apply later float sign=secureDivision(gradintegral,fabs(gradintegral)); // Use magnitude gradstrength=fabs(gradstrength); gradintegral=fabs(gradintegral); float rampintegral; get_ramps(get_label(), rampintegral, onrampdur, offrampdur, gradstrength, dt, rampMode, steepnessfactor, minrampduration); if(rampintegral<0.0) { // Consistency check: should be positive ODINLOG(odinlog,warningLog) << "Polarity mismatch: rampintegral=" << rampintegral << STD_endl; } if(rampintegral>gradintegral) { // Use ramp-only gradient constdur=0.0; trapezstrength=secureDivision(gradintegral,rampintegral)*gradstrength; // scale down ramp for correct integral } else { constdur=secureDivision(gradintegral-rampintegral,gradstrength); // Use const part for remainder trapezstrength=gradstrength; double rastertime=systemInfo->get_rastertime(gradObj); if(rastertime>0.0) { int nraster=(int)secureDivision(constdur,rastertime); if(rastertime*nraster!=constdur) nraster++; // always increase length of constant part constdur=nraster*rastertime; float rastered_integral=constdur*gradstrength+rampintegral; float scalefactor=secureDivision(gradintegral,rastered_integral); // scale down amplitude if(scalefactor>1.0) { ODINLOG(odinlog,warningLog) << "scalefactor=" << scalefactor << ", setting to 1" << STD_endl; } trapezstrength*=scalefactor; } } // Apply sign trapezstrength=sign*trapezstrength; update_driver(); build_seq(); } SeqGradTrapez::SeqGradTrapez(const SeqGradTrapez& sgt) { common_init(); SeqGradTrapez::operator = (sgt); } SeqGradTrapez::SeqGradTrapez(const STD_string& object_label) : SeqGradChanList(object_label), trapezdriver(object_label) { common_init(); } SeqGradTrapez& SeqGradTrapez::set_constgrad_duration(double duration) { constdur=duration; update_driver(); return *this; } SeqGradTrapez& SeqGradTrapez::set_integral(float gradintegral) { float newstrength=secureDivision( gradintegral, get_integral() )*trapezstrength; trapezstrength=newstrength; update_driver(); return *this; } float SeqGradTrapez::get_integral() const { return get_onramp_integral()+get_constgrad_integral()+get_offramp_integral(); } unsigned int SeqGradTrapez::get_onramp_npts() const { return (unsigned int)( secureDivision(onrampdur, dt)+0.5); } unsigned int SeqGradTrapez::get_const_npts() const { return (unsigned int)( secureDivision(constdur, dt)+0.5); } unsigned int SeqGradTrapez::get_offramp_npts() const { return (unsigned int)( secureDivision(offrampdur, dt)+0.5); } unsigned int SeqGradTrapez::get_npts() const { return ( get_onramp_npts()+ get_const_npts() + get_offramp_npts() ); } fvector SeqGradTrapez::get_trapezshape() const { fvector result(get_npts()); fvector onramp(get_onramp()); fvector offramp(get_offramp()); unsigned int index=0; unsigned int i; for(i=0; i odinlog(this,"check_platform"); ODINLOG(odinlog,normalDebug) << "checking if dt is valid on current platform" << STD_endl; double min_dt=systemInfo->get_min_grad_rastertime(); if(dtget_min_grad_rastertime()) { dt=min_dt; } ODINLOG(odinlog,normalDebug) << "checking if ramptype is valid on current platform" << STD_endl; if(!trapezdriver->check_ramptype(rampMode)) { ODINLOG(odinlog,errorLog) << "rampMode not supported on this platform" << STD_endl; } } void SeqGradTrapez::get_ramps(const STD_string& label, float& rampintegral, double& rampondur, double& rampoffdur, float strength, double dwelltime, rampType ramptype, float steepness, double mindur) { Log odinlog(label.c_str(),"get_ramps"); ODINLOG(odinlog,normalDebug) << "steepness/dwelltime=" << steepness << "/" << dwelltime << STD_endl; if( (steepness<=0.0) || (steepness>1.0) ) { ODINLOG(odinlog,warningLog) << "Steepness out of range, setting to 1.0" << STD_endl; steepness=1.0; } SeqGradRamp onramp4calc (label+"_onramp4calc", readDirection,0.0,strength,dwelltime,ramptype,steepness,false); SeqGradRamp offramp4calc(label+"_offramp4calc",readDirection,strength,0.0,dwelltime,ramptype,steepness,true); ODINLOG(odinlog,normalDebug) << "on/off/mindur=" << onramp4calc.get_duration() << "/" << offramp4calc.get_duration() << "/" << mindur << STD_endl; if(onramp4calc.get_duration() odinlog(this,"update_driver"); ODINLOG(odinlog,normalDebug) << "setting label" << STD_endl; trapezdriver->set_label(STD_string(get_label())); ODINLOG(odinlog,normalDebug) << "updating driver: onrampdur/constdur/offrampdur=" << onrampdur << "/" << constdur << "/" << offrampdur << STD_endl; trapezdriver->update_driver(trapezchannel,onrampdur,constdur,offrampdur,trapezstrength,dt,rampMode,exclude_offramp_timing); } void SeqGradTrapez::build_seq() { Log odinlog(this,"build_seq"); clear(); SeqGradChanList sgcl_driver(trapezdriver->get_driverchanlist()); (*this)+=sgcl_driver; } ////////////////////////////////////////////////////////// SeqGradTrapezParallel::SeqGradTrapezParallel(const STD_string& object_label, float gradintegral_read, float gradintegral_phase, float gradintegral_slice, float maxgradstrength, double timestep, rampType type, double minrampduration) : SeqGradChanParallel(object_label) { Log odinlog(this,"build_seq"); float maxint=maxof3(fabs(gradintegral_read),fabs(gradintegral_phase),fabs(gradintegral_slice)); ODINLOG(odinlog,normalDebug) << "maxint=" << maxint << STD_endl; // first, initialize sub-pulses with max integral: readgrad =SeqGradTrapez(object_label+"_readgrad", maxint,maxgradstrength,readDirection, timestep,type,minrampduration); phasegrad=SeqGradTrapez(object_label+"_phasegrad",maxint,maxgradstrength,phaseDirection,timestep,type,minrampduration); slicegrad=SeqGradTrapez(object_label+"_slicegrad",maxint,maxgradstrength,sliceDirection,timestep,type,minrampduration); ODINLOG(odinlog,normalDebug) << "readgrad.get_gradintegral()=" << readgrad.get_gradintegral().printbody() << STD_endl; // second, adjust strength readgrad. set_strength(secureDivision(gradintegral_read, maxint)*readgrad.get_strength()); phasegrad.set_strength(secureDivision(gradintegral_phase,maxint)*phasegrad.get_strength()); slicegrad.set_strength(secureDivision(gradintegral_slice,maxint)*slicegrad.get_strength()); ODINLOG(odinlog,normalDebug) << "readgrad.get_gradintegral()=" << readgrad.get_gradintegral().printbody() << STD_endl; build_seq(); } SeqGradTrapezParallel::SeqGradTrapezParallel(const SeqGradTrapezParallel& sgtp) : SeqGradChanParallel(sgtp) { SeqGradTrapezParallel::operator = (sgtp); } SeqGradTrapezParallel::SeqGradTrapezParallel(const STD_string& object_label) : SeqGradChanParallel(object_label) { } SeqGradTrapezParallel& SeqGradTrapezParallel::operator = (const SeqGradTrapezParallel& sgtp) { SeqGradChanParallel::operator = (sgtp); readgrad =sgtp.readgrad; phasegrad=sgtp.phasegrad; slicegrad=sgtp.slicegrad; build_seq(); return *this; } void SeqGradTrapezParallel::build_seq() { clear(); (*this)+=readgrad/phasegrad/slicegrad; } odin-1.8.5/odinseq/seqgradwave.h0000644000175000017500000000715511322062345013531 00000000000000/*************************************************************************** seqgradwave.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADWAVE_H #define SEQGRADWAVE_H #include /** * @addtogroup odinseq * @{ */ /** * \brief Gradient Waveform * * This class represents a gradient object with an arbitrarily shaped gradient field * The physical gradient strengths of one data point is the product of the value * of the waveform at that point and the gradient strength of this object */ class SeqGradWave : public SeqGradChan { public: /** * Constructs a gradient waveform labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - gradduration: The duration of this gradient object * - maxgradstrength: The maximum gradient strength for this object * - waveform: The waveform that will be played out */ SeqGradWave(const STD_string& object_label,direction gradchannel, double gradduration, float maxgradstrength,const fvector& waveform); /** * Constructs a copy of 'sgw' */ SeqGradWave(const SeqGradWave& sgw); /** * Construct an empty gradient object with the given label */ SeqGradWave(const STD_string& object_label = "unnamedSeqGradWave"); /** * Specifies the waveform that will be used */ SeqGradWave& set_wave(const fvector& waveform); /** * Returns the waveform that will be used */ const fvector& get_wave() const {return wave;} /** * Returns the integral of the waveform time tmin to time tmax (relative to the starting point of the ramp) */ float get_integral(double tmin, double tmax) const; /** * Returns the number of digitised points for the waveform */ unsigned int get_npts() const; /** * Returns the number of digitised points for the waveform */ unsigned int size() const {return get_npts();} /** * Returns the sampling rate of the waveform */ double get_timestep() const {return secureDivision(get_gradduration(),double(get_npts()));} /** * Returns the i'th element of the waveform */ float operator [] (unsigned int i) const {return wave[i];} /** * Assignment operator that makes this gradient channel object become a copy of 'sgw' */ SeqGradWave& operator = (const SeqGradWave& sgw); protected: fvector wave; private: // overwriting virtual functions from SeqClass bool prep(); // overwriting virtual functions from SeqGradChan int get_wavesize() const; void resize(unsigned int newsize); SeqGradChan& get_subchan(double starttime, double endtime) const; STD_string get_grdpart(float matrixfactor) const; float get_integral() const {return get_integral(0.0,get_gradduration());} void check_wave(); }; /** @} */ #endif odin-1.8.5/odinseq/seqoperator.cpp0000644000175000017500000003563411322062345014122 00000000000000#include "seqoperator.h" #include "seqobj.h" #include "seqgradobj.h" #include "seqlist.h" #include "seqloop.h" #include "seqdec.h" #include "seqparallel.h" #include "seqgradchan.h" #include "seqgradchanlist.h" #include "seqgradchanparallel.h" void bad_parallel(const SeqGradInterface& s1, const SeqGradInterface& s2, direction chan) { Log odinlog("","bad_parallel"); ODINLOG(odinlog,errorLog) << s1.get_label() << "/" << s2.get_label() << " - same channel: " << directionLabel[chan] << STD_endl; } ///////////////////////////////////////////////////////////////// void SeqOperator::append_list2list(SeqObjList& dst, const SeqObjList& src) { if(src.gradrotmatrixvec.get_handled()) { dst+=src; // keep whole object in list for correct rotation } else { STD_list::const_iterator constiter; for(constiter=src.get_const_begin();constiter!=src.get_const_end();++constiter) { dst+=(**constiter); } } } SeqObjList& SeqOperator::create_SeqObjList_label(const STD_string& label1, const STD_string& label2, bool swap) { STD_string l1=label1; STD_string l2=label2; if(swap) { l1=label2; l2=label1; } SeqObjList* result=new SeqObjList(l1+"+"+l2); result->set_temporary(); return *result; } SeqObjList& SeqOperator::create_SeqObjList_obj(const SeqObjBase& s1, const SeqObjBase& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(!swap) result+=s1; result+=s2; if(swap) result+=s1; return result; } SeqObjList& SeqOperator::create_SeqObjList_list(const SeqObjList& s1, const SeqObjBase& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; append_list2list(result,s1); if(!swap) result+=s2; return result; } SeqGradChanList& SeqOperator::create_SeqGradChanList(const STD_string& label1, const STD_string& label2, bool swap) { STD_string l1=label1; STD_string l2=label2; if(swap) { l1=label2; l2=label1; } SeqGradChanList* result=new SeqGradChanList(l1+"+"+l2); result->set_temporary(); return *result; } SeqGradChanList& SeqOperator::create_SeqGradChanList(SeqGradChan& sgc) { SeqGradChanList* result=new SeqGradChanList("("+sgc.get_label()+")"); result->set_temporary(); (*result)+=sgc; return *result; } SeqGradChanParallel& SeqOperator::create_SeqGradChanParallel_concat(const STD_string& label1, const STD_string& label2, bool swap) { STD_string l1=label1; STD_string l2=label2; if(swap) { l1=label2; l2=label1; } SeqGradChanParallel* result=new SeqGradChanParallel(l1+"+"+l2); result->set_temporary(); return *result; } SeqParallel& SeqOperator::create_SeqParallel(const STD_string& label1, const STD_string& label2) { SeqParallel* result=new SeqParallel(label1+"/"+label2); result->set_temporary(); return *result; } SeqGradChanParallel& SeqOperator::create_SeqGradChanParallel_simultan(const STD_string& label1, const STD_string& label2) { SeqGradChanParallel* result=new SeqGradChanParallel(label1+"/"+label2); result->set_temporary(); return *result; } //////////////////////////////////////////////////////////////////////////////////////////// SeqObjList& SeqOperator::concat(const SeqObjBase& s1, const SeqObjBase& s2) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),false); result+=s1; result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, const SeqObjList& s2, bool swap) { return create_SeqObjList_list(s2,s1,!swap); } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, const SeqObjLoop& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, const SeqDecoupling& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, const SeqParallel& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, SeqGradChan& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(!swap) result+=s1; result+=s2; if(swap) result+=s1; return result; } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, SeqGradChanList& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(!swap) result+=s1; result+=s2; if(swap) result+=s1; return result; } SeqObjList& SeqOperator::concat(const SeqObjBase& s1, SeqGradChanParallel& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(!swap) result+=s1; result+=s2; if(swap) result+=s1; return result; } SeqObjList& SeqOperator::concat(const SeqObjList& s1, const SeqObjList& s2) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),false); append_list2list(result,s1); append_list2list(result,s2); return result; } SeqObjList& SeqOperator::concat(const SeqObjList& s1, const SeqObjLoop& s2, bool swap) { return create_SeqObjList_list(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjList& s1, const SeqDecoupling& s2, bool swap) { return create_SeqObjList_list(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjList& s1, const SeqParallel& s2, bool swap) { return create_SeqObjList_list(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjList& s1, SeqGradChan& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; append_list2list(result,s1); if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjList& s1, SeqGradChanList& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; append_list2list(result,s1); if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjList& s1, SeqGradChanParallel& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; append_list2list(result,s1); if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, const SeqObjLoop& s2) { return create_SeqObjList_obj(s1,s2,false); } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, const SeqDecoupling& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, const SeqParallel& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, SeqGradChan& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, SeqGradChanList& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqObjLoop& s1, SeqGradChanParallel& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqDecoupling& s1, const SeqDecoupling& s2) { return create_SeqObjList_obj(s1,s2,false); } SeqObjList& SeqOperator::concat(const SeqDecoupling& s1, const SeqParallel& s2, bool swap) { return create_SeqObjList_obj(s1,s2,swap); } SeqObjList& SeqOperator::concat(const SeqDecoupling& s1, SeqGradChan& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqDecoupling& s1, SeqGradChanList& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqDecoupling& s1, SeqGradChanParallel& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqParallel& s1, const SeqParallel& s2) { return create_SeqObjList_obj(s1,s2,false); } SeqObjList& SeqOperator::concat(const SeqParallel& s1, SeqGradChan& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqParallel& s1, SeqGradChanList& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqObjList& SeqOperator::concat(const SeqParallel& s1, SeqGradChanParallel& s2, bool swap) { SeqObjList& result=create_SeqObjList_label(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqGradChanList& SeqOperator::concat(SeqGradChan& s1, SeqGradChan& s2) { SeqGradChanList& result=create_SeqGradChanList(s1.get_label(),s2.get_label(),false); result+=s1; result+=s2; return result; } SeqGradChanList& SeqOperator::concat(SeqGradChan& s1, SeqGradChanList& s2, bool swap) { SeqGradChanList& result=create_SeqGradChanList(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqGradChanParallel& SeqOperator::concat(SeqGradChan& s1, SeqGradChanParallel& s2, bool swap) { SeqGradChanParallel& result=create_SeqGradChanParallel_concat(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqGradChanList& SeqOperator::concat(SeqGradChanList& s1, SeqGradChanList& s2) { SeqGradChanList& result=create_SeqGradChanList(s1.get_label(),s2.get_label(),false); result+=s1; result+=s2; return result; } SeqGradChanParallel& SeqOperator::concat(SeqGradChanList& s1, SeqGradChanParallel& s2, bool swap) { SeqGradChanParallel& result=create_SeqGradChanParallel_concat(s1.get_label(),s2.get_label(),swap); if(swap) result+=s2; result+=s1; if(!swap) result+=s2; return result; } SeqGradChanParallel& SeqOperator::concat(SeqGradChanParallel& s1, SeqGradChanParallel& s2) { SeqGradChanParallel& result=create_SeqGradChanParallel_concat(s1.get_label(),s2.get_label(),false); result+=s1; result+=s2; return result; } //////////////////////////////////////////////////////////////////////////////////////////// SeqParallel& SeqOperator::simultan(const SeqObjBase& s1, SeqGradObjInterface& s2) { SeqParallel& result=create_SeqParallel(s1.get_label(),s2.get_label()); result.set_pulsptr(&s1); result.set_gradptr(&s2); return result; } SeqParallel& SeqOperator::simultan(const SeqObjBase& s1, SeqGradChan& s2) { SeqParallel& result=create_SeqParallel(s1.get_label(),s2.get_label()); result.set_pulsptr(&s1); SeqGradChanParallel* sgcp=new SeqGradChanParallel("{"+s2.get_label()+"}"); sgcp->set_temporary(); (*sgcp)+=s2; result.set_gradptr((SeqGradObjInterface*)sgcp); return result; } SeqParallel& SeqOperator::simultan(const SeqObjBase& s1, SeqGradChanList& s2) { SeqParallel& result=create_SeqParallel(s1.get_label(),s2.get_label()); result.set_pulsptr(&s1); SeqGradChanParallel* sgcp=new SeqGradChanParallel("{"+s2.get_label()+"}"); sgcp->set_temporary(); (*sgcp)+=s2; result.set_gradptr((SeqGradObjInterface*)sgcp); return result; } SeqGradChanParallel& SeqOperator::simultan(SeqGradChan& s1, SeqGradChan& s2) { SeqGradChanParallel& result=create_SeqGradChanParallel_simultan(s1.get_label(),s2.get_label()); if(s1.get_channel()==s2.get_channel()) { bad_parallel(s1,s2,s1.get_channel()); return result; } result.set_gradchan(s1.get_channel(),&create_SeqGradChanList(s1)); result.set_gradchan(s2.get_channel(),&create_SeqGradChanList(s2)); return result; } SeqGradChanParallel& SeqOperator::simultan(SeqGradChan& s1, SeqGradChanList& s2) { SeqGradChanParallel& result=create_SeqGradChanParallel_simultan(s1.get_label(),s2.get_label()); if(s2.size() && s1.get_channel()==s2.get_channel()) { bad_parallel(s1,s2,s1.get_channel()); return result; } result.set_gradchan(s1.get_channel(),&create_SeqGradChanList(s1)); SeqGradChanList* s2_copy=new SeqGradChanList(s2); s2_copy->set_temporary(); result.set_gradchan(s2.get_channel(),s2_copy); return result; } SeqGradChanParallel& SeqOperator::simultan(SeqGradChan& s1, SeqGradChanParallel& s2) { SeqGradChanParallel* result=new SeqGradChanParallel(s2); result->set_label(s1.get_label()+"/"+s2.get_label()); result->set_temporary(); if(result->get_gradchan(s1.get_channel())) { bad_parallel(s1,s2,s1.get_channel()); return *result; } result->set_gradchan(s1.get_channel(),&create_SeqGradChanList(s1)); return (*result); } SeqGradChanParallel& SeqOperator::simultan(SeqGradChanList& s1, SeqGradChanList& s2) { Log odinlog("SeqOperator","simultan"); SeqGradChanParallel& result=create_SeqGradChanParallel_simultan(s1.get_label(),s2.get_label()); if(s1.size() && s2.size()) { if(s1.get_channel()==s2.get_channel()) { bad_parallel(s1,s2,s1.get_channel()); return result; } } ODINLOG(odinlog,normalDebug) << "chan1/2=" << s1.get_channel() << "/" << s2.get_channel() << STD_endl; SeqGradChanList* s1_copy=new SeqGradChanList(s1); s1_copy->set_temporary(); result.set_gradchan(s1.get_channel(),s1_copy); SeqGradChanList* s2_copy=new SeqGradChanList(s2); s2_copy->set_temporary(); result.set_gradchan(s2.get_channel(),s2_copy); return result; } SeqGradChanParallel& SeqOperator::simultan(SeqGradChanList& s1, SeqGradChanParallel& s2) { SeqGradChanParallel *result=new SeqGradChanParallel(s2); result->set_label(s1.get_label()+"/"+s2.get_label()); result->set_temporary(); if(result->get_gradchan(s1.get_channel())) { bad_parallel(s1,s2,s1.get_channel()); return *result; } else { SeqGradChanList* s1_copy=new SeqGradChanList(s1); s1_copy->set_temporary(); result->set_gradchan(s1.get_channel(),s1_copy); } return *result; } SeqGradChanParallel& SeqOperator::simultan(SeqGradChanParallel& s1, SeqGradChanParallel& s2) { SeqGradChanParallel *result=new SeqGradChanParallel(s2); result->set_label(s1.get_label()+"/"+s2.get_label()); result->set_temporary(); for(unsigned int cn=readDirection; cn <= sliceDirection; cn++) { direction chanNo=direction(cn); if(result->get_gradchan(chanNo) && s1.get_gradchan(chanNo)) { bad_parallel(s1,s2,chanNo); return *result; } else { if(s1.get_gradchan(chanNo)) { SeqGradChanList* s1_copy=new SeqGradChanList(*s1.get_gradchan(chanNo)); s1_copy->set_temporary(); result->set_gradchan(chanNo,s1_copy); } } } return *result; } odin-1.8.5/odinseq/seqoperator.h0000644000175000017500000003662611322062345013571 00000000000000/*************************************************************************** seqoperator.h - description ------------------- begin : Mon Apr 19 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQOPERATOR_H #define SEQOPERATOR_H #include // forward declarations class SeqObjBase; class SeqGradObjInterface; class SeqObjList; class SeqObjLoop; class SeqDecoupling; class SeqParallel; class SeqGradChan; class SeqGradChanList; class SeqGradChanParallel; /** * @ingroup odinseq_internals * A class for connecting sequence objects via operators. */ class SeqOperator : public SeqClass { public: static SeqObjList& concat(const SeqObjBase& s1, const SeqObjBase& s2); static SeqObjList& concat(const SeqObjBase& s1, const SeqObjList& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, const SeqObjLoop& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, const SeqDecoupling& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, const SeqParallel& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, SeqGradChan& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, SeqGradChanList& s2, bool swap); static SeqObjList& concat(const SeqObjBase& s1, SeqGradChanParallel& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, const SeqObjList& s2); static SeqObjList& concat(const SeqObjList& s1, const SeqObjLoop& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, const SeqDecoupling& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, const SeqParallel& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, SeqGradChan& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, SeqGradChanList& s2, bool swap); static SeqObjList& concat(const SeqObjList& s1, SeqGradChanParallel& s2, bool swap); static SeqObjList& concat(const SeqObjLoop& s1, const SeqObjLoop& s2); static SeqObjList& concat(const SeqObjLoop& s1, const SeqDecoupling& s2, bool swap); static SeqObjList& concat(const SeqObjLoop& s1, const SeqParallel& s2, bool swap); static SeqObjList& concat(const SeqObjLoop& s1, SeqGradChan& s2, bool swap); static SeqObjList& concat(const SeqObjLoop& s1, SeqGradChanList& s2, bool swap); static SeqObjList& concat(const SeqObjLoop& s1, SeqGradChanParallel& s2, bool swap); static SeqObjList& concat(const SeqDecoupling& s1, const SeqDecoupling& s2); static SeqObjList& concat(const SeqDecoupling& s1, const SeqParallel& s2, bool swap); static SeqObjList& concat(const SeqDecoupling& s1, SeqGradChan& s2, bool swap); static SeqObjList& concat(const SeqDecoupling& s1, SeqGradChanList& s2, bool swap); static SeqObjList& concat(const SeqDecoupling& s1, SeqGradChanParallel& s2, bool swap); static SeqObjList& concat(const SeqParallel& s1, const SeqParallel& s2); static SeqObjList& concat(const SeqParallel& s1, SeqGradChan& s2, bool swap); static SeqObjList& concat(const SeqParallel& s1, SeqGradChanList& s2, bool swap); static SeqObjList& concat(const SeqParallel& s1, SeqGradChanParallel& s2, bool swap); static SeqGradChanList& concat(SeqGradChan& s1, SeqGradChan& s2); static SeqGradChanList& concat(SeqGradChan& s1, SeqGradChanList& s2, bool swap); static SeqGradChanParallel& concat(SeqGradChan& s1, SeqGradChanParallel& s2, bool swap); static SeqGradChanList& concat(SeqGradChanList& s1, SeqGradChanList& s2); static SeqGradChanParallel& concat(SeqGradChanList& s1, SeqGradChanParallel& s2, bool swap); static SeqGradChanParallel& concat(SeqGradChanParallel& s1, SeqGradChanParallel& s2); static SeqParallel& simultan(const SeqObjBase& s1, SeqGradObjInterface& s2); static SeqParallel& simultan(const SeqObjBase& s1, SeqGradChan& s2); static SeqParallel& simultan(const SeqObjBase& s1, SeqGradChanList& s2); static SeqGradChanParallel& simultan(SeqGradChan& s1, SeqGradChan& s2); static SeqGradChanParallel& simultan(SeqGradChan& s1, SeqGradChanList& s2); static SeqGradChanParallel& simultan(SeqGradChan& s1, SeqGradChanParallel& s2); static SeqGradChanParallel& simultan(SeqGradChanList& s1, SeqGradChanList& s2); static SeqGradChanParallel& simultan(SeqGradChanList& s1, SeqGradChanParallel& s2); static SeqGradChanParallel& simultan(SeqGradChanParallel& s1, SeqGradChanParallel& s2); private: static void append_list2list(SeqObjList& dst, const SeqObjList& src); static SeqObjList& create_SeqObjList_label(const STD_string& label1, const STD_string& label2, bool swap); static SeqObjList& create_SeqObjList_obj(const SeqObjBase& s1, const SeqObjBase& s2, bool swap); static SeqObjList& create_SeqObjList_list(const SeqObjList& s1, const SeqObjBase& s2, bool swap); static SeqGradChanList& create_SeqGradChanList(const STD_string& label1, const STD_string& label2, bool swap); static SeqGradChanList& create_SeqGradChanList(SeqGradChan& sgc); static SeqGradChanParallel& create_SeqGradChanParallel_concat(const STD_string& label1, const STD_string& label2, bool swap); static SeqParallel& create_SeqParallel(const STD_string& label1, const STD_string& label2); static SeqGradChanParallel& create_SeqGradChanParallel_simultan(const STD_string& label1, const STD_string& label2); }; inline SeqObjList& operator + (const SeqObjBase& s1, const SeqObjBase& s2){return SeqOperator::concat(s1,s2);} inline SeqObjList& operator + (const SeqObjBase& s1, const SeqObjList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, const SeqParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjBase& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqObjList& s1, const SeqObjList& s2) {return SeqOperator::concat(s1,s2);} inline SeqObjList& operator + (const SeqObjList& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, const SeqParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjList& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjLoop& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqObjLoop& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqObjLoop& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s1,s2);} inline SeqObjList& operator + (const SeqObjLoop& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjLoop& s1, const SeqParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjLoop& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjLoop& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqObjLoop& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqDecoupling& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqDecoupling& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqDecoupling& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqDecoupling& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s1,s2);} inline SeqObjList& operator + (const SeqDecoupling& s1, const SeqParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqDecoupling& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqDecoupling& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqDecoupling& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqParallel& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqParallel& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqParallel& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqParallel& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (const SeqParallel& s1, const SeqParallel& s2) {return SeqOperator::concat(s1,s2);} inline SeqObjList& operator + (const SeqParallel& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqParallel& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (const SeqParallel& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (SeqGradChan& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChan& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChan& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChan& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChan& s1, const SeqParallel& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanList& operator + (SeqGradChan& s1, SeqGradChan& s2) {return SeqOperator::concat(s1,s2);} inline SeqGradChanList& operator + (SeqGradChan& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqGradChanParallel& operator + (SeqGradChan& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (SeqGradChanList& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanList& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanList& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanList& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanList& s1, const SeqParallel& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanList& operator + (SeqGradChanList& s1, SeqGradChan& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanList& operator + (SeqGradChanList& s1, SeqGradChanList& s2) {return SeqOperator::concat(s1,s2);} inline SeqGradChanParallel& operator + (SeqGradChanList& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2,false);} inline SeqObjList& operator + (SeqGradChanParallel& s1, const SeqObjBase& s2){return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanParallel& s1, const SeqObjList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanParallel& s1, const SeqObjLoop& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanParallel& s1, const SeqDecoupling& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqObjList& operator + (SeqGradChanParallel& s1, const SeqParallel& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanParallel& operator + (SeqGradChanParallel& s1, SeqGradChan& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanParallel& operator + (SeqGradChanParallel& s1, SeqGradChanList& s2) {return SeqOperator::concat(s2,s1,true);} inline SeqGradChanParallel& operator + (SeqGradChanParallel& s1, SeqGradChanParallel& s2) {return SeqOperator::concat(s1,s2);} inline SeqParallel& operator / (const SeqObjBase& s1, SeqGradObjInterface& s2) {return SeqOperator::simultan(s1,s2);} inline SeqParallel& operator / (SeqGradObjInterface& s1, const SeqObjBase& s2) {return SeqOperator::simultan(s2,s1);} inline SeqParallel& operator / (const SeqObjBase& s1, SeqGradChan& s2) {return SeqOperator::simultan(s1,s2);} inline SeqParallel& operator / (SeqGradChan& s1, const SeqObjBase& s2) {return SeqOperator::simultan(s2,s1);} inline SeqParallel& operator / (const SeqObjBase& s1, SeqGradChanList& s2) {return SeqOperator::simultan(s1,s2);} inline SeqParallel& operator / (SeqGradChanList& s1, const SeqObjBase& s2) {return SeqOperator::simultan(s2,s1);} inline SeqGradChanParallel& operator / (SeqGradChan& s1, SeqGradChan& s2) {return SeqOperator::simultan(s1,s2);} inline SeqGradChanParallel& operator / (SeqGradChan& s1, SeqGradChanList& s2) {return SeqOperator::simultan(s1,s2);} inline SeqGradChanParallel& operator / (SeqGradChanList& s1, SeqGradChan& s2) {return SeqOperator::simultan(s2,s1);} inline SeqGradChanParallel& operator / (SeqGradChan& s1, SeqGradChanParallel& s2) {return SeqOperator::simultan(s1,s2);} inline SeqGradChanParallel& operator / (SeqGradChanParallel& s1, SeqGradChan& s2) {return SeqOperator::simultan(s2,s1);} inline SeqGradChanParallel& operator / (SeqGradChanList& s1, SeqGradChanList& s2) {return SeqOperator::simultan(s1,s2);} inline SeqGradChanParallel& operator / (SeqGradChanList& s1, SeqGradChanParallel& s2) {return SeqOperator::simultan(s1,s2);} inline SeqGradChanParallel& operator / (SeqGradChanParallel& s1, SeqGradChanList& s2) {return SeqOperator::simultan(s2,s1);} inline SeqGradChanParallel& operator / (SeqGradChanParallel& s1, SeqGradChanParallel& s2) {return SeqOperator::simultan(s1,s2);} #endif odin-1.8.5/odinseq/seqdiffweight.h0000644000175000017500000002001711322062345014041 00000000000000/*************************************************************************** seqdiffweight.h - description ------------------- begin : Wed Feb 12 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDIFFWEIGHT_H #define SEQDIFFWEIGHT_H #include #include #include #include #include #include /** * @addtogroup odinseq * @{ */ /** * * \brief Diffusion Weighting * * A bipolar gradient pulse for diffusion weighting * * The b-value and the properties of the gradient pulses are connected through the equation * * b = gamma^2 * delta^2 ( Delta - delta/3 ) G^2 * * - b: b-value * - gamma: gyromagnetic ratio * - delta: gradient pulse duration * - Delta: gradient pulse separation, the duration of midpart (sequence part which is enclosed by the two gradient) is considered here * - G: gradient strength * * The order in which the series of b-values is played out can be cyclically * reordered by using the vector which is returned by the get_reorder_vector() * function: At each iteration of this vector, the b-values are exchanged cyclically. */ class SeqDiffWeight : public SeqObjList, public SeqSimultanVector, public virtual SeqGradInterface { public: /** * Constructs a bipolar gradient pulse labeled 'object_label' with the following properties: * - bvals: The b-values for diffusion weighting, a postive value means that the first * gradient pulse will have positive polarity and the second gradient pulse a negative polarity. * These polarities are swapped in case of a negative b-value. * - maxgradstrength: The maximum gradient strength to use for the maximum b-value * - midpart: The sequence part which will be enclosed by the two gradient pulses. * - chan: The gradient channel for the gradient pulses. * - stejskalTanner: If set to 'true', both gradients will have the same polarity * - nucleus: The nucleus for which the gradient pulses will be calculated */ SeqDiffWeight(const STD_string& object_label, const fvector& bvals, float maxgradstrength, const SeqObjBase& midpart, direction chan, bool stejskalTanner=false, const STD_string& nucleus = "" ); /** * Constructs a bipolar gradient pulse labeled 'object_label' with the following properties: * - ndir: Number of uniformly ditributed directions * - bvals: The b-values for diffusion weighting, a postive value means that the first * gradient pulse will have positive polarity and the second gradient pulse a negative polarity. * These polarities are swapped in case of a negative b-value. * - maxgradstrength: The maximum gradient strength to use for the maximum b-value * - midpart: The sequence part which will be enclosed by the two gradient pulses. * - baseline_rep: Repetition rate of the baseline (b=0) scan. Not repeated if zero. * - stejskalTanner: If set to 'true', both gradients will have the same polarity * - nucleus: The nucleus for which the gradient pulses will be calculated */ SeqDiffWeight(const STD_string& object_label, unsigned int ndir, const fvector& bvals, float maxgradstrength, const SeqObjBase& midpart, unsigned int baseline_rep=0, bool stejskalTanner=false, const STD_string& nucleus = "" ); /** * Default constructor */ SeqDiffWeight(const STD_string& object_label = "unnamedSeqDiffWeight" ); /** * Copy constructor */ SeqDiffWeight(const SeqDiffWeight& sgdw) {SeqDiffWeight::operator = (sgdw);} /** * Assignment operator */ SeqDiffWeight& operator = (const SeqDiffWeight& sgdw); /** * Returns the first gradient lobe */ const SeqGradInterface& get_grad1() const {return par1;} /** * Returns the second gradient lobe */ const SeqGradInterface& get_grad2() const {return par2;} /** * Returns the duration of the first gradient lobe */ double get_grad1_duration() const {return par1.get_duration();} /** * Returns the duration of the second gradient lobe */ double get_grad2_duration() const {return par2.get_duration();} /** * Returns the duration of the part in the middle between the two gradient lobes */ double get_midpart_duration() const {return middle_part.get_duration();} /** * Returns the b-vectors used in subsequent order. */ const darray& get_b_vectors() const {return b_vectors_cache;} // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; fvector get_gradintegral() const; double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); // final overrider of virtual functions from SeqClass void clear_container() {SeqObjList::clear(); SeqSimultanVector::clear();} // implemented virtual functions from SeqVector bool is_qualvector() const {return false;} private: void build_seq(); SeqGradVectorPulse pfg1[n_directions]; SeqGradVectorPulse pfg2[n_directions]; SeqParallel par1; SeqParallel par2; SeqObjList middle_part; darray b_vectors_cache; }; ////////////////////////////////////////////////////////////////////////////////////////// /** * * \brief Flow-Compensated Diffusion Weighting * * A flow-compensated gradient train for diffusion weighting * */ class SeqDiffWeightFlowComp : public SeqGradChanList, public SeqSimultanVector { public: /** * Constructs a flow-compensated gradient train labeled 'object_label' with the following properties: * - bvals: The b-values for diffusion weighting, a postive value means that the first * gradient pulse will have positive polarity and the second gradient pulse a negative polarity. * These polarities are swapped in case of a negative b-value * - maxgradstrength: The maximum gradient strength to use for the maximum b-value * - chan: The gradient channel for the gradient pulses * - stimdelay: Extra delay between gradient sub-pulses to avoid stimulation * - nucleus: The nucleus for which the gradient pulses will be calculated */ SeqDiffWeightFlowComp(const STD_string& object_label, const fvector& bvals, float maxgradstrength, direction chan, double stimdelay=1.0, const STD_string& nucleus = "" ); /** * Default constructor */ SeqDiffWeightFlowComp(const STD_string& object_label = "unnamedSeqDiffWeightFlowComp" ); /** * Copy constructor */ SeqDiffWeightFlowComp(const SeqDiffWeightFlowComp& sgdwfc) {SeqDiffWeightFlowComp::operator = (sgdwfc);} /** * Assignment operator */ SeqDiffWeightFlowComp& operator = (const SeqDiffWeightFlowComp& sgdwfc); // final overrider of virtual functions from SeqClass void clear_container() {SeqGradChanList::clear(); SeqSimultanVector::clear();} // implemented virtual functions from SeqVector bool is_qualvector() const {return false;} private: void build_seq(); SeqGradVectorPulse pfg1; SeqGradVectorPulse pfg2; SeqGradVectorPulse pfg3; SeqGradDelay delay; }; /** @} */ #endif odin-1.8.5/odinseq/seqdriver.h0000644000175000017500000000654211322062345013223 00000000000000/*************************************************************************** seqdriver.h - description ------------------- begin : Sat Apr 3 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQDRIVER_H #define SEQDRIVER_H #include #include class SeqDriverBase : public virtual SeqClass { public: SeqDriverBase() {} virtual ~SeqDriverBase() {} virtual odinPlatform get_driverplatform() const = 0; }; ///////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The interface class for all driver (platform specific) classes */ template class SeqDriverInterface : public SeqClass { public: typedef D* (*create_driver_callback)(); SeqDriverInterface(const STD_string& driverlabel="unnamedSeqDriverInterface") : current_driver(0) { set_label(driverlabel); } virtual ~SeqDriverInterface(){ if(current_driver) delete current_driver; } SeqDriverInterface& operator = (const SeqDriverInterface& di) { SeqClass::operator = (di); if(current_driver) delete current_driver; current_driver=0; if(di.current_driver) current_driver=di.current_driver->clone_driver(); return *this; } D& operator * () {return *get_driver();} D* operator -> () {return get_driver();} private: // overwriting virtual functions from SeqClass bool prep() {return bool(get_driver());} // make sure correct driver is loaded D* get_driver() { odinPlatform current_pf=SeqPlatformProxy::get_current_platform(); if(!current_driver) allocate_driver(); else { odinPlatform driver_platform=current_driver->get_driverplatform(); if(driver_platform!=current_pf) { delete current_driver; allocate_driver(); } } if(!current_driver) { STD_cerr << "ERROR: " << get_label() << ": Driver missing for platform " << SeqPlatformProxy::get_platform_str(current_pf) << STD_endl; } if(current_driver->get_driverplatform()!=current_pf) { STD_string drvplat(SeqPlatformProxy::get_possible_platforms()[current_driver->get_driverplatform()]); STD_cerr << "ERROR: " << get_label() << ": Driver has wrong platform signature " << drvplat << ", but expected " << SeqPlatformProxy::get_platform_str(current_pf) << STD_endl; } return current_driver; } void allocate_driver() { current_driver=pfinterface->create_driver(current_driver); if(current_driver) current_driver->set_label(get_label()); } SeqPlatformProxy pfinterface; D* current_driver; }; #endif odin-1.8.5/odinseq/seqgradwave.cpp0000644000175000017500000001046011322062345014055 00000000000000#include "seqgradwave.h" SeqGradWave::SeqGradWave(const STD_string& object_label,direction gradchannel, double gradduration, float maxgradstrength,const fvector& waveform) : SeqGradChan(object_label,gradchannel,maxgradstrength,gradduration) { set_wave(waveform); } SeqGradWave::SeqGradWave(const SeqGradWave& sgw) { SeqGradWave::operator = (sgw); } SeqGradWave::SeqGradWave(const STD_string& object_label) : SeqGradChan(object_label) { } SeqGradWave& SeqGradWave::set_wave(const fvector& waveform) { Log odinlog(this,"set_wave"); wave=waveform; ODINLOG(odinlog,normalDebug) << "wave(" << wave.length() << ")" << STD_endl; return *this; } float SeqGradWave::get_integral(double tmin, double tmax) const { Log odinlog(this,"get_integral"); double dur=get_gradduration(); ODINLOG(odinlog,normalDebug) << "dur=" << dur << STD_endl; if(tmin<0.0) tmin=0.0; if(tmin>dur) tmin=dur; if(tmax<0.0) tmax=0.0; if(tmax>dur) tmax=dur; ODINLOG(odinlog,normalDebug) << "dur/tmin/tmax=" << dur << "/" << tmin << "/" << tmax << STD_endl; double len=double(wave.length()); unsigned int startindex=(unsigned int)(secureDivision(tmin,dur)*len+0.5); unsigned int endindex =(unsigned int)(secureDivision(tmax,dur)*len+0.5); ODINLOG(odinlog,normalDebug) << "len/startindex/endindex=" << len << "/" << startindex << "/" << endindex << STD_endl; float integral=wave.range(startindex,endindex).sum(); ODINLOG(odinlog,normalDebug) << "sum=" << integral << STD_endl; integral= secureDivision(integral * get_strength() * dur,len); ODINLOG(odinlog,normalDebug) << "integral=" << integral << STD_endl; return integral; } unsigned int SeqGradWave::get_npts() const { return wave.length(); } SeqGradWave& SeqGradWave::operator = (const SeqGradWave& sgw) { Log odinlog(this,"operator="); SeqGradChan::operator = (sgw); wave=sgw.wave; ODINLOG(odinlog,normalDebug) << "wave(" << wave.length() << ")" << STD_endl; return *this; } STD_string SeqGradWave::get_grdpart(float matrixfactor) const { return graddriver->get_wave_program(get_strength(),matrixfactor); } bool SeqGradWave::prep() { Log odinlog(this,"prep"); if(!SeqGradChan::prep()) return false; check_wave(); return graddriver->prep_wave(get_strength(),get_grdfactors_norot(),get_gradduration(),wave); } SeqGradChan& SeqGradWave::get_subchan(double starttime, double endtime) const { Log odinlog(this,"get_subchan"); double startindex_round=starttime/get_gradduration()*double(wave.length())*1000.0+0.5; double endindex_round= endtime/get_gradduration()*double(wave.length())*1000.0+0.5; unsigned int startindex=(unsigned int)(startindex_round)/1000; unsigned int endindex =(unsigned int)(endindex_round)/1000; ODINLOG(odinlog,normalDebug) << "startindex/endindex=" << startindex << "/" << endindex << STD_endl; JDXfloatArr subwave(wave.range(startindex,endindex)); if(!subwave.length()) { subwave.resize(1); if(wave.length()>startindex) subwave[0]=wave[startindex]; } ODINLOG(odinlog,normalDebug) << "starttime/endtime/length=" << starttime << "/" << endtime << "/" << subwave.length() << STD_endl; SeqGradWave* sgw= new SeqGradWave(STD_string(get_label())+"_("+ftos(starttime)+"-"+ftos(endtime)+")", get_channel(),endtime-starttime,get_strength(),subwave); sgw->prep(); // we have to call prep() manually here because prep_all() has already been executed sgw->set_temporary(); return *sgw; } int SeqGradWave::get_wavesize() const { Log odinlog(this,"get_wavesize"); ODINLOG(odinlog,normalDebug) << "wavesize=" << wave.length() << STD_endl; return wave.length(); } void SeqGradWave::resize(unsigned int newsize) { Log odinlog(this,"resize"); ODINLOG(odinlog,normalDebug) << "to " << newsize << STD_endl; wave.interpolate(newsize); check_wave(); graddriver->update_wave(wave); } void SeqGradWave::check_wave() { Log odinlog(this,"check_wave"); float max=0.0; for(unsigned int i=0; i 1.0) {if(fabs(wave[i])>max) max=fabs(wave[i]); wave[i]= 1.0;} if(wave[i]<-1.0) {if(fabs(wave[i])>max) max=fabs(wave[i]); wave[i]=-1.0;} } if(max>0.0) ODINLOG(odinlog,warningLog) << "Corrected SeqGradWave value of " << max << " to stay within [-1,1] limits" << STD_endl; } odin-1.8.5/odinseq/seqacqdeph.h0000644000175000017500000000565611322062345013342 00000000000000/*************************************************************************** seqacqdeph.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQDEPH_H #define SEQACQDEPH_H #include #include class SeqAcqInterface; // forward declaration /** * @addtogroup odinseq * @{ */ /** * This enum is used to specify the type of the pre-dephasing or post-rephasing gradient: * - FID: It will have opposite polarity * - spinEcho: It will have the same polarity * - rephase: Gradient pulse to rephase acquisition gradients */ enum dephaseMode {FID,spinEcho,rephase}; ////////////////////////////////////////////////////////////////////////// /** * \brief Pre-read dephasing * * This class provides a pre-dephasing or post-rephasing gradient pulse for acquisition objects */ class SeqAcqDeph : public SeqGradChanParallel { public: /** * Constructs a read dephase gradient pulse labeled 'object_label' with the following properties: * - acq: The acquisition object for which the dephasing should be performed * - polarity: Specifies whether the gradient will have balanced (FID) or * inverted polarity (spinEcho). */ SeqAcqDeph(const STD_string& object_label,const SeqAcqInterface& acq, dephaseMode mode = FID); /** * Constructs a copy of 'sad' */ SeqAcqDeph(const SeqAcqDeph& sad); /** * Construct an empty read dephase gradient pulse with the given label */ SeqAcqDeph(const STD_string& object_label = "unnamedSeqAcqDeph"); /** * Assignment operator that makes this object become a copy of 'sad' */ SeqAcqDeph& operator = (const SeqAcqDeph& sad); /** * returns vector to iterate through different segments in multi-shot EPI */ const SeqVector& get_epi_segment_vector() const; /** * returns vector to iterate through different GRAPPA interleaves in parallel-imaging EPI */ const SeqVector& get_epi_reduction_vector() const; private: void common_init(); SeqVector dummyvec; Handler segvec; }; /** @} */ #endif odin-1.8.5/odinseq/seqgradpulse.cpp0000644000175000017500000000463411322062345014251 00000000000000#include "seqgradpulse.h" SeqGradConstPulse::SeqGradConstPulse(const STD_string& object_label,direction gradchannel, float gradstrength, float gradduration) : SeqGradChanList(object_label), constgrad(object_label+"_grad",gradchannel,gradstrength,gradduration), offgrad(object_label+"_off",gradchannel,0.0){ SeqGradConstPulse::set_strength(gradstrength); // set duration of offgrad, do NOT call virtual functions in constructor (*this)+= constgrad + offgrad; } SeqGradConstPulse::SeqGradConstPulse(const SeqGradConstPulse& sgcp) { SeqGradConstPulse::operator = (sgcp); } SeqGradConstPulse::SeqGradConstPulse(const STD_string& object_label) : SeqGradChanList(object_label) {} SeqGradConstPulse& SeqGradConstPulse::operator = (const SeqGradConstPulse& sgcp) { SeqGradChanList::operator = (sgcp); constgrad=sgcp.constgrad; offgrad=sgcp.offgrad; clear(); (*this)+= constgrad + offgrad; return *this; } SeqGradInterface& SeqGradConstPulse::set_strength(float gradstrength) { constgrad.set_strength(gradstrength); offgrad.set_duration(systemInfo->get_grad_switch_time(constgrad.get_strength())); return *this; } ///////////////////////////////////////////////////////////////////////////////// SeqGradVectorPulse::SeqGradVectorPulse(const STD_string& object_label, direction gradchannel, float maxgradstrength, const fvector& trimarray, float gradduration) : SeqGradChanList(object_label), vectorgrad(object_label+"_grad",gradchannel,maxgradstrength,trimarray,gradduration), offgrad(object_label+"_off",gradchannel,0.0){ SeqGradVectorPulse::set_strength(maxgradstrength); // set duration of offgrad, do NOT call virtual functions in constructor (*this)+= vectorgrad + offgrad; } SeqGradVectorPulse::SeqGradVectorPulse(const SeqGradVectorPulse& sgvp) { SeqGradVectorPulse::operator = (sgvp); } SeqGradVectorPulse::SeqGradVectorPulse(const STD_string& object_label) : SeqGradChanList(object_label) { } SeqGradVectorPulse& SeqGradVectorPulse::operator = (const SeqGradVectorPulse& sgvp) { SeqGradChanList::operator = (sgvp); vectorgrad=sgvp.vectorgrad; offgrad=sgvp.offgrad; clear(); (*this)+= vectorgrad + offgrad; return *this; } SeqGradInterface& SeqGradVectorPulse::set_strength(float gradstrength) { vectorgrad.set_strength(gradstrength); offgrad.set_duration(systemInfo->get_grad_switch_time(vectorgrad.get_strength())); return *this; } odin-1.8.5/odinseq/seqcounter.h0000644000175000017500000001441611322062345013406 00000000000000/*************************************************************************** seqcounter.h - description ------------------- begin : Fri Jan 19 2007 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQCOUNTER_H #define SEQCOUNTER_H #include #include #include /** * @addtogroup odinseq_internals * @{ */ class SeqCounter; // forward declaration class SeqObjList; // forward declaration /** * The base class for platform specific drivers of counters objects to iterate over vectors */ class SeqCounterDriver : public SeqDriverBase { public: SeqCounterDriver() {} virtual ~SeqCounterDriver() {} /** * Will be called once during prepping the sequence */ virtual bool prep_driver() = 0; /** * Function to update driver internals which is called before * the driver is queried for actions, seqlist can be zero */ virtual void update_driver(const SeqCounter* counter, const SeqObjList* seqlist, const List* vectors) const = 0; /** * Duration the loop itself takes before iteration is started */ virtual double get_preduration () const = 0; /** * Duration the loop itself takes after its kernel is iterated */ virtual double get_postduration() const = 0; /** * Duration the loop itself takes before each iteration */ virtual double get_preduration_inloop() const = 0; /** * Duration the loop itself takes after each iteration */ virtual double get_postduration_inloop() const = 0; /** * Asks driver whether a program has to be created at all for the given context and loopkernel, * useful to avoid 'empty' loops in the program */ virtual bool create_program(programContext& context, const STD_string& loopkernel) const = 0; /** * Returns the head of the loop, i.e. code before the loop kernel */ virtual STD_string get_program_head(programContext& context, const STD_string& loopkernel, unsigned int times) const = 0; /** * Returns the tail of the loop, i.e. code after the loop kernel */ virtual STD_string get_program_tail(programContext& context, const STD_string& loopkernel, unsigned int times) const = 0; /** * Returns the head of the loop, i.e. code before the loop kernel if the loop is unrolled */ virtual STD_string get_program_head_unrolled(programContext& context, unsigned int index) const = 0; /** * Returns commands to iterate vectors manually */ virtual STD_string get_program_iterator(programContext& context) const = 0; /** * Will be called before vectors are prepped for the current iteration */ virtual void pre_vecprepevent (eventContext& context) const = 0; /** * Will be called after vectors are prepped for the current iteration * If repcounter>=0, the repetition display of the platform will be updated to 'repcounter' */ virtual void post_vecprepevent(eventContext& context, int repcounter) const = 0; /** * Will be called if any attribute of the counter was changed */ virtual void outdate_cache() const = 0; /** * Asks driver whether the loop should be unrolled i.e. whether each iteration will be * explicitely written to the program, seqlist can be zero */ virtual bool unroll_program(const SeqCounter* counter, const SeqObjList* seqlist, const List* vectors, programContext& context) const = 0; /** * Return an exact copy of this driver */ virtual SeqCounterDriver* clone_driver() const = 0; }; /////////////////////////////////////////////////////////////////////////////////// /** * The base class for objects iterating through vectors by incremental counting */ class SeqCounter : public Handled, public virtual SeqTreeObj { public: /** * Construct an empty counter object with the given label */ SeqCounter(const STD_string& object_label = "unnamedSeqCounter"); /** * Constructs a copy of 'sl' */ SeqCounter(const SeqCounter& sc); virtual ~SeqCounter() {} /** * Assignment operator */ SeqCounter& operator = (const SeqCounter& sc); /** * The number of iterations of this counter object */ virtual int get_times() const; /** * Adds a vector to this counter */ virtual void add_vector(const SeqVector& seqvector); // counter functions int get_counter() const {return counter;} // also used by SeqVector bool counter_is_active() const {return counter!=-1;} void init_counter(unsigned int start=0) const; void increment_counter() const {counter++;} void disable_counter() const {counter=-1;} // helper functions (also used by platform drivers) bool prep_veciterations() const; protected: // helpers to reduce template code mutable STD_list::const_iterator veciter; STD_list::const_iterator get_vecbegin() const {return vectors.get_const_begin();} STD_list::const_iterator get_vecend() const {return vectors.get_const_end();} unsigned int n_vectors() const {return vectors.size();} List vectors; void clear_vectorlist() {vectors.clear();} mutable SeqDriverInterface counterdriver; // overwriting virtual functions from SeqClass bool prep(); void clear_container(); private: friend class SeqVector; // helper functions (also used by SeqVector) virtual bool unroll_program(programContext& context) const {return true;} void set_vechandler_for_all() const; mutable int counter; }; /** @} */ #endif odin-1.8.5/odinseq/seqtrigg.h0000644000175000017500000001423011363773555013056 00000000000000/*************************************************************************** seqtrigg.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQTRIGG_H #define SEQTRIGG_H #include #include ////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of external triggers */ class SeqTriggerDriver : public SeqDriverBase { public: SeqTriggerDriver() {} virtual ~SeqTriggerDriver() {} virtual double get_postduration() const = 0; virtual bool prep_exttrigger(double duration) = 0; virtual bool prep_halttrigger() = 0; virtual bool prep_snaptrigger(const STD_string& snapshot_fname) = 0; virtual bool prep_resettrigger() = 0; virtual void event(eventContext& context, double start) const = 0; virtual STD_string get_program(programContext& context) const = 0; virtual SeqTriggerDriver* clone_driver() const = 0; }; ////////////////////////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * * \brief Output trigger * * Insert triggers for external devices into the sequence. */ class SeqTrigger : public SeqObjBase { public: /** * Constructs a trigger labeled 'object_label' with the following properties: * - duration: The duration of the trigger pulse */ SeqTrigger(const STD_string& object_label, double duration); /** * Default Constructor */ SeqTrigger(const STD_string& object_label = "unnamedSeqTrigger"); /** * Constructs a trigger which is a copy of 'st' */ SeqTrigger(const SeqTrigger& st) {SeqTrigger::operator = (st);} /** * This assignment operator will make this object become an exact copy of 'st'. */ SeqTrigger& operator = (const SeqTrigger& st); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; unsigned int event(eventContext& context) const; private: // overwriting virtual functions from SeqClass bool prep(); mutable SeqDriverInterface triggdriver; double triggdur; }; ////////////////////////////////////////////////////////////////////// /** * * \brief Input trigger * * Halt sequence until an input trigger is received (e.g. cardiac gating). */ class SeqHalt : public SeqObjBase { public: /** * Constructs a trigger labeled 'object_label' */ SeqHalt(const STD_string& object_label = "unnamedSeqHalt"); /** * Constructs a trigger which is a copy of 'sh' */ SeqHalt(const SeqHalt& sh) {SeqHalt::operator = (sh);} /** * This assignment operator will make this object become an exact copy of 'sh'. */ SeqHalt& operator = (const SeqHalt& sh); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; unsigned int event(eventContext& context) const; private: // overwriting virtual functions from SeqClass bool prep(); mutable SeqDriverInterface triggdriver; }; ////////////////////////////////////////////////////////////////////// /** * * \brief Magnetization snapshot * * This class is used to trigger a snapshot of the current magnetization * during simulation of the sequence. */ class SeqSnapshot : public SeqObjBase { public: /** * Constructs a trigger labeled 'object_label' with the following properties: * - snapshot_fname: The file name where the magnetization will be stored consecutively in float format. */ SeqSnapshot(const STD_string& object_label, const STD_string& snapshot_fname); /** * Default Constructor */ SeqSnapshot(const STD_string& object_label = "unnamedSeqSnapshot"); /** * Constructs a snapshot trigger which is a copy of 'ss' */ SeqSnapshot(const SeqSnapshot& ss) {SeqSnapshot::operator = (ss);} /** * This assignment operator will make this object become an exact copy of 'ss'. */ SeqSnapshot& operator = (const SeqSnapshot& ss); // overloading virtual function from SeqTreeObj double get_duration() const {return 0.0;} unsigned int event(eventContext& context) const; private: // overwriting virtual functions from SeqClass bool prep(); STD_string magn_fname; mutable SeqDriverInterface triggdriver; }; ////////////////////////////////////////////////////////////////////// /** * * \brief Magnetization reset * * This class is used to reset the current magnetization to its initial equilibrium state * during simulation of the sequence. */ class SeqMagnReset : public SeqObjBase { public: /** * Constructs a trigger labeled 'object_label' */ SeqMagnReset(const STD_string& object_label = "unnamedSeqMagnReset"); /** * Constructs a snapshot trigger which is a copy of 'smr' */ SeqMagnReset(const SeqMagnReset& smr) {SeqMagnReset::operator = (smr);} /** * This assignment operator will make this object become an exact copy of 'smr'. */ SeqMagnReset& operator = (const SeqMagnReset& smr); // overloading virtual function from SeqTreeObj double get_duration() const {return 0.0;} unsigned int event(eventContext& context) const; private: // overwriting virtual functions from SeqClass bool prep(); mutable SeqDriverInterface triggdriver; }; /** @} */ #endif odin-1.8.5/odinseq/seqdriver_standalone.cpp0000644000175000017500000000241011322062345015754 00000000000000#ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #ifdef STANDALONE_PLUGIN #include "../platforms/StandAlone/odinseq_standalone/seqplot_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqstandalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqacq_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqacqepi_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqcounter_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqdec_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqdelay_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqfreq_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqgradchan_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqgradtrapez_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqlist_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqparallel_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqphase_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqpuls_standalone.cpp" #include "../platforms/StandAlone/odinseq_standalone/seqtrigg_standalone.cpp" #endif odin-1.8.5/odinseq/seqfreq.h0000644000175000017500000002606711455553540012702 00000000000000/*************************************************************************** seqfreq.h - description ------------------- begin : Wed Aug 14 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQFREQ_H #define SEQFREQ_H #include #include #include #include /////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Abstract interfac class for all sequence objects that occupy a * transmitter/receiver channel, e.g. pulse objects or acquisition objects */ class SeqFreqChanInterface : public virtual SeqClass { public: /** * Specify the nucleus for this frequency channel */ virtual SeqFreqChanInterface& set_nucleus(const STD_string& nucleus) {if(marshall) marshall->set_nucleus(nucleus); else marshall_error(); return *this;} /** * Sets the freqlist for the object */ virtual SeqFreqChanInterface& set_freqlist(const dvector& freqlist) {if(marshall) marshall->set_freqlist(freqlist); else marshall_error(); return *this;} /** * Sets the phaselist for the object */ virtual SeqFreqChanInterface& set_phaselist(const dvector& phaselist) {if(marshall) marshall->set_phaselist(phaselist); else marshall_error(); return *this;} /** * Returns the frequency list vector (for loop insertion) */ virtual const SeqVector& get_freqlist_vector() const {if(marshall) return marshall->get_freqlist_vector(); else marshall_error(); return get_dummyvec();} /** * Returns the phaselist vector (for loop insertion) */ virtual const SeqVector& get_phaselist_vector() const {if(marshall) return marshall->get_phaselist_vector(); else marshall_error(); return get_dummyvec();} /** * Returns the frequency list vector (for loop insertion) */ operator const SeqVector& () const {return get_freqlist_vector();} /** * Sets the frequency encoding scheme */ virtual SeqFreqChanInterface& set_encoding_scheme(encodingScheme scheme) {if(marshall) marshall->get_mutable_freqlist_vector().set_encoding_scheme(scheme); else marshall_error(); return *this;} /** * Sets the reordering scheme for the frequency list */ virtual SeqFreqChanInterface& set_reorder_scheme(reorderScheme scheme, unsigned int nsegments=1) {if(marshall) marshall->get_mutable_freqlist_vector().set_reorder_scheme(scheme,nsegments); else marshall_error(); return *this;} /** * Returns the reordering vector of the frequency list (for loop insertion) */ virtual const SeqVector& get_reorder_vector() const {if(marshall) return marshall->get_freqlist_vector().get_reorder_vector(); else marshall_error(); return get_dummyvec();} /** * Sets the encoding scheme of the phase list */ virtual SeqFreqChanInterface& set_phaselist_encoding_scheme(encodingScheme scheme) {if(marshall) marshall->get_mutable_phaselist_vector().set_encoding_scheme(scheme); else marshall_error(); return *this;} /** * Sets the reordering scheme for the phase list */ virtual SeqFreqChanInterface& set_phaselist_reorder_scheme(reorderScheme scheme, unsigned int nsegments=1) {if(marshall) marshall->get_mutable_phaselist_vector().set_reorder_scheme(scheme,nsegments); else marshall_error(); return *this;} /** * Returns the reordering vector of the phase list (for loop insertion) */ virtual const SeqVector& get_phaselist_reorder_vector() const {if(marshall) return marshall->get_phaselist_vector().get_reorder_vector(); else marshall_error(); return get_dummyvec();} /** * Sets the frequency list to a single value 'freqoffset' */ SeqFreqChanInterface& set_freqoffset(double freqoffset); /** * Sets the phase list to a single value 'phaseval' */ SeqFreqChanInterface& set_phase(double phaseval); /** * Sets a phase list for RF spoiling of length 'size', multiplicator 'incr' and uniform 'offset'. * Defaults are recommended by the 'Handbook of MRI' */ SeqFreqChanInterface& set_phasespoiling(unsigned int size=80, double incr=117.0, double offset=0.0); protected: SeqFreqChanInterface() {} virtual ~SeqFreqChanInterface() {} void set_marshall(SeqFreqChanInterface* mymarshall) {marshall=mymarshall;} // to be used in constructor code private: friend class SeqAcqEPI; // to allow SeqAcqEPI full access to its driver SeqFreqChanInterface* marshall; // for marshalling member functions to a sub-object virtual SeqVector& get_mutable_freqlist_vector() {if(marshall) return marshall->get_mutable_freqlist_vector(); else marshall_error(); return get_dummyvec();} virtual SeqVector& get_mutable_phaselist_vector() {if(marshall) return marshall->get_mutable_phaselist_vector(); else marshall_error(); return get_dummyvec();} }; /////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The base class for platform specific drivers of transmit/receive channels */ class SeqFreqChanDriver : public SeqDriverBase { public: SeqFreqChanDriver() {} virtual ~SeqFreqChanDriver() {} virtual bool prep_driver(const STD_string& nucleus, const dvector& freqlist) = 0; virtual void prep_iteration(double current_frequency, double current_phase, double freqchan_duration) const = 0; virtual int get_channel() const = 0; virtual STD_string get_iteratorcommand(objCategory cat,int freqlistindex) const = 0; virtual svector get_freqvec_commands(const STD_string& iterator, const STD_string& instr) const = 0; virtual STD_string get_pre_program(programContext& context, objCategory cat, const STD_string& instr_label, double default_frequency, double default_phase) const = 0; virtual SeqFreqChanDriver* clone_driver() const = 0; virtual void pre_event (eventContext& context,double starttime) const = 0; virtual void post_event(eventContext& context,double starttime) const = 0; }; /////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * This is the base class for all sequence objects that occupy a * transmitter/receiver channel */ class SeqFreqChan : public SeqVector, public virtual SeqFreqChanInterface { public: /** * Constructs an empty frequency channel labeled 'object_label' */ SeqFreqChan(const STD_string& object_label="unnamedSeqFreqChan"); /** * Constructs a frequency channel labeled 'object_label' with the following properties: * - nucleus: The nucleus for which the frequency channel should be reserved. * The default is the protons resonance frequency. * - freqlist: This is an array of frequencies at which the transmit/receive signal will be * modulated/demodulated. * - phaselist: This is an array of phases at which the transmit/receive signal will be * modulated/demodulated. */ SeqFreqChan(const STD_string& object_label,const STD_string& nucleus, const dvector& freqlist=0,const dvector& phaselist=0); /** * Constructs a copy of 'sfc' */ SeqFreqChan(const SeqFreqChan& sfc); /** * Destructor */ virtual ~SeqFreqChan() {} /** * Assignment operator that makes this frequency channel become a copy of 'sfc' */ SeqFreqChan& operator = (const SeqFreqChan& sfc); /** * Return the assigned number of this frequency channel */ int get_channel() const {return freqdriver->get_channel();} /** * Returns the freqlist of the object */ dvector get_freqlist() const {return frequency_list;} /** * Returns the current phase (in rad !) */ double get_phase() const {return phaselistvec.get_phase();} /** * Returns the current frequency */ virtual double get_frequency() const; /** * Return the index for the phase list */ unsigned int get_phaselistindex() const {return phaselistvec.get_phaselistindex();} /** * Return the index for the frequency list */ virtual unsigned int get_freqlistindex() const {return 1;} /** * Returns the command to iterate through the frequency list */ STD_string get_iteratorcommand(objCategory cat) const; // overloaded virtual functions of SeqFreqChanInterface SeqFreqChanInterface& set_nucleus(const STD_string& nucleus); SeqFreqChanInterface& set_freqlist (const dvector& freqlist) {frequency_list=freqlist; return *this;} SeqFreqChanInterface& set_phaselist(const dvector& phaselist) {phaselistvec.set_phaselist(phaselist); return *this;} const SeqVector& get_freqlist_vector() const {return *this;} const SeqVector& get_phaselist_vector() const {return phaselistvec;} // overloaded virtual functions of SeqVector unsigned int get_vectorsize() const {return frequency_list.size();} bool prep_iteration() const; bool is_qualvector() const {return false;} svector get_vector_commands(const STD_string& iterator) const {return freqdriver->get_freqvec_commands(iterator,get_driver_instr_label());} // overloaded functions for SeqTreeObj SeqValList get_freqvallist(freqlistAction action) const; protected: STD_string get_pre_program(programContext& context, objCategory cat, const STD_string& instr_label) const; void pre_event (eventContext& context,double starttime) const {freqdriver->pre_event(context,starttime);} void post_event(eventContext& context,double starttime) const {freqdriver->post_event(context,starttime);} /** * Overload this function to return the duration of the object * while it effectively occupies the RF channel */ virtual double get_freqchan_duration() const {return 0.0;} // overwriting virtual functions from SeqClass bool prep(); private: friend class SeqPhaseListVector; // overloaded virtual functions of SeqFreqChanInterface SeqVector& get_mutable_freqlist_vector() {return *this;} SeqVector& get_mutable_phaselist_vector() {return phaselistvec;} double get_default_phase() const {return closest2zero(phaselistvec.get_phaselist());} double get_default_frequency() const {return closest2zero(frequency_list);} static double closest2zero(const dvector& v); // for EPIC virtual STD_string get_driver_instr_label() const {return "";} // the hardware driver mutable SeqDriverInterface freqdriver; // the nucleus of this freq/phase object STD_string nucleusName; // the frequency list to iterate through dvector frequency_list; // the phaselist associated with this freq/phase object SeqPhaseListVector phaselistvec; }; ///////////////////////////////////////////////////////////////////////// #endif odin-1.8.5/odinseq/seqacq.cpp0000644000175000017500000002020111455553540013024 00000000000000#include "seqacq.h" #include "seqdelay.h" #include "seqmeth.h" #include #include void SeqAcq::common_init() { sweep_width=0.0; npts=0; oversampl=1.0; rel_center=0.5; reflect_flag=false; readoutIndex=-1; trajIndex=-1; weightIndex=-1; dimvec=new Handler*[n_recoIndexDims]; for(int i=0; i; default_recoindex[i]=0; } } SeqAcq::~SeqAcq() { for(int i=0; i1.0) { unsigned int adcsize_os=(unsigned int)(oversampl*shape.size()+0.5); fvector newshape(shape); newshape.interpolate(adcsize_os); readoutIndex=recoInfo->append_readout_shape(newshape,dstsize); } else { readoutIndex=recoInfo->append_readout_shape(shape,dstsize); } return *this; } void SeqAcq::set_kspace_traj(const farray& kspaceTraj) { Log odinlog(this,"set_kspace_traj"); if(kspaceTraj.dim()!=3) { ODINLOG(odinlog,errorLog) << "Dimension of kspaceTraj != 3" << STD_endl; return; } if(kspaceTraj.size(2)!=3) { ODINLOG(odinlog,errorLog) << "Third dimension of kspaceTraj != 3" << STD_endl; return; } unsigned int trajsize=kspaceTraj.size(1); if(trajsize!=npts) ODINLOG(odinlog,warningLog) << "size mismatch : " << trajsize << "!=" << npts << STD_endl; trajIndex=recoInfo->append_kspace_traj(kspaceTraj); } void SeqAcq::set_weight_vec(const cvector& weightVec) { Log odinlog(this,"set_weight_vec"); unsigned int vecsize=weightVec.length(); if(vecsize!=npts) ODINLOG(odinlog,warningLog) << "size mismatch : " << vecsize << "!=" << npts << STD_endl; weightIndex=recoInfo->append_adc_weight_vec(weightVec); } double SeqAcq::get_acquisition_center() const { Log odinlog(this,"get_acquisition_center"); double centerpts=rel_center*double(npts); ODINLOG(odinlog,normalDebug) << "centerpts=" << centerpts << STD_endl; double result=get_acquisition_start()+secureDivision(centerpts,sweep_width); ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } SeqAcqInterface& SeqAcq::set_sweepwidth(double sw, float os_factor) { Log odinlog(this,"set_sweepwidth"); double possible_sw_os=acqdriver->adjust_sweepwidth(sw*os_factor); ODINLOG(odinlog,normalDebug) << "possible_sw_os/sw/os_factor=" << possible_sw_os << "/" << sw << "/" << os_factor << STD_endl; sweep_width=secureDivision(possible_sw_os,os_factor); oversampl=STD_max(float(1.0),os_factor); return *this; } SeqAcqInterface& SeqAcq::set_reco_vector(recoDim dim, const SeqVector& vec, const dvector& valvec) { Log odinlog(this,"set_reco_vector"); if(dimset_handled(&vec); ODINLOG(odinlog,normalDebug) << "valvec(" << recoDimLabel[dim] << ")=" << valvec.printbody() << STD_endl; recoInfo->set_DimValues(dim,valvec); } else { ODINLOG(odinlog,warningLog) << "dim=" << dim << " out of range" << STD_endl; } return *this; } SeqAcqInterface& SeqAcq::set_default_reco_index(recoDim dim, unsigned int index) { Log odinlog(this,"set_default_reco_index"); if(dim odinlog(this,"set_npts"); ODINLOG(odinlog,normalDebug) << "nAcqPoints=" << nAcqPoints << STD_endl; npts=nAcqPoints; if(!npts) ODINLOG(odinlog,warningLog) << "Zero sampling points" << STD_endl; return *this; } SeqAcq& SeqAcq::operator = (const SeqAcq& sa) { SeqObjBase::operator = (sa); SeqFreqChan::operator = (sa); sweep_width=sa.sweep_width; npts=sa.npts; oversampl=sa.oversampl; rel_center=sa.rel_center; reflect_flag=sa.reflect_flag; readoutIndex=sa.readoutIndex; trajIndex=sa.trajIndex; weightIndex=sa.weightIndex; for(int i=0; i odinlog(this,"prep"); if(!SeqFreqChan::prep()) return false; kcoord.oversampling=oversampl; kcoord.relcenter=rel_center; kcoord.adcSize=int(float(npts)*kcoord.oversampling+0.5); if(reflect_flag) kcoord.flags=kcoord.flags|recoReflectBit; kcoord.readoutIndex=readoutIndex; kcoord.trajIndex=trajIndex; kcoord.weightIndex=weightIndex; kcoord.dtIndex=recoInfo->append_dwell_time(secureInv(oversampl*sweep_width)); kcoord.channels=acqdriver->get_numof_channels(); // For slicetime functor in odinreco: // store slice order in DimValues of recoInfo according to vector in slice dimension const SeqVector* vec=dimvec[slice]->get_handled(); if(vec) { ivector ivec(vec->get_index_matrix()); dvector ivals(ivec.size()); for(unsigned int i=0; iset_DimValues(slice,ivals); } return acqdriver->prep_driver(kcoord, oversampl*sweep_width, (unsigned int)(oversampl*npts+0.5), get_acquisition_center(), get_channel()); } STD_string SeqAcq::get_program(programContext& context) const { STD_string result=SeqFreqChan::get_pre_program(context,acqObj,acqdriver->get_instr_label()); result+=acqdriver->get_program(context,get_phaselistindex()); return result; } double SeqAcq::get_duration() const { double result=acqdriver->get_predelay(); result+=get_freqchan_duration(); result+=acqdriver->get_postdelay(oversampl*sweep_width); return result; } SeqValList SeqAcq::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()); double newfreq=SeqFreqChan::get_frequency(); if(action==calcAcqList) { result.set_value(newfreq); ODINLOG(odinlog,normalDebug) << "freq=" << newfreq << STD_endl; } return result; } const kSpaceCoord& SeqAcq::get_kcoord() const { Log odinlog(this,"get_kcoord"); // fill reco index with values of the attached vectors for(int i=0; iget_handled(); if(vec) kcoord.index[i]=vec->get_acq_index(); else kcoord.index[i]=default_recoindex[i]; } return kcoord; } RecoValList SeqAcq::get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const { Log odinlog(this,"get_recovallist"); kSpaceCoord idx(get_kcoord()); idx.reps=reptimes; coords.append_coord(idx); RecoValList result(get_label()); result.set_value(idx.number); return result; } unsigned int SeqAcq::event(eventContext& context) const { Log odinlog(this,"event"); double startelapsed=context.elapsed; SeqTreeObj::event(context); if(context.action==seqRun) { SeqFreqChan::pre_event(context,startelapsed); ODINLOG(odinlog,normalDebug) << "startelapsed/get_acquisition_start()=" << startelapsed << "/" << get_acquisition_start() << STD_endl; acqdriver->event(context,startelapsed+get_acquisition_start()); SeqFreqChan::post_event(context,startelapsed+get_acquisition_start()+get_freqchan_duration()); } if(context.event_progmeter) context.event_progmeter->increase_counter(); return 1; } STD_string SeqAcq::get_properties() const { return "SweepWidth="+ftos(sweep_width)+", Samples="+itos(npts)+", OverSampling="+ftos(oversampl); } odin-1.8.5/odinseq/seqacqepi.h0000644000175000017500000003153111625224370013172 00000000000000/*************************************************************************** seqacqepi.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQACQEPI_H #define SEQACQEPI_H #include #include #include #include #include #include #include #include #include /** * @ingroup odinseq_internals * The base class for platform specific EPI drivers */ class SeqEpiDriver : public SeqDriverBase, public SeqObjList, public virtual SeqAcqInterface, public virtual SeqGradInterface { public: SeqEpiDriver() {} virtual ~SeqEpiDriver() {} virtual void init_driver(const STD_string& object_label,double sweepwidth, float kread_min, float kread_max, unsigned readntps, float kphase_min, float kphase_max, unsigned phasentps,int startindex_phase, bool ramp_sampling,rampType rampmode, float ramp_steepness, const STD_string& nucleus, const dvector& phaselist, const dvector& freqlist, unsigned int echo_pairs) = 0; virtual unsigned get_npts_read() const = 0; virtual unsigned int get_numof_gradechoes() const = 0; virtual double get_echoduration() const = 0; virtual double get_ramp_rastertime() const = 0; virtual float get_gradintegral2center_read() const = 0; virtual float get_gradintegral2center_phase() const = 0; virtual fvector get_readout_shape() const = 0; virtual const kSpaceCoord& get_kcoord_template(unsigned int& padded_zeroes) const = 0; virtual SeqEpiDriver* clone_driver() const = 0; unsigned int get_npts() const {return get_npts_read()*get_numof_gradechoes();} protected: SeqEpiDriver(const SeqEpiDriver& seda) : SeqObjList(seda) {SeqEpiDriver::operator = (seda);} SeqEpiDriver& operator = (const SeqEpiDriver& seda) { SeqObjList::operator =(seda); return *this; } }; ///////////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * The default EPI driver */ class SeqEpiDriverDefault : public SeqEpiDriver { // virtual functions of SeqFreqChanInterface are marhshalled to adc public: SeqEpiDriverDefault(); ~SeqEpiDriverDefault() {} SeqEpiDriverDefault(const SeqEpiDriverDefault& sedi); void init_driver(const STD_string& object_label,double sweepwidth, float kread_min, float kread_max, unsigned readntps, float kphase_min, float kphase_max, unsigned phasentps,int startindex_phase, bool ramp_sampling, rampType rampmode, float ramp_steepness, const STD_string& nucleus, const dvector& phaselist, const dvector& freqlist, unsigned int echo_pairs); // overloading virtual functions from SeqDriverBase odinPlatform get_driverplatform() const {return standalone;} // implemented virtual functions from SeqEpiDriver unsigned int get_npts_read() const {return adc.get_npts();} unsigned int get_numof_gradechoes() const; double get_echoduration() const {return posread.get_gradduration();} double get_ramp_rastertime() const {return posread.get_timestep();} float get_gradintegral2center_read() const {return gradint2center_read;} float get_gradintegral2center_phase() const {return gradint2center_phase;} fvector get_readout_shape() const {return readshape;} const kSpaceCoord& get_kcoord_template(unsigned int& padded_zeroes) const {padded_zeroes=0; return adc.get_kcoord();} SeqEpiDriver* clone_driver() const {return new SeqEpiDriverDefault(*this);} // marshalling virtual functions of SeqAcqInterface to adc, except: double get_acquisition_center() const; double get_acquisition_start() const; SeqAcqInterface& set_template_type(templateType type); // implementing virtual functions of SeqGradInterface SeqGradInterface& set_strength(float gradstrength) {return *this;} SeqGradInterface& invert_strength() {kernel.invert_strength(); return *this;} float get_strength() const {return kernel.get_strength();} fvector get_gradintegral() const; double get_gradduration() const {return kernel.get_gradduration();} SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix) {kernel.set_gradrotmatrix(matrix); return *this;} private: void build_seq(); SeqAcq adc; SeqDelay acqdelay_begin; SeqDelay acqdelay_middle; SeqDelay acqdelay_end; SeqGradTrapez posread; SeqGradTrapez negread; SeqGradTrapez phaseblip1st; SeqGradTrapez phaseblip2nd; SeqGradDelay phasezero1st; SeqGradDelay phasezero2nd; SeqGradDelay phasezero_lastblip; SeqGradChanParallel gradkernel; SeqGradChanParallel lastgradkernel; SeqObjList oneadckernel; SeqObjList adckernel; SeqObjList lastadckernel; SeqParallel kernel; SeqParallel lastkernel; SeqObjLoop loop; float gradint2center_read; float gradint2center_phase; int centerindex_phase; fvector readshape; templateType templtype; int echopairs; bool lastecho; }; ///////////////////////////////////////////////////////////////////////////////////// class SeqAcqEPIdephObjs; // forward declaration /** * @addtogroup odinseq * @{ */ /** * \brief Acquisition + echo-planar imaging readout * * This class represents an acquisition window with an EPI gradient. */ class SeqAcqEPI : public SeqObjBase, public virtual SeqAcqInterface, public virtual SeqGradInterface { public: /** * Constructs an acquisition window with an EPI gradient labeled 'object_label' with the * following properties: * - sweepwidth: The sampling frequency * - read_size: The number of sampling points per gradient echo, with ramp_sampling enabled, this is the number of points after regridding * - FOVread: The Field Of View in read direction * - phase_size: The final matrix size in phase direction without partial fourier undersampling * - FOVphase: The Field Of View in phase direction * - shots: Number of shots, a multi-shot (segmented) EPI readout will be created if 'shots' is larger than 1 * - reduction: Reduction factor (parallel imaging) * - os_factor: The oversampling factor, os_factor=1 means no oversampling * - nucleus: The nucleus to measure * - phaselist: Phase list for acquisition * - freqlist: Frequency list for acquisition * - rampmode: This parameter determines the shape of the ramp waveform * - ramp_sampling: The EPI readout performs data acquisition during the ramps if this parameter is set to 'true' * - ramp_steepness: This parameter in the range of ]0,1] determines the relative rising * speed of the gradient strength, i.e. with 1 the gradients are switched * as fast as possible * - fourier_factor: The amount of undersampling (0=no undersampling, 1=half fourier) * - echo_pairs: Number of interleaved acquired pairs of echoes for one phase-encodin step, 0 means only one echo */ SeqAcqEPI(const STD_string& object_label, double sweepwidth, unsigned int read_size, float FOVread, unsigned int phase_size, float FOVphase, unsigned int shots=1, unsigned int reduction=1, float os_factor=1.0, const STD_string& nucleus="", const dvector& phaselist=0, const dvector& freqlist=0, rampType rampmode = linear, bool ramp_sampling=false, float ramp_steepness=1.0, float fourier_factor=0.0, unsigned int echo_pairs=0, bool invert_partial_fourier=false); /** * Constructs an acquisition window with an EPI gradient which is a copy of 'sae' */ SeqAcqEPI(const SeqAcqEPI& sae); /** * Constructs an empty acquisition window with an EPI gradient with the given label. */ SeqAcqEPI(const STD_string& object_label="unnamedSeqAcqEPI"); /** * Destructor */ ~SeqAcqEPI(); /** * Returns the number of points that will be acquired during each read gradient period, * including the ramp points. */ unsigned int get_npts_read() const {return driver->get_npts_read();} /** * Returns the number of gradient echoes, i.e. the number of k-space lines that will * be sampled */ unsigned int get_numof_gradechoes() const {return driver->get_numof_gradechoes();} /** * Returns the readout gradient shape that is used for regridding */ fvector get_readout_shape() const {return driver->get_readout_shape();} /** * This assignment operator will make this object become an exact copy of 'sae'. */ SeqAcqEPI& operator = (const SeqAcqEPI& sae); // forwarding virtual functions of SeqAcqInterface to driver // we cannot use marshalling with a fixed pointer here because // driver may be changed when switching platform double get_acquisition_center() const {return driver->get_acquisition_center();} double get_acquisition_start() const {return driver->get_acquisition_start();} unsigned int get_npts() const {return driver->get_npts();} SeqAcqInterface& set_sweepwidth(double sw, float os_factor); // produce warning double get_sweepwidth() const {return driver->get_sweepwidth();} float get_oversampling() const {return os_factor_cache;} SeqAcqInterface& set_template_type(templateType type); SeqAcqInterface& set_reco_vector(recoDim dim, const SeqVector& vec, const dvector& valvec=dvector()) {driver->set_reco_vector(dim,vec,valvec); return *this;} SeqAcqInterface& set_default_reco_index(recoDim dim, unsigned int index) {driver->set_default_reco_index(dim,index); return *this;} // forwarding virtual functions of SeqFreqChanInterface to driver SeqFreqChanInterface& set_nucleus(const STD_string& nucleus) {driver->set_nucleus(nucleus); return *this;} SeqFreqChanInterface& set_freqlist(const dvector& freqlist) {driver->set_freqlist(freqlist); return *this;} SeqFreqChanInterface& set_phaselist(const dvector& phaselist) {driver->set_phaselist(phaselist); return *this;} const SeqVector& get_freqlist_vector() const {return driver->get_freqlist_vector();} const SeqVector& get_phaselist_vector() const {return driver->get_phaselist_vector();} // forwarding virtual functions of SeqGradInterface to driver SeqGradInterface& set_strength(float gradstrength) {driver->set_strength(gradstrength); return *this;} SeqGradInterface& invert_strength() {driver->invert_strength(); return *this;} float get_strength() const {return driver->get_strength();} fvector get_gradintegral() const {return driver->get_gradintegral();} double get_gradduration() const {return driver->get_gradduration();} SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix) {driver->set_gradrotmatrix(matrix); return *this;} // forwarding virtual functions of SeqTreeObj to driver STD_string get_program(programContext& context) const {return driver->get_program(context);} double get_duration() const {return driver->get_duration();} SeqValList get_freqvallist(freqlistAction action) const {return driver->get_freqvallist(action);} void query(queryContext& context) const {driver->query(context);} RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; bool contains(const SeqTreeObj* sto) const {return driver->contains(sto);} void tree(SeqTreeCallbackAbstract* display) const {driver->tree(display);} unsigned int event(eventContext& context) const {return driver->event(context);} STD_string get_properties() const {return driver->get_properties();} private: SeqVector& get_mutable_freqlist_vector() {return driver->get_mutable_freqlist_vector();} SeqVector& get_mutable_phaselist_vector() {return driver->get_mutable_phaselist_vector();} // overloaded for SeqAcqDeph const SeqVector* get_dephgrad(SeqGradChanParallel& dephobj, bool rephase) const; // overwriting virtual functions from SeqClass bool prep(); void common_init(); void create_deph_and_reph(); unsigned int readsize_os_cache; float os_factor_cache; unsigned int phasesize_cache; unsigned int segments_cache; unsigned int reduction_cache; int echo_pairs_cache; float blipint_cache; templateType templtype_cache; rampType ramptype_cache; mutable SeqDriverInterface driver; SeqAcqEPIdephObjs* dephobjs; }; /** @} */ #endif odin-1.8.5/odinseq/seqobj.cpp0000644000175000017500000000057211322062345013032 00000000000000#include "seqobj.h" SeqObjBase::SeqObjBase(const STD_string& object_label) : SeqTreeObj() { Log odinlog(object_label.c_str(),"SeqObjBase()"); set_label(object_label); } SeqObjBase::SeqObjBase(const SeqObjBase& soa) { SeqObjBase::operator = (soa); } SeqObjBase& SeqObjBase::operator = (const SeqObjBase& soa) { SeqTreeObj::operator = (soa); return *this; } odin-1.8.5/odinseq/seqgrad.h0000644000175000017500000000501611322062345012640 00000000000000/*************************************************************************** seqgrad.h - description ------------------- begin : Wed Aug 8 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRAD_H #define SEQGRAD_H #include class RotMatrix; // forward declaration /** * @addtogroup odinseq_internals * @{ */ /** * This is the abstract base class for all objects that represent * gradient fields */ class SeqGradInterface : public virtual SeqClass { public: /** * Changes the strength of the gradient object */ virtual SeqGradInterface& set_strength(float gradstrength) = 0; /** * Changes the polarity of the gradient, i.e. inverts the sign of the gradient strength */ virtual SeqGradInterface& invert_strength() = 0; /** * Returns the strength of the gradient object */ virtual float get_strength() const = 0; /** * Returns the integral vector of the gradient course */ virtual fvector get_gradintegral() const = 0; /** * Returns the norm of the integral vector of the gradient course */ float get_gradintegral_norm() const; /** * Returns the duration of the gradient object. This function returns * only the effective duration during whichthe gradient is active, * any delays before and after the gradient are omitted. */ virtual double get_gradduration() const = 0; /** * This function can be used to specify a rotation of the gradient object * in the spatial domain, the rotation will be applied to this object only * rather than to the whole sequence. */ virtual SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix) = 0; protected: SeqGradInterface() {} virtual ~SeqGradInterface() {} }; /** @} */ #endif odin-1.8.5/odinseq/odinpulse.h0000644000175000017500000003021511322062345013213 00000000000000/*************************************************************************** odinpulse.h - description ------------------- begin : Tue Jun 4 2002 copyright : (C) 2002 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINPULSE_H #define ODINPULSE_H #include #include #include class SeqSimAbstract; // forward declaration class Sample; // forward declaration #define _BOUNDARY_VALUE_ 0.005 #define _SETREFGAIN_ADIABATIC_INTERVAL_ 0.01 #define _SETREFGAIN_ADIABATIC_INCR_FACTOR_ 1.1 #define _SETREFGAIN_ITERATIONS_ 3 // Parameter values of this optimization parameter must be in range [0,1] #define _TRAJ_OPTIMIZE_PARLABEL_ "FreeParameter" ////////////////////////////////////////////////// /** * @addtogroup odinseq_internals * @{ */ /** * * Wrapper class for trajectory functions. */ class JDXtrajectory : public JDXfunction, public StaticHandler { public: JDXtrajectory(const STD_string& jdxlabel="unnamedJDXtrajectory") : JDXfunction(trajFunc,jdxlabel) {} JDXtrajectory(const JDXtrajectory& jt) : JDXfunction(jt) {} JDXtrajectory& operator = (const JDXtrajectory& jt) {JDXfunction::operator = (jt); return *this;} void init_trajectory(OdinPulse* pls=0) {if(allocated_function) allocated_function->init_trajectory(pls);} const kspace_coord& calculate(float s) const; const traj_info& get_traj_info() const; static void init_static(); static void destroy_static(); }; ////////////////////////////////////////////////// /** * * Wrapper class for pulse shape functions. */ class JDXshape : public JDXfunction, public StaticHandler { public: JDXshape(const STD_string& jdxlabel="unnamedJDXshape") : JDXfunction(shapeFunc,jdxlabel) {} JDXshape(const JDXshape& js) : JDXfunction(js) {} JDXshape& operator = (const JDXshape& js) {JDXfunction::operator = (js); return *this;} void init_shape() {if(allocated_function) allocated_function->init_shape();} STD_complex calculate(const kspace_coord& coord ) const; STD_complex calculate(float s, float Tp) const; const shape_info& get_shape_info() const; farray get_excitation_mask(float fov, unsigned int size) const; static void init_static(); static void destroy_static(); }; ////////////////////////////////////////////////// struct OdinPulseData; // forward declaration /** @} */ ////////////////////////////////////////////////// /** * @addtogroup odinseq * @{ */ /** * \brief Advandced RF pulses * * * This class represents an advanced RF pulse. The RF and gradient * shape will be calculated according to a set of given parameters. */ class OdinPulse : public JcampDxBlock, public virtual SeqClass { public: /** * Constructs an OdinPulse with the given label. If 'interactive' is set to 'true', the RF, gradient shape and * pulse_gain will be recalculted each time a parameter has been changed */ OdinPulse(const STD_string& pulse_label="unnamedOdinPulse",bool interactive=false); /** * Constructs an OdinPulse which is a copy of 'pulse' */ OdinPulse(const OdinPulse& pulse); virtual ~OdinPulse(); /** * This assignment operator will make this OdinPulse become an exact copy of 'pulse'. */ OdinPulse& operator = (const OdinPulse& pulse); /** * * Sets the pulse mode (dimensionality) of the pulse */ OdinPulse& set_dim_mode(funcMode dmode); /** * * Returns the pulse mode (dimensionality) of the pulse */ funcMode get_dim_mode() const; /** * * Returns the number of data points */ unsigned int get_size() const; /** * * specifies number of data points */ OdinPulse& resize(unsigned int newsize); /** * * Sets the duration of the pulse */ OdinPulse& set_Tp(double duration); /** * * Returns the duration of the pulse */ double get_Tp() const; /** * * Specifies whether to consider maximum gradient strength and * slew-rate while calculating the trajectory. */ OdinPulse& set_consider_system_cond(bool flag); /** * * Returns whether to consider maximum gradient strength and * slew-rate while calculating the trajectory. */ bool get_consider_system_cond() const; /** * * Specifies whether to consider Nyquist-theorem while sampling along * the k-space trajectory. */ OdinPulse& set_consider_Nyquist_cond(bool flag); /** * * Returns whether to consider Nyquist-theorem while sampling along * the k-space trajectory. */ bool get_consider_Nyquist_cond() const; /** * * Sets the spatial resolution if the pulse is calculated according * to the small tip angle approximation, otherwise this has no effect. */ OdinPulse& set_spat_resolution(double sigma); /** * * Sets whether minimum spatial resolution is used. */ OdinPulse& use_min_spat_resolution(bool flag); /** * * Returns the spatial resolution */ double get_spat_resolution() const; /** * * Sets the field of excitation, i.e. the spatial area where no aliasing occurs */ OdinPulse& set_field_of_excitation(double fox); /** * * Returns the field of excitation */ double get_field_of_excitation() const; /** * * Sets the spatial offset in the given direction */ OdinPulse& set_spatial_offset(direction direction, double offset); /** * * Returns the spatial offset in the given direction */ double get_spatial_offset(direction direction) const; /** * * Sets the nucleus for the pulse */ OdinPulse& set_nucleus(const STD_string& nucleusname); /** * * Returns the nucleus for the pulse */ STD_string get_nucleus() const; /** * * Sets the type of the pulse, this is necessary for calculating the pulse gain of * adiabatic pulses and optimization of pulses. */ OdinPulse& set_pulse_type(pulseType type); /** * * Returns the type of the pulse */ pulseType get_pulse_type() const; /** * * Specifies the composite pulse to use. * A composite pulse can be specified by a string * of the form a1(x2) a2(x2) ... where a1,a2,... * are the flipangles in degree and x1,x2,... * are the axes, .e.g. X,-X,Y or -Y. */ OdinPulse& set_composite_pulse(const STD_string& cpstring); /** * * Returns a 2dim array with the first index indicating the pulse in the composite pulse * train and the second index selects the flipangle(=0) or pulse phase(=1) of the sub-pulse. */ farray get_composite_pulse_parameters() const; /** * * Returns 'true' if the pulse is a composite pulse */ bool is_composite_pulse() const; /** * * Returns the number of composite pulses */ unsigned int get_numof_composite_pulse() const; /** * * Returns whether the pulse shape is adiabatic */ bool is_adiabatic() const; /** * * Returns the relative center of the pulse, * i.e. the point where the center of k-space is passed. * The value will be in the range in the range [0,1]. */ float get_rel_center() const; /** * * Returns the pulse gain */ double get_pulse_gain() const; /** * * Returns the correction factor for the IDEA flipangle */ float get_flipangle_corr_factor() const; /** * * Sets the flip angle */ OdinPulse& set_flipangle(double angle); /** * * Returns the flip angle */ double get_flipangle() const; /** * * Generates the pulse */ OdinPulse& generate(); /** * * Calculates the pulse gain in comparison to a 90deg 1ms block-shaped pulse */ OdinPulse& set_pulse_gain(); /** * * Update all relations and recalculate pulse */ virtual OdinPulse& update(); /** * * Calculates the power deposition of the pulse */ float get_power_depos() const; /** * * Specifies the pulse shape and its parameters by a string where the first * element is the function name followed by the parameters in braces separated by commas */ OdinPulse& set_shape(const STD_string& shapeval); /** * * Specifies the pulse trajectory and its parameters by a string where the first * element is the function name followed by the parameters in braces separated by commas */ OdinPulse& set_trajectory(const STD_string& shapeval); /** * * Specifies the pulse filter and its parameters by a string where the first * element is the function name followed by the parameters in braces separated by commas */ OdinPulse& set_filter(const STD_string& shapeval); /** * * Sets the value of the pulse shape parameter which has the label 'parameter_label' to 'value' */ OdinPulse& set_shape_parameter(const STD_string& parameter_label, const STD_string& value); /** * * Sets the value of the pulse trajectory parameter which has the label 'parameter_label' to 'value' */ OdinPulse& set_trajectory_parameter(const STD_string& parameter_label, const STD_string& value); /** * * Sets the value of the pulse filter parameter which has the label 'parameter_label' to 'value' */ OdinPulse& set_filter_parameter(const STD_string& parameter_label, const STD_string& value); /** * * Returns the value of the pulse shape parameter which has the given label */ STD_string get_shape_parameter(const STD_string& parameter_label) const; /** * * Returns the value of the pulse trajectory parameter which has the given label */ STD_string get_trajectory_parameter(const STD_string& parameter_label) const; /** * * Returns the value of the pulse filter parameter which has the given label */ STD_string get_filter_parameter(const STD_string& parameter_label) const; /** * * Returns the label of the current pulse shape */ STD_string get_shape() const; /** * * Returns the label of the current pulse trajectory */ STD_string get_trajectory() const; /** * * Returns the label of the current pulse filter */ STD_string get_filter() const; /** * Returns the gradient waveform for the specified channel */ const fvector& get_Grad(direction channel) const; /** * * Returns the scaling factor for the gradient channels */ double get_G0() const; /** * Returns the complex RF waveform */ const cvector& get_B1() const; /** * * Returns the scaling factor for the RF channels */ double get_B10() const; /** * Simulates the effect of the pulse using simulator 'sim' * using virtual sample 'sample'. */ void simulate_pulse(SeqSimAbstract& sim, const Sample& sample) const; /** * * This function writes the RF waveform to file in the native (binary) * format of the current platform */ int write_rf_waveform (const STD_string& filename) const; /** * * This function loads the RF waveform from file in the native (binary) * format of the current platform */ int load_rf_waveform (const STD_string& filename); // overloading virtual functions of JcampDxBlock int load(const STD_string& filename); int write(const STD_string& filename) const; protected: virtual void update_B10andPower(); OdinPulse& recalc_pulse(); double get_Tp_1pulse() const; private: int append_all_members(); static float ensure_unit_range(float x); OdinPulse& make_composite_pulse(); static float gradient_system_max (const fvector& Gvec, float Gmax, float maxslew, float Tp); static float max_kspace_step(const fvector& Gz,float gamma,float Tp,float G0); static float max_kspace_step2(const fvector& Gx, const fvector& Gy, float gamma,float Tp,float G0); OdinPulse& resize_noupdate(unsigned int newsize); // this pointer holds all data of the pulse OdinPulseData* data; }; /** @} */ #endif odin-1.8.5/odinseq/seqfreq.cpp0000644000175000017500000000743011322062345013215 00000000000000#include "seqfreq.h" SeqFreqChanInterface& SeqFreqChanInterface::set_freqoffset(double freqoffset) { dvector flist(1); flist[0]=freqoffset; return set_freqlist(flist); } SeqFreqChanInterface& SeqFreqChanInterface::set_phase(double phaseval) { dvector plist(1); plist[0]=phaseval; return set_phaselist(plist); } SeqFreqChanInterface& SeqFreqChanInterface::set_phasespoiling(unsigned int size, double incr, double offset) { dvector plist(size); plist[0]=incr+offset; // recommended initialisation, handbook of MRI for(unsigned int iphase=1; iphase odinlog(this,"SeqFreqChan(...)"); set_label(object_label); // this is neccessary because SeqClass is a virtual base class phaselistvec.user=this; } SeqFreqChan::SeqFreqChan(const STD_string& object_label,const STD_string& nucleus, const dvector& freqlist,const dvector& phaselist) : SeqVector(object_label), freqdriver(object_label+"_freqdriver"), phaselistvec(object_label+"_phaselistvec") { Log odinlog(this,"SeqFreqChan(...)"); nucleusName=nucleus; frequency_list=freqlist; SeqFreqChan::set_phaselist (phaselist); // Do NOT call virtual function in constructor phaselistvec.user=this; } SeqFreqChan::SeqFreqChan(const SeqFreqChan& sfc) { SeqFreqChan::operator = (sfc); } SeqFreqChan& SeqFreqChan::operator = (const SeqFreqChan& sfc) { Log odinlog(this,"operator = (...)"); SeqVector::operator = (sfc); nucleusName=sfc.nucleusName; freqdriver=sfc.freqdriver; phaselistvec=sfc.phaselistvec; frequency_list=sfc.frequency_list; phaselistvec.user=this; // precaution return *this; } SeqFreqChanInterface& SeqFreqChan::set_nucleus(const STD_string& nucleus) { Log odinlog(this,"set_nucleus"); nucleusName=nucleus; return *this; } STD_string SeqFreqChan::get_iteratorcommand(objCategory cat) const { return freqdriver->get_iteratorcommand(cat,get_freqlistindex()); } SeqValList SeqFreqChan::get_freqvallist(freqlistAction action) const { Log odinlog(this,"get_freqvallist"); SeqValList result(get_label()); result.set_value(get_frequency()); return result; } STD_string SeqFreqChan::get_pre_program(programContext& context, objCategory cat, const STD_string& instr_label) const { return freqdriver->get_pre_program(context,cat,instr_label,get_default_frequency(),get_default_phase()); } double SeqFreqChan::get_frequency() const { if(frequency_list.size()) return frequency_list[get_current_index()]; else return 0.0; } bool SeqFreqChan::prep() { Log odinlog(this,"prep"); if(!SeqClass::prep()) return false; freqdriver->prep_driver(nucleusName,get_freqlist()); prep_iteration(); // to initialize constant frequency offset return true; } bool SeqFreqChan::prep_iteration() const { Log odinlog(this,"prep_iteration"); double phase=get_phase(); double freq=get_frequency(); ODINLOG(odinlog,normalDebug) << "freq/phase=" << freq << "/" << phase << STD_endl; freqdriver->prep_iteration(freq,phase,get_freqchan_duration()); return true; } double SeqFreqChan::closest2zero(const dvector& v) { Log odinlog("SeqFreqChan","closest2zero"); unsigned int n=v.length(); if(!n) return 0.0; double result=v[0]; double min=fabs(result); for(unsigned int i=0; i::staticdone=false; odin-1.8.5/odinseq/seqacqread.cpp0000644000175000017500000001322111455553540013664 00000000000000#include "seqacqread.h" #include "seqlist.h" void SeqAcqRead::common_init() { SeqAcqInterface::set_marshall(&acq); SeqFreqChanInterface::set_marshall(&acq); } SeqAcqRead::SeqAcqRead(const STD_string& object_label,double sweepwidth,unsigned int read_size, float fov, direction gradchannel,float os_factor, float partial_fourier, bool partial_fourier_at_end, const STD_string& nucleus,const dvector& phaselist,const dvector& freqlist, float timestep, rampType rampmode ) : SeqParallel(object_label), corrected_partfour(STD_max(0.0f,STD_min(1.0f,partial_fourier))), // check and correct range acq(object_label+"_acq",(1.0-0.5*corrected_partfour)*read_size+0.5,sweepwidth,os_factor,nucleus,phaselist,freqlist), read(object_label+"_read"), middelay(object_label+"_middelay",0.0), midgrad(object_label+"_midgrad",gradchannel,0.0), tozero(object_label+"_tozero",0.0) { Log odinlog(this,"SeqAcqRead"); common_init(); float gradstrength=secureDivision(2.0*PII*acq.get_sweepwidth(),systemInfo->get_gamma(nucleus)*fov); // Use adjusted sweepwidth double constgradduration=secureDivision(acq.get_npts(),acq.get_sweepwidth()); double rastertime=systemInfo->get_rastertime(gradObj); if(rastertime>0.0) { int nraster=(int)secureDivision(constgradduration,rastertime); if(rastertime*nraster!=constgradduration) nraster++; // always increase length of constant part constgradduration=nraster*rastertime; } read=SeqGradTrapez(object_label+"_read",gradchannel, gradstrength, constgradduration, timestep, rampmode); tozero=SeqDelay(object_label+"_tozero",read.get_offramp_duration()+systemInfo->get_inter_grad_delay()); float rel_center=secureDivision(0.5*(1.0-corrected_partfour),1.0-0.5*corrected_partfour); ODINLOG(odinlog,normalDebug) << "rel_center=" << rel_center << STD_endl; if(partial_fourier_at_end) rel_center=1.0-rel_center; acq.set_rel_center(rel_center); float dephintegral=-(read.get_onramp_integral()+rel_center*read.get_constgrad_integral()); float rephintegral=-(read.get_offramp_integral()+(1.0-rel_center)*read.get_constgrad_integral()); // Initialze once so that consecutive calls to get_dephgrad return always the same objects // readdephgrad=SeqGradTrapez(object_label+"_readdephgrad", // dephintegral, // gradchannel,0.5 *read.get_constgrad_duration(), // timestep,rampmode); readdephgrad=SeqGradTrapez(object_label+"_readdephgrad",dephintegral,gradstrength,gradchannel,timestep,rampmode); // readrephgrad=SeqGradTrapez(object_label+"_readrephgrad", // rephintegral, // gradchannel,0.5 *read.get_constgrad_duration(), // timestep,rampmode); readrephgrad=SeqGradTrapez(object_label+"_readrephgrad",rephintegral,gradstrength,gradchannel,timestep,rampmode); build_seq(); } SeqAcqRead::SeqAcqRead(const STD_string& object_label) : SeqParallel(object_label) { common_init(); } SeqAcqRead::SeqAcqRead(const SeqAcqRead& sar) { common_init(); SeqAcqRead::operator = (sar); } double SeqAcqRead::get_acquisition_center() const { double result=0.0; result+=SeqParallel::get_pulprogduration(); result+=middelay.get_duration(); result+=acq.get_acquisition_center(); return result; } double SeqAcqRead::get_acquisition_start() const { double result=0.0; result+=SeqParallel::get_pulprogduration(); result+=middelay.get_duration(); result+=acq.get_acquisition_start(); return result; } SeqAcqInterface& SeqAcqRead::set_sweepwidth(double sw, float os_factor) { Log odinlog(this,"set_sweepwidth"); ODINLOG(odinlog,warningLog) << "Ignoring request to change sweepwidth after construction" << STD_endl; return *this; } SeqAcqRead& SeqAcqRead::operator = (const SeqAcqRead& sar) { SeqParallel::operator = (sar); acq=sar.acq; read=sar.read; middelay=sar.middelay; midgrad=sar.midgrad; tozero=sar.tozero; readdephgrad=sar.readdephgrad; readrephgrad=sar.readrephgrad; build_seq(); return *this; } void SeqAcqRead::build_seq() { Log odinlog(this,"build_seq"); bool seqset=false; double ppgdur=SeqParallel::get_pulprogduration(); double gradstart=systemInfo->get_grad_shift_delay()+read.get_onramp_duration(); double acqstart=ppgdur+acq.get_acquisition_start(); double shift=gradstart-acqstart; ODINLOG(odinlog,normalDebug) << "ppgdur/gradstart/acqstart/shift=" << ppgdur << "/" << gradstart << "/" << acqstart << "/" << shift << STD_endl; if(shift>=systemInfo->get_min_duration(delayObj)) { ODINLOG(odinlog,normalDebug) << "acq is played out later, because gradient switching is delayed" << STD_endl; middelay.set_duration(shift); SeqParallel::operator = ( read / ( middelay + acq + tozero ) ); seqset=true; } if((-shift)>=systemInfo->get_min_duration(gradObj)) { ODINLOG(odinlog,normalDebug) << "gradients are played out later, because acq is delayed" << STD_endl; midgrad.set_duration(-shift); SeqParallel::operator = ( (midgrad+read) / ( acq + tozero ) ); seqset=true; } if(!seqset) { ODINLOG(odinlog,normalDebug) << "acq and gradients are played out simultaneously" << STD_endl; SeqParallel::operator = ( read / ( acq + tozero ) ); } } const SeqVector* SeqAcqRead::get_dephgrad(SeqGradChanParallel& dephobj, bool rephase) const { SeqGradTrapez* sgt; if(rephase) sgt=new SeqGradTrapez(readrephgrad); // Create deep copy so user can modify SeqAcqDeph safely else sgt=new SeqGradTrapez(readdephgrad); // Create deep copy so user can modify SeqAcqDeph safely sgt->set_temporary(); dephobj+=(*sgt); return 0; } odin-1.8.5/odinseq/seqplatform.cpp0000644000175000017500000000676511322062345014116 00000000000000#include "seqplatform.h" #include "seqdriver.h" #include ///////////////////////////////////////////////////////////////////////////////// void SeqPlatformProxy::set_current_platform(odinPlatform pF) { if(platforms) platforms->set_current(pF); } odinPlatform SeqPlatformProxy::get_current_platform() { if(platforms) return platforms->get_current_platform_id(); else return SeqPlatformInstances::pf_during_platform_construction; } int SeqPlatformProxy::load_systemInfo(const STD_string& filename) { Log odinlog("SeqPlatformProxy","load_systemInfo"); SeqPlatformProxy(); // create platform instances JDXstring pfdummy("","Platform",true,notBroken); // determine the platform first pfdummy.load(filename); if(STD_string(pfdummy)=="") return -1; ODINLOG(odinlog,normalDebug) << "pfdummy=" << STD_string(pfdummy) << STD_endl; odinPlatform pF=odinPlatform(0); svector poss(get_possible_platforms()); for(unsigned int i=0; i odinlog("SeqPlatformProxy","get_possible_platforms"); SeqPlatformProxy(); // create platform instances svector result; result.resize(numof_platforms); for(unsigned int i=0; iinstance[i]) { result+=STD_string(platforms->instance[i]->get_label())+" ACTIONS:\n\n"; result+=SeqCmdLine::format_actions(platforms->instance[i]->get_actions_usage()); } } #endif return result; } int SeqPlatformProxy::get_platform_for_action(const STD_string& action) { #ifndef NO_CMDLINE Log odinlog("SeqPlatformProxy","get_platform_for_action"); SeqPlatformProxy(); // create platform instances for(unsigned int ipf=0; ipfinstance[ipf]) { SeqCmdlineActionList actions=platforms->instance[ipf]->get_actions_usage(); ODINLOG(odinlog,normalDebug) << "platform/actions.size()=" << ipf << "/" << actions.size() << STD_endl; for(STD_list::const_iterator it=actions.begin(); it!=actions.end(); ++it) { STD_string pfact=it->action; ODINLOG(odinlog,normalDebug) << "pfact=" << pfact << STD_endl; if(pfact==action) return ipf; } } } #endif return -1; } SeqPlatform* SeqPlatformProxy::get_platform_ptr() {return platforms->get_current();} void SeqPlatformProxy::init_static() { Log odinlog("SeqClass","init_static"); platforms.init("platforms"); } void SeqPlatformProxy::destroy_static() { Log odinlog("SeqPlatformProxy","destroy_static"); platforms.destroy(); } template class SingletonHandler; SingletonHandler SeqPlatformProxy::platforms; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/odinseq/seqmakefile.cpp0000644000175000017500000002132311363773555014053 00000000000000#include "seqmakefile.h" #include "seqplatform.h" #include "seqdriver.h" #ifndef NO_CMDLINE STD_string SeqMakefile::get_exe_postfix() { STD_string result; #ifdef USING_WIN32 result=".exe"; #endif return result; } STD_string SeqMakefile::get_so_postfix() { STD_string result=".so"; #ifdef MACOS result=".dylib"; #endif #ifdef USING_WIN32 result=".dll"; #endif return result; } STD_string SeqMakefile::get_obj_postfix() { STD_string result=".o"; #ifdef USING_WIN32 #ifndef USING_GCC result=".obj"; #endif #endif return result; } SeqMakefile::SeqMakefile(const STD_string& methlabel, const STD_string& odin_install_prefix, const STD_string& compiler, const STD_string& compiler_flags, const STD_string& linker, const STD_string& extra_includes, const STD_string& extra_libs) : inst_prefix(odin_install_prefix), cxx(compiler), cxxflags(compiler_flags), ld(linker), add_includes(extra_includes), add_libs(extra_libs) { set_label(methlabel); // SeqPlatformCreator(); // create platform instances/drivers } STD_string SeqMakefile::get_Makefile(const STD_string& methroot) const { STD_string result; unsigned int i; result+="all: "+get_methlabel()+get_exe_postfix()+" "; /*if(pf!=paravision)*/ result+=get_methlabel()+get_so_postfix(); result+="\n\n"; // code for shared object svector cmd_chain(get_method_compile_chain(false,true)); if(cmd_chain.size()<3) return result; result+=get_methlabel()+get_obj_postfix()+": "+get_methlabel()+".cpp\n"; result+=" "+cmd_chain[0]+"\n"; // stuff for unique id result+=" "+cmd_chain[1]+"\n"; // compilation of object result+="\n\n"; result+=get_methlabel()+get_so_postfix()+": "+get_methlabel()+get_obj_postfix()+"\n"; for(i=2; i='a' && c<='z') result=true; if(c>='A' && c<='Z') result=true; if(!firstchar && c>='0' && c<='9') result=true; return result; } STD_string valid_c_label(const STD_string& label) { STD_string clabel(label); if(!clabel.length()) { clabel="Label"; } else { if(!valid_c_char(clabel[0],true)) clabel="_"+clabel; for(unsigned int i=0; i unique_id"; ichain++; result[ichain]=compiler+" -c "+get_methlabel()+".cpp "+includes+cxxflags+" -fPIC "+defines; ichain++; if(executable) { STD_string exeflags; #ifdef MACOS exeflags="-Wl,-bind_at_load "; // avoids lots of warnings #endif result[ichain]=linker+" "+exeflags+cxxflags+" -o "+get_methlabel()+" "+get_methlabel()+get_obj_postfix()+" -lc "+libdir+LDFLAGS+" "+odin_libs; ichain++; } if(shared_object) { result[ichain] ="rm -f *"+get_so_postfix()+" so_locations"; ichain++; STD_string soflags; #ifdef MACOS soflags=" -dynamiclib "; // the MacOS way of shared objects #else soflags=" -shared -Wl,-soname,`cat unique_id`"+get_so_postfix()+" "; #endif soflags+=" -o `cat unique_id`"+get_so_postfix()+" "; result[ichain]=linker+soflags+get_methlabel()+get_obj_postfix()+" -lc "+libdir+LDFLAGS+" "+odin_libs; ichain++; } #endif return result; } STD_string SeqMakefile::get_method_clean() const { return "rm -f unique_id *"+get_so_postfix()+" *"+get_obj_postfix()+" "+get_methlabel()+" odin_parx* "+get_methlabel()+"_sequencePars* odinpls* "+get_methlabel()+".ppg "+get_methlabel()+".r odin_versionInfo "+get_methlabel()+"_description "+get_methlabel()+"_messages"; } STD_string SeqMakefile::get_method_install(const STD_string& methdir) const { return "./"+get_methlabel()+" write_code -s "+methdir; } svector SeqMakefile::get_odin4idea_method_compile_chain(const STD_string& in_dir, const STD_string& odindir, const STD_string& vxworks_path, const STD_string& vxworks_cxx, const STD_string& vxworks_flags, const STD_string& win_cxx, const STD_string& hostd_flags, const STD_string& host_flags) const { STD_string defines=get_methdefines(get_methlabel()+"_main",valid_c_label(get_methlabel())); /* This will be done in cxxwrapper #ifdef USING_WIN32 // add path for ppc-compiler binaries JDXfileName ppc_path(vxworks_path); // normalize file name STD_string oldpath=secure_getenv("PATH"); // remove blanks which make ccppc fail while(oldpath.find("; ")!=STD_string::npos) oldpath=replaceStr(oldpath,"; ",";"); while(oldpath.find(" ;")!=STD_string::npos) oldpath=replaceStr(oldpath," ;",";"); if(oldpath.find(ppc_path) == STD_string::npos) { STD_string path="PATH="+oldpath+";"+ppc_path; _putenv(path.c_str()); } #endif */ JDXfileName methdir(in_dir); // normalize filename STD_string method_bname=methdir+SEPARATOR_STR+get_methlabel(); STD_string method_bname_slash=replaceStr(method_bname,"\\","/"); // use forward slashes for vxworks STD_string includes; svector result; result.resize(3); includes=STD_string(" -I")+odindir+SEPARATOR_STR+"vxworks"+SEPARATOR_STR+"include"; result[0]=JDXfileName(vxworks_cxx)+" "+method_bname_slash+".cpp -c "+includes+" "+defines+" "+vxworks_flags+" -o "+method_bname_slash+".o"; // srccode must be 1st for ccpentium includes=STD_string(" -I")+odindir+SEPARATOR_STR+"host"+SEPARATOR_STR+"include"; result[1]=JDXfileName(win_cxx)+" "+method_bname+".cpp -c "+includes+" "+defines+" "+host_flags+" -Fo"+method_bname+".obj"; includes=STD_string(" -I")+odindir+SEPARATOR_STR+"hostd"+SEPARATOR_STR+"include"; result[2]=JDXfileName(win_cxx)+" "+method_bname+".cpp -c "+includes+" "+defines+" "+hostd_flags+" -Fo"+method_bname+"d.obj"; return result; } #endif odin-1.8.5/odinseq/seqvec.cpp0000644000175000017500000002645411322062345013044 00000000000000#include "seqvec.h" #include "seqloop.h" #include #include void SeqVector::common_int() { reordvec=0; nr_cache_up2date=false; } SeqVector::SeqVector(const STD_string& object_label) { common_int(); set_label(object_label); } SeqVector::SeqVector(const STD_string& object_label, unsigned int nindices, int slope, int offset ) { common_int(); set_label(object_label); ivector ivec(nindices); for(unsigned int i=0; i odinlog(this,"~SeqVector()"); if(reordvec) delete reordvec; } SeqVector& SeqVector::operator = (const SeqVector& sv) { SeqClass::operator = (sv); indexvec=sv.indexvec; if(reordvec) delete reordvec; reordvec=0; if(sv.reordvec) reordvec=new SeqReorderVector(this,sv.reordvec); return *this; } unsigned int SeqVector::get_numof_iterations() const { Log odinlog(this,"get_numof_iterations"); unsigned int result=get_vectorsize(); if(reordvec) { result=reordvec->get_reordered_size(result); } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } int SeqVector::get_current_index() const { Log odinlog(this,"get_current_index"); int result=0; const SeqVector* sim=simhandler.get_handled(); if(sim) { result=sim->get_current_index(); ODINLOG(odinlog,normalDebug) << "result(sim)=" << result << STD_endl; } else { if(loopcounter_is_active()) { result=get_loopcounter(); ODINLOG(odinlog,normalDebug) << "result(loopcounter)=" << result << STD_endl; } } if(reordvec) { result=reordvec->get_reordered_index(result); ODINLOG(odinlog,normalDebug) << "result(reordvec)=" << result << STD_endl; } return result; } int SeqVector::get_acq_index() const { Log odinlog(this,"get_acq_index"); int result=get_current_index(); if(result>=0 && resultnr_cache_up2date==false) nr_cache_up2date=false; if(nr_cache_up2date) return nr_cache; nr_cache=noRelation; if(vechandler.get_handled()) { ODINLOG(odinlog,normalDebug) << "has vechandler" << STD_endl; if(reordvec && reordvec->vechandler.get_handled()) { ODINLOG(odinlog,normalDebug) << "has reorder vector" << STD_endl; if(vechandler.get_handled()->contains(reordvec->vechandler.get_handled())) nr_cache=reorderInner; if(reordvec->vechandler.get_handled()->contains(vechandler.get_handled())) nr_cache=vecInner; } else ODINLOG(odinlog,normalDebug) << "has NO reorder vector" << STD_endl; } else ODINLOG(odinlog,normalDebug) << "has NO vechandler" << STD_endl; programContext gpgcontext; gpgcontext.mode=brukerGpg; if(reordvec && nr_cache!=noRelation) { if(reordvec->vechandler.get_handled()->unroll_program(gpgcontext) || vechandler.get_handled()->unroll_program(gpgcontext)) nr_cache=unrolledLoop; } if(nr_cache==noRelation) ODINLOG(odinlog,normalDebug) << "noRelation" << STD_endl; if(nr_cache==reorderInner) ODINLOG(odinlog,normalDebug) << "reorderInner" << STD_endl; if(nr_cache==vecInner) ODINLOG(odinlog,normalDebug) << "vecInner" << STD_endl; if(nr_cache==unrolledLoop) ODINLOG(odinlog,normalDebug) << "unrolledLoop" << STD_endl; nr_cache_up2date=true; if(reordvec) reordvec->nr_cache_up2date=true; return nr_cache; } iarray SeqVector::get_index_matrix() const { unsigned int ncols=get_numof_iterations(); unsigned int nrows=1; if(reordvec) nrows=reordvec->get_numof_iterations(); iarray result(nrows,ncols); unsigned int icol,irow; if(reordvec) { for(irow=0; irowget_reordered_index(icol,irow); } } } else { for(icol=0; icolget_current_index(); return result; } STD_string SeqVector::get_reord_iterator(const STD_string& iterator) const { STD_string result(iterator); if(reordvec) result=reordvec->get_reordered_iterator(iterator); return result; } const SeqVector& SeqVector::set_vechandler(const SeqCounter *sc) const { Log odinlog(this,"set_vechandler"); ODINLOG(odinlog,normalDebug) << "counter=" << sc->get_label() << STD_endl; vechandler.set_handled(sc); return *this; } bool SeqVector::loopcounter_is_active() const { Log odinlog(this,"loopcounter_is_active"); bool result=false; const SeqCounter* sc=vechandler.get_handled(); ODINLOG(odinlog,normalDebug) << "sc=" << (void*)sc << STD_endl; if(sc) { result=sc->counter_is_active(); ODINLOG(odinlog,normalDebug) << "loop " << vechandler.get_handled()->get_label() << " says " << result << STD_endl; } return result; } int SeqVector::get_loopcounter() const { Log odinlog(this,"get_loopcounter"); unsigned int result=0; const SeqCounter* sc=vechandler.get_handled(); if(sc) { result=sc->get_counter(); ODINLOG(odinlog,normalDebug) << "result(" << sc->get_label() << ")=" << result << STD_endl; } if(result>=get_numof_iterations()) result=0; return result; } bool SeqVector::is_qualvector() const { if(indexvec.size()) return false; // assume simple index vector return true; } bool SeqVector::is_acq_vector() const { if(simhandler.get_handled()) return simhandler.get_handled()->is_acq_vector(); return Handled::is_handled(); } /////////////////////////////////////////////////////////////////////////////// // template instantiations, collect them here to include tjutils/tjhandler_code.h only once template class Handler; template class Handled; /////////////////////////////////////////////////////////////////////////////// SeqReorderVector::SeqReorderVector(const SeqVector* user, const SeqReorderVector* copy_templ) : reord_scheme(noReorder), n_reord_segments(1), encoding_scheme(linearEncoding), reorder_user(user) { set_label(STD_string(user->get_label())+"_reordvec"); if(copy_templ) { reord_scheme=copy_templ->reord_scheme; n_reord_segments=copy_templ->n_reord_segments; encoding_scheme=copy_templ->encoding_scheme; } } unsigned int SeqReorderVector::get_reordered_size(unsigned int vecsize) const { Log odinlog(this,"get_reordered_size"); unsigned int result=vecsize; if( reord_scheme==blockedSegmented || reord_scheme==interleavedSegmented) { result=vecsize/n_reord_segments; ODINLOG(odinlog,normalDebug) << "vecsize/n_reord_segments/result=" << vecsize << "/" << n_reord_segments << "/" << result << STD_endl; } return result; } svector SeqReorderVector::get_vector_commands(const STD_string& iterator) const { reord_iterator_cache=iterator; // cache for later use by get_reordered_iterator() return reorder_user->get_reord_vector_commands(iterator); } int SeqReorderVector::get_reordered_index(int counter, int reord_iteration) const { Log odinlog(this,"get_reordered_index"); int nvals_per_segment =reorder_user->get_numof_iterations(); ODINLOG(odinlog,normalDebug) << "counter/reord_iteration/nvals_per_segment/n_reord_segments=" << counter << "/" << reord_iteration << "/" << nvals_per_segment << "/" << n_reord_segments << STD_endl; int peindex=counter; if(reord_scheme==rotateReorder) { ODINLOG(odinlog,normalDebug) << "using rotateReorder" << STD_endl; peindex=counter+reord_iteration; if(peindex>=nvals_per_segment) peindex-=nvals_per_segment; } if( reord_scheme==blockedSegmented ) { ODINLOG(odinlog,normalDebug) << "using blockedSegmented" << STD_endl; peindex=reord_iteration*nvals_per_segment+counter; } if( reord_scheme==interleavedSegmented ) { ODINLOG(odinlog,normalDebug) << "using interleavedSegmented" << STD_endl; peindex=counter*n_reord_segments+reord_iteration; } // phase-encoding scheme int result=peindex; //default if(encoding_scheme==reverseEncoding) { result=reorder_user->get_vectorsize()-1-peindex; } if(encoding_scheme==centerOutEncoding || encoding_scheme==centerInEncoding) { int sign=int(pow(-1,peindex)); int n=reorder_user->get_vectorsize(); int cent=n/2; int index=peindex; if(encoding_scheme==centerInEncoding) index=n-1-peindex; result=cent+sign*int((index+1)/2); ODINLOG(odinlog,normalDebug) << "sign/cent=" << sign << "/" << cent<< STD_endl; } if(encoding_scheme==maxDistEncoding) { result = peindex%2 * (reorder_user->get_vectorsize()+1)/2 + peindex/2; } ODINLOG(odinlog,normalDebug) << "peindex/result" << peindex << "/" << result << STD_endl; return result; } STD_string SeqReorderVector::get_reordered_iterator(const STD_string& iterator) const { STD_string result(iterator); STD_string nvals_per_segment =itos(reorder_user->get_numof_iterations()); if(reord_scheme==rotateReorder) { result= "("+iterator+"+"+reord_iterator_cache+")%"+nvals_per_segment; } if( reord_scheme==blockedSegmented ) { result= reord_iterator_cache+"*"+nvals_per_segment+"+"+iterator; } if( reord_scheme==interleavedSegmented ) { result= iterator+"*"+itos(n_reord_segments)+"+"+reord_iterator_cache; } // phase-encoding scheme STD_string vectorsize =itos(reorder_user->get_vectorsize()); if(encoding_scheme==reverseEncoding) { result = vectorsize +"-1-(" + result + ")"; } if(encoding_scheme==centerOutEncoding || encoding_scheme==centerInEncoding) { STD_string sign="(int)(pow(-1,"+result+"))"; STD_string cent=vectorsize+"/2"; STD_string indexstr=result; if(encoding_scheme==centerInEncoding) indexstr="("+vectorsize+"-1-"+result+")"; result=cent+"+"+sign+"*(int)(("+indexstr+"+1)/2)"; } if(encoding_scheme==maxDistEncoding) { result = result + "%2 * (" +vectorsize + "+1)/2 + "+result+"/2"; } return result; } unsigned int SeqReorderVector::get_vectorsize() const { unsigned int result=1; if(reord_scheme==rotateReorder) result=reorder_user->get_vectorsize(); if( blockedSegmented <= reord_scheme && reord_scheme <= interleavedSegmented ) { result=n_reord_segments; } return result; } // Template instantiations template class ListItem; template class List; template class Handler; template class Handled; odin-1.8.5/odinseq/seqlist.h0000644000175000017500000001324411322062345012700 00000000000000/*************************************************************************** seqlist.h - description ------------------- begin : Wed Aug 14 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQLIST_H #define SEQLIST_H #include #include #include #include #define _MIN_PPG_CMDSIZE_ 25 #define _MIN_GP_CMDSIZE_ 50 /** * @addtogroup odinseq_internals * @{ */ /** * The base class for platform specific drivers of lists of sequence objects */ class SeqListDriver : public SeqDriverBase { public: SeqListDriver() {} virtual ~SeqListDriver() {} virtual STD_string pre_program (programContext& context, const SeqRotMatrixVector* rotmats) const = 0; virtual STD_string post_program(programContext& context, const SeqRotMatrixVector* rotmats) const = 0; virtual STD_string get_itemprogram(const SeqTreeObj* item, programContext& context) const = 0; virtual void pre_event (eventContext& context, const RotMatrix* rotmatrix) const = 0; virtual void post_event(eventContext& context, const RotMatrix* rotmatrix) const = 0; virtual void pre_itemevent (const SeqTreeObj* item, eventContext& context) const = 0; virtual void post_itemevent(const SeqTreeObj* item, eventContext& context) const = 0; virtual bool prep_driver() = 0; virtual SeqListDriver* clone_driver() const = 0; }; /** @} */ ////////////////////////////////////////////////////////////////////// class SeqObjLoop; // forward declaration class SeqDecoupling; // forward declaration class SeqGradObjInterface; // forward declaration class SeqGradChan; // forward declaration class SeqGradChanList; // forward declaration /** * @ingroup odinseq * * \brief Container for sequence objects * * This is a container class for other sequence objects. */ class SeqObjList : public SeqObjBase, public List { public: /** * Construct an empty sequence container with the given label */ SeqObjList(const STD_string& object_label="unnamedSeqObjList"); /** * Constructs a copy of 'so' */ SeqObjList(const SeqObjList& so); ~SeqObjList(); /** * Assignment operator that makes this sequence container become a copy of 'so' */ SeqObjList& operator = (const SeqObjList& so); /** * Special assignment for loops */ SeqObjList& operator = (const SeqObjLoop& sl); /** * Special assignment for decoupling */ SeqObjList& operator = (const SeqDecoupling& sd); /** * Special treatment for single non-container sequence objects */ SeqObjList& operator = (const SeqObjBase& soa); /** * Special treatment for assignment from gradient objects */ SeqObjList& operator = (SeqGradObjInterface& sgoa) {clear(); return (*this)+=sgoa;} /** * Special treatment for assignment from gradient objects */ SeqObjList& operator = (SeqGradChan& sgc) {clear(); return (*this)+=sgc;} /** * Special treatment for assignment from gradient objects */ SeqObjList& operator = (SeqGradChanList& sgcl) {clear(); return (*this)+=sgcl;} /** * Special treatment for appending sequence objects */ SeqObjList& operator += (const SeqObjBase& soa); /** * Special treatment for appending gradient objects */ SeqObjList& operator += (SeqGradObjInterface& sgoa); /** * Special treatment for appending gradient objects */ SeqObjList& operator += (SeqGradChan& sgc); /** * Special treatment for appending gradient objects */ SeqObjList& operator += (SeqGradChanList& sgcl); /** * Specifies an extra vector of rotatition matrices to be used with this container. * The part held by this container will be executed with the current rotation matrix. * The sequence vector 'matrixVec' can then be attached to a loop to iterate over the different matrices. */ SeqObjList& set_gradrotmatrixvector(const SeqRotMatrixVector& matrixVec) {gradrotmatrixvec.set_handled(&matrixVec); return *this;} // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; unsigned int event(eventContext& context) const; double get_duration() const; STD_string get_properties() const; void query(queryContext& context) const; RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; SeqValList get_freqvallist(freqlistAction action) const; SeqValList get_delayvallist() const; double get_rf_energy() const; protected: // overloading virtual function from SeqClass void clear_container() {clear();} bool prep(); private: friend class SeqGradChan; friend class SeqOperator; // overloading virtual function from SeqObjBase bool contains_list() const {return true;} mutable SeqDriverInterface listdriver; Handler gradrotmatrixvec; static Handler current_gradrotmatrixvec; }; #endif odin-1.8.5/odinseq/odinpulse_shapes.cpp0000644000175000017500000003351311625224370015121 00000000000000#include "odinpulse.h" #include "seqplatform.h" #ifndef __DBL_EPSILON__ #define __DBL_EPSILON__ 1.e-38 #endif //////////////////////////////////////////////////// // adiabatic shapes: /** * * Sech Pulse */ class Sech : public JDXfunctionPlugIn { JDXdouble trunc; JDXdouble bw; public: Sech() : JDXfunctionPlugIn ( "Sech" ) { set_description ( "Adiabatic hyperbolic secant pulse." ); trunc=0.01; trunc.set_minmaxval ( 0.001,0.5 ).set_description ( "Relative amplitude at the edges of the pulse" ); append_member ( trunc,"TruncationLevel" ); bw=10.0; bw.set_minmaxval ( 0.001,100.0 ).set_description ( "Inversion width" ).set_unit ( ODIN_FREQ_UNIT ); append_member ( bw,"BandWidth" ); } STD_complex calculate_shape ( float s, float Tp ) const { double beta=2.0*acosh ( secureInv ( trunc ) ); double my=secureDivision ( PII*Tp*bw,beta ); double x=beta* ( s-0.5 ); double sech= ( 1/cosh ( x ) ); double amplitude=100*sech; double phase=my*log ( sech ); return STD_complex ( amplitude*cos ( phase ),amplitude*sin ( phase ) ); } const shape_info& get_shape_properties() const { shape_info_retval.adiabatic=true; return shape_info_retval; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Sech;} }; //////////////////////////////////////////////////// /** * * Wurst Pulse */ class Wurst : public JDXfunctionPlugIn { JDXdouble ncycles; JDXdouble truncpar; public: Wurst() : JDXfunctionPlugIn ( "Wurst" ) { set_description ( "Adiabatic WURST pulse (Kupce and Freeman 1995, JMR A 117:246)" ); ncycles=10.0; ncycles.set_minmaxval ( 1.0,50.0 ).set_description ( "Number of phase cycles" ); append_member ( ncycles,"NumOfCycles" ); truncpar=10.0; truncpar.set_minmaxval ( 1.0,50.0 ).set_description ( "Truncation Parameter" ); append_member ( truncpar,"Truncation" ); } STD_complex calculate_shape ( float s, float Tp ) const { float beta_t,phi,amplitude,ss; ss=s-0.5; phi=4.0* ( 2.0*PII*ncycles ) *ss*ss; beta_t=ss*PII; amplitude=1.0-pow ( double ( fabs ( sin ( beta_t ) ) ),double ( truncpar ) ); return STD_complex ( amplitude*cos ( phi ),amplitude*sin ( phi ) ); } const shape_info& get_shape_properties() const { shape_info_retval.adiabatic=true; return shape_info_retval; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Wurst;} }; //////////////////////////////////////////////////// /** * * Wurst Pulse */ class Fermi : public JDXfunctionPlugIn { JDXdouble width; JDXdouble slope; public: Fermi() : JDXfunctionPlugIn ( "Fermi" ) { set_description ( "Fermi pulse for MT and B1 mapping with Bloch-Siegert shift" ); width=0.75; width.set_minmaxval ( 0, 1 ).set_description ( "Distance of Fermi Function turning points (not FWHM)" ); append_member ( width,"width" ); slope=80; slope.set_minmaxval ( 0,150 ).set_description ( "Exponential factor in Fermi function: influences the slope of the ramps" ); append_member ( slope,"slope" ); } STD_complex calculate_shape ( float s, float Tp ) const { STD_complex result ( exp ( -width / 2 * slope ) / ( exp ( ( fabs ( s - 0.5 ) - width / 2 ) * slope ) + 1 ), 0 ); if ( s < __DBL_EPSILON__ || s > 1 - __DBL_EPSILON__ ) result = STD_complex ( 0,0 ); return result; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Fermi;} }; //////////////////////////////////////////////////// /** * * Const Pulse */ class ConstPulse : public JDXfunctionPlugIn { public: ConstPulse() : JDXfunctionPlugIn ( "Const" ) { set_description ( "Constant-amplitude pulse" ); } STD_complex calculate_shape ( float,float ) const { return STD_complex ( 1.0 ); } STD_complex calculate_shape ( const kspace_coord& ) const { return STD_complex ( 1.0 ); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new ConstPulse;} }; //////////////////////////////////////////////////// /** * * Sinc Pulse */ class Sinc : public JDXfunctionPlugIn { public: JDXdouble thick; Sinc() : JDXfunctionPlugIn ( "Sinc" ) { set_description ( "Pulse with a box-car shaped excitation profile" ); thick=5.0; thick.set_minmaxval ( 0.01,200.0 ).set_description ( "Slice thickness" ).set_unit ( ODIN_SPAT_UNIT ); append_member ( thick,"SliceThickness" ); } STD_complex calculate_shape ( const kspace_coord& tdep ) const { return STD_complex ( sinc ( 0.5*tdep.kz*thick ) ); } const shape_info& get_shape_properties() const { shape_info_retval.spatial_extent=thick; return shape_info_retval; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Sinc;} }; //////////////////////////////////////////////////// /** * * Import ASCII */ class ImportASCII : public JDXfunctionPlugIn { public: JDXfileName fname; JDXcomplexArr shape; ImportASCII() : JDXfunctionPlugIn ( "ImportASCII" ) { set_description ( "Import pulse from ASCII file which must have the format 'amplitude phase amplitude phase ...'. The phase is taken as rad." ); fname.set_description ( "ASCII file name" ); append_member ( fname,"FileName" ); } void init_shape() { if ( fname=="" ) return; STD_string sF; ::load ( sF,fname ); svector posstring=tokens ( sF ); unsigned int numpoints=posstring.size() /2; shape.redim ( numpoints ); for ( unsigned int i=0; iregister_function ( shapeFunc,zeroDeeMode ).register_function ( shapeFunc,oneDeeMode ).register_function ( shapeFunc,twoDeeMode ); ( new ImportASCII )->register_function ( shapeFunc,zeroDeeMode ).register_function ( shapeFunc,oneDeeMode ).register_function ( shapeFunc,twoDeeMode ); ( new ImportBruker )->register_function ( shapeFunc,zeroDeeMode ).register_function ( shapeFunc,oneDeeMode ).register_function ( shapeFunc,twoDeeMode ); ( new Sinc )->register_function ( shapeFunc,oneDeeMode ); ( new Sech )->register_function ( shapeFunc,zeroDeeMode ); ( new Wurst )->register_function ( shapeFunc,zeroDeeMode ); ( new Fermi )->register_function ( shapeFunc,zeroDeeMode ); ( new Rect )->register_function ( shapeFunc,twoDeeMode ); ( new Disk )->register_function ( shapeFunc,twoDeeMode ); ( new NPeaks )->register_function ( shapeFunc,twoDeeMode ); } void JDXshape::destroy_static() { // pulgins will be deleted by JDXfunction } EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/odinseq/seqdelay.cpp0000644000175000017500000000165611322062345013362 00000000000000#include "seqdelay.h" SeqDelay::SeqDelay(const STD_string& object_label,float delayduration, const STD_string& command,const STD_string& durationVariable) : SeqObjBase(object_label),SeqDur(object_label,delayduration), delaydriver(object_label) { cmd=command; durcmd=durationVariable; } SeqDelay::SeqDelay(const SeqDelay& sd) : delaydriver(sd.get_label()) { SeqDelay::operator = (sd); } SeqDelay& SeqDelay::set_command(const STD_string& command) { cmd=command; return *this; } SeqDelay& SeqDelay::operator = (const SeqDelay& sd) { SeqObjBase::operator = (sd); SeqDur::operator = (sd); delaydriver=sd.delaydriver; cmd=sd.cmd; durcmd=sd.durcmd; return *this; } SeqDelay& SeqDelay::operator = (float dur) { set_duration(dur); return *this; } STD_string SeqDelay::get_program(programContext& context) const { return delaydriver->get_program(context,get_duration(),cmd,durcmd); } odin-1.8.5/odinseq/seqgradobj.h0000644000175000017500000000403311322062345013331 00000000000000/*************************************************************************** seqgradobj.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADOBJ_H #define SEQGRADOBJ_H #include #include #include #include class SeqObjList; // forward declaration class SeqRotMatrixVector; // forward declaration /** * @addtogroup odinseq_internals * @{ */ /** * This is the abstract base class for all gradient objects that can be part of a sequence */ class SeqGradObjInterface : public virtual SeqGradInterface, public virtual SeqTreeObj, public Handled, public Handled { public: // overloading virtual functions from SeqTreeObj double get_duration() const; double get_pulprogduration() const; // Do we still need this? virtual bool need_gp_terminator() const {return false;} protected: SeqGradObjInterface(const STD_string& object_label="unnamedSeqGradObjInterface"); SeqGradObjInterface(const SeqGradObjInterface& sgoa); SeqGradObjInterface& operator = (const SeqGradObjInterface& sgoa); }; /** @} */ #endif odin-1.8.5/odinseq/seqloop.h0000644000175000017500000001121511455553540012703 00000000000000/*************************************************************************** seqloop.h - description ------------------- begin : Mon Aug 13 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQLOOP_H #define SEQLOOP_H #include #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Sequence Loop * * This class represents a loop which is used to enclose other sequence objects * so that they are repeatedely played out in the sequence */ class SeqObjLoop : public SeqCounter, public SeqObjList, public Embed { public: /** * Construct an empty loop object with the given label */ SeqObjLoop(const STD_string& object_label = "unnamedSeqObjLoop"); /** * Constructs a copy of 'sl' */ SeqObjLoop(const SeqObjLoop& sl); ~SeqObjLoop() {} /** * Assignment operator that makes this loop object become a copy of 'sl' */ SeqObjLoop& operator = (const SeqObjLoop& sl); /** * Duration the loop itself takes before iteration is started */ double get_preduration () const; /** * Duration the loop itself takes after its kernel is iterated */ double get_postduration() const; /** * Sets the inner part of loop, only useful for explicit setup of loops, i.e. in SeqEpiDriverDefault */ SeqObjLoop& set_body(const SeqObjBase& so); /** * Specify the number of times the body of the loop will be repeated, only useful for explicit setup of loops, i.e. in SeqEpiDriverDefault */ SeqObjLoop& set_times(unsigned int t); /** * Generates and returns a new loop object that is a copy of this. The new loop will * loop over 'embeddedBody'. */ SeqObjLoop& operator () (const SeqObjBase& embeddedBody); /** * This operator will append 'seqvector' to the list of vectors the loop will iterate through */ SeqObjLoop& operator [] (const SeqVector& seqvector); /** * This operator specifies the number of times the body of the loop will be repeated */ SeqObjLoop& operator [] (unsigned int t); // overwriting virtual functions from SeqCounter int get_times() const; // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const; double get_duration() const; unsigned int event(eventContext& context) const; SeqValList get_freqvallist(freqlistAction action) const; SeqValList get_delayvallist() const; double get_rf_energy() const; void query(queryContext& context) const; RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; STD_string get_properties() const; private: // overwriting virtual functions from SeqClass bool prep(); void clear_container(); // overwriting virtual functions from SeqCounter void add_vector(const SeqVector& seqvector); bool unroll_program(programContext& context) const; /** * Returns 'true' if the loop only repeats its contents and does not change its objects while looping. * If 'only_qualvectors' is set to true, all vectors that do not influence the timing or RF power * deposition will be considered as repetitions. */ bool is_repetition_loop(bool only_qualvectors=false) const; /** * Returns 'true' if the loop only repeats the acquisition ordering. */ bool is_acq_repetition_loop() const; /** * Returns 'true' if the loop repeats its kernel by altering values of the vectors therein * (gradient strength, frequency, phase) but without changing the order of the sequence objects. */ bool is_obj_repetition_loop() const; /** * Returns 'true' if the subtree of the loop contains an iterator which changes reco indices. */ bool contains_acq_iter() const; float get_single_duration() const; unsigned int times; unsigned int get_numof_acq() const; mutable unsigned int numof_acq_cache; mutable bool is_toplevel_reploop; }; /** @} */ #endif odin-1.8.5/odinseq/seqmeth.h0000644000175000017500000003114211322062345012657 00000000000000/*************************************************************************** seqmeth.h - description ------------------- begin : Thu Aug 9 2001 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQMETH_H #define SEQMETH_H #include #include #include #include #include ////////////////////////////////////////////////////////////////////// // forward declarations class SeqMethod; class SeqPulsar; ////////////////////////////////////////////////////////////////////// /** * @ingroup odinseq_internals * Proxy class to deal with different ODIN methods at once */ class SeqMethodProxy : public StaticHandler { public: SeqMethodProxy() { Log odinlog("SeqMethodProxy","SeqMethodProxy()"); } static void set_current_method(unsigned int index); static SeqMethod* get_current_method(); static unsigned int get_numof_methods(); static unsigned int delete_methods(); static const char* get_method_label(); static const char* get_status_string(); // pointer-like syntax to access current method SeqMethod* operator -> () {return get_current_method();} SeqMethod& operator [] (unsigned int index); static bool load_method_so(const STD_string& so_filename); // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); protected: // called by derivedmethod classes to register themselves static void register_method(SeqMethod* meth); private: // struct to store references to all registered methods struct MethodList : public STD_list, public Labeled {}; static SingletonHandler registered_methods; // struct to store references to the current method struct MethodPtr : public Labeled { SeqMethod* ptr; }; static SingletonHandler current_method; static SeqMethod* empty_method; }; ////////////////////////////////////////////////////////////////////// /* State diagram for SeqMethod, i.e. for all NMR sequences: Possible transitions between states are indicated by the corresponding member functions that perform the transition. empty <--------\ | | | clear() | init() | | | V | | initialised ---| | | | | build() | | | V | | built ---------| | | | | prepare() | | | V | | prepared ------' */ /** * @ingroup odinseq * * \brief Base class for methods (sequences) * * The base class for all NMR sequences. * To create a new sequence, write a new class which is derived * from SeqMethod and overload the following virtual functions * with the specified functionality: * - void method_pars_init(): Initialize sequence parameters (set default values, * append to the list of registered parameters of the method) * - void method_seq_init(): Create the internal layout of the sequence, i.e. * the sequence tree * - void method_rels(): Calculate timings of the sequence * - void method_pars_set(): Finalize the sequence * * To get an idea what has to be done in each function, please take a * look at the example sequences. */ class SeqMethod : protected SeqMethodProxy, public SeqObjList, public virtual JDXeditCaller, public StateMachine { public: /** * Constructs a method with the given label. */ SeqMethod(const STD_string& method_label); /** * Destructor */ virtual ~SeqMethod(); // public interface to obtain the different states: /** * Performs state transition to 'empty' */ bool clear() {return empty.obtain_state();} /** * Performs state transition to 'initialised' */ bool init() {return initialised.obtain_state();} /** * Performs state transition to 'built' */ bool build() {return built.obtain_state();} /** * Performs state transition to 'prepared' */ bool prepare() {return prepared.obtain_state();} /** * Updates the timing of the sequence (TR, TE) without changing its structure. * If the sequence is not yet in the 'built' state, this state will * be obtained first. */ bool update_timings(); /** * Prepares the acquisition parameters, i.e. recoInfo structure * and performs platform specific preparation (generating pulse program, etc.). * This function will be called by the current frontend (ODIN GUI, odin2idea, ...) * prior to the measurement. */ bool prep_acquisition() const; /** * Returns the description of the method */ const char* get_description() const {return description.c_str();} /** * This function is used in the ODINMAIN function to hand over control to the SeqMethod object. */ int process(int argc, char *argv[]); /** * Loads the sequence protocol (systemInfo, geometryInfo, sequencePars) from file 'filename' */ int load_protocol(const STD_string& filename); /** * Writes the sequence protocol (systemInfo, geometryInfo, sequencePars) to file 'filename' */ int write_protocol(const STD_string& filename) const {create_protcache(); return protcache->write(filename);} /** * Returns the method-specific parameters */ JcampDxBlock& get_methodPars() {return *methodPars;} /** * Loads the sequence parameters (commonPars & methodPars) from file */ int load_sequencePars(const STD_string& filename); /** * Writes the sequence parameters (commonPars & methodPars) to file */ int write_sequencePars(const STD_string& filename) const; /** * Sets the value of the sequence parameter 'parameter_label' to 'value'. * Returns true if successful. */ bool set_sequenceParameter(const STD_string& parameter_label, const STD_string& value); /** * Sets the current set of common sequence parameters */ SeqMethod& set_commonPars(const SeqPars& pars); /** * Returns the current set of common sequence parameters */ SeqPars& get_commonPars() {return (*commonPars);} /** * Sets the current geometry to 'geo' */ SeqMethod& set_geometry(const Geometry& geo) {geometryInfo->operator = (geo); return *this;} /** * Returns the current geometry */ Geometry& get_geometry() {return *(geometryInfo.unlocked_ptr());} /** * Loads the current geometry from disk */ int load_geometry(const STD_string& filename) {return geometryInfo->load(filename);} /** * Writes the current geometry to disk */ int write_geometry(const STD_string& filename) const {return geometryInfo->write(filename);} /** * Returns reference to the current study info */ Study& get_studyInfo() {return *(studyInfo.unlocked_ptr());} /** * Writes the systemInfo to disk */ int write_systemInfo(const STD_string& filename) const {return systemInfo->write(filename);} /** * Loads the systemInfo from disk */ int load_systemInfo(const STD_string& filename); /** * Initialises the method with the given system-specific stuff */ SeqMethod& init_systemInfo(double basicfreq,double maxgrad,double slewrate); /** * Writes the recoInfo to disk */ int write_recoInfo(const STD_string& filename) const; /** * Writes all files which describe the measurement, uses the given filename-prefix */ int write_meas_contex(const STD_string& prefix) const; /** * Returns the scan duration for this method */ double get_totalDuration() const; /** * Returns the current main nucleus of the sequence, i.e. the nucleus for which both, excitation and acquisition, will be performed */ STD_string get_main_nucleus() const {return systemInfo->get_main_nucleus();} /** * Returns the total number of acquisition windows in the sequence. */ unsigned int get_numof_acquisitions() const; /** * Returns a list of Pulsar pulses which are currently * active. */ STD_list get_active_pulsar_pulses() const; // overloaded virtual functions from SeqTreeObj unsigned int event(eventContext& context) const; // leave this public for idea_emulation void set_current_testcase(unsigned int index) {if(index empty; bool reset(); State initialised; bool empty2initialised(); State built; bool initialised2built(); State prepared; bool built2prepared(); }; ////////////////////////////////////////////////////////////////////// // Macro to include in every sequence file to create an entry point // Double-stage macros to stringize METHOD_LABEL, see http://c-faq.com/ansi/stringize.html #define ODINMETHOD_STRINGIZE_MACRO(x) #x #define ODINMETHOD_STRINGIZE(x) ODINMETHOD_STRINGIZE_MACRO(x) #ifdef NO_CMDLINE #define ODINMETHOD_ENTRY_POINT \ int ODINMAIN(int argc, char *argv[]) {\ return (new METHOD_CLASS(ODINMETHOD_STRINGIZE(METHOD_LABEL)))->process(argc,argv); \ } #else #define ODINMETHOD_ENTRY_POINT \ int ODINMAIN(int argc, char *argv[]) {\ if(LogBase::set_log_levels(argc,argv,false)) return 0; \ return (new METHOD_CLASS(ODINMETHOD_STRINGIZE(METHOD_LABEL)))->process(argc,argv); \ } #endif #endif odin-1.8.5/odinseq/seqgradvec.h0000644000175000017500000000664311322062345013345 00000000000000/*************************************************************************** seqgradvec.h - description ------------------- begin : Tue Aug 13 2002 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQGRADVEC_H #define SEQGRADVEC_H #include #include /** * @addtogroup odinseq * @{ */ /** * \brief Vector of constant gradients * * This class represents a gradient object with a constant gradient * shape with the the strength taken from a vector. This object * can be attached to a SeqLoop to iterate over the values in the * vector. */ class SeqGradVector : public SeqGradChan, public SeqVector { public: /** * Constructs a gradient vector labeled 'object_label' with the following properties: * - gradchannel: The channel this object should be played out * - maxgradstrength: The maximum gradient strength for this object * - trimarray: The vector of gradient strength values * - gradduration: The duration of this gradient object */ SeqGradVector(const STD_string& object_label,direction gradchannel, float maxgradstrength,const fvector& trimarray, double gradduration); /** * Constructs a copy of 'sgv' */ SeqGradVector(const SeqGradVector& sgv); /** * Construct an empty gradient object with the given label */ SeqGradVector(const STD_string& object_label = "unnamedSeqGradVector"); /** * Specifies the trim values that will be used */ SeqGradVector& set_trims(const fvector& trims); /** * Returns the trim values that will be used */ fvector get_trims() const {return trimvals;} /** * Assignment operator that makes this gradient channel object become a copy of 'sgv' */ SeqGradVector& operator = (const SeqGradVector& sgv); private: friend class SeqGradSubVector; friend class SeqGradVectorPulse; // overwriting virtual functions from SeqClass bool prep(); // overwriting virtual functions from SeqGradChan SeqGradChan& get_subchan(double starttime, double endtime) const; STD_string get_grdpart(float matrixfactor) const; float get_integral() const {return get_current_strength()*get_gradduration();} // overwriting virtual functions from SeqVector svector get_vector_commands(const STD_string& iterator) const; unsigned int get_vectorsize() const; bool prep_iteration() const; bool is_qualvector() const {return false;} svector get_reord_vector_commands(const STD_string& iterator) const; float get_current_strength() const; const SeqGradVector* parent; fvector trimvals; }; /** @} */ ///////////////////////////////////////////////////////////////// #endif odin-1.8.5/odinseq/seqparallel.h0000644000175000017500000001150511322062345013517 00000000000000/*************************************************************************** seqparallel.h - description ------------------- begin : Fri Apr 16 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPARALLEL_H #define SEQPARALLEL_H #include #include #include #include /** * @addtogroup odinseq_internals * @{ */ /** * The base class for platform specific drivers of parallel RF/gradient handling */ class SeqParallelDriver : public SeqDriverBase { public: SeqParallelDriver() {} virtual ~SeqParallelDriver() {} virtual STD_string get_program(programContext& context, const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const = 0; virtual double get_duration (const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const = 0; virtual double get_predelay (const SeqObjBase* soa, const SeqGradObjInterface* sgoa) const = 0; virtual SeqParallelDriver* clone_driver() const = 0; }; ///////////////////////////////////////////////////////////////////////////////////////// /** * This container class is used to play out a sequence object (RF pulse, acquisition) * and a gradient object in parallel */ class SeqParallel : public SeqObjBase, public virtual SeqGradInterface { public: /** * Construct an empty gradient channel list with the given label */ SeqParallel(const STD_string& object_label="unnamedSeqParallel"); /** * Constructs a copy of 'sgp' */ SeqParallel(const SeqParallel& sgp); /** * Assignment operator */ SeqParallel& operator = (const SeqParallel& sgp); /** * Makes 'sgc' become the gradient part */ SeqParallel& operator /= (SeqGradChan& sgc); /** * Makes 'sgcl' become the gradient part */ SeqParallel& operator /= (SeqGradChanList& sgcl); /** * Makes 'sgcp' become the gradient part */ SeqParallel& operator /= (SeqGradChanParallel& sgcp); /** * Makes 'sgoa' become the gradient part */ SeqParallel& operator /= (SeqGradObjInterface& sgoa); /** * Makes 'soa' become the RF part */ SeqParallel& operator /= (const SeqObjBase& soa); // overloading virtual function from SeqTreeObj STD_string get_program(programContext& context) const {return pardriver->get_program(context,get_pulsptr(),get_const_gradptr());} double get_duration() const; STD_string get_properties() const; unsigned int event(eventContext& context) const; SeqValList get_freqvallist(freqlistAction action) const; SeqValList get_delayvallist() const; void query(queryContext& context) const; RecoValList get_recovallist(unsigned int reptimes, JDXkSpaceCoords& coords) const; double get_rf_energy() const; // overloading virtual function from SeqGradInterface SeqGradInterface& set_strength(float gradstrength); SeqGradInterface& invert_strength(); float get_strength() const; fvector get_gradintegral() const; double get_gradduration() const; SeqGradInterface& set_gradrotmatrix(const RotMatrix& matrix); /** * Returns the duration for the gradient commands in the pulse programm */ double get_pulprogduration() const; /** * Clears the RF anf gradient part */ void clear(); protected: SeqParallel& set_pulsptr(const SeqObjBase* pptr); const SeqObjBase* get_pulsptr() const; SeqParallel& set_gradptr(SeqGradObjInterface* gptr); SeqParallel& set_gradptr(const SeqGradObjInterface* gptr); SeqParallel& clear_gradptr(); SeqGradObjInterface* get_gradptr() const; const SeqGradObjInterface* get_const_gradptr() const; private: friend class SeqOperator; friend class SeqObjList; friend class SeqObjVector; friend class SeqGradObjInterface; friend class SeqGradChanList; friend class SeqEpiDriverParavision; // overloading virtual function from SeqClass void clear_container() {clear();} mutable SeqDriverInterface pardriver; Handler pulsptr; Handler gradptr; Handler const_gradptr; }; /** @} */ #endif odin-1.8.5/odinseq/seqgradchanlist.cpp0000644000175000017500000001607111322062345014724 00000000000000#include "seqgradchanlist.h" #include "seqparallel.h" #include "seqgradchanparallel.h" #include void bad_serial(const Labeled& s1, const Labeled& s2) { Log odinlog("","bad_serial"); ODINLOG(odinlog,errorLog) << s1.get_label() << "+=" << s2.get_label() << ": different channels"; } SeqGradChanList::SeqGradChanList(const STD_string& object_label) { set_label(object_label); } SeqGradChanList::SeqGradChanList(const SeqGradChanList& sgcl) { Log odinlog(this,"SeqGradChanList"); SeqGradChanList::operator = (sgcl); } SeqGradChanList::~SeqGradChanList() { clear(); } SeqGradChanList& SeqGradChanList::operator = (const SeqGradChanList& sgcl) { Log odinlog(this,"operator = (...)"); SeqTreeObj::operator = (sgcl); clear(); for(constiter it=sgcl.get_const_begin();it!=sgcl.get_const_end();++it) { append(**it); } return *this; } double SeqGradChanList::get_duration() const { Log odinlog(this,"SeqGradChanList::get_duration"); SeqGradChanList dummylist(*this); SeqGradChanParallel dummypar; dummypar+=dummylist; SeqParallel dummy; dummy.set_gradptr((SeqGradObjInterface*)&dummypar); // will use SeqParallel to calculate duration ODINLOG(odinlog,normalDebug) << "duration=" << dummy.get_duration() << STD_endl; return dummy.get_duration(); } direction SeqGradChanList::get_channel() const { Log odinlog(this,"get_channel"); if(size()) return (*get_const_begin())->get_channel(); else return readDirection; } fvector SeqGradChanList::get_gradintegral() const { fvector result(3); for(constiter it=get_const_begin();it!=get_const_end();++it) { result=result+(*it)->get_gradintegral(); } return result; } SeqGradInterface& SeqGradChanList::set_strength(float gradstrength) { Log odinlog(this,"set_strength"); for(iter it=get_begin();it!=get_end();++it) { (*it)->set_strength(gradstrength); } return *this; } SeqGradInterface& SeqGradChanList::invert_strength() { Log odinlog(this,"invert_strength"); for(iter it=get_begin();it!=get_end();++it) { (*it)->invert_strength(); } return *this; } float SeqGradChanList::get_strength() const { Log odinlog(this,"get_strength"); float result=0.0; for(constiter it=get_const_begin();it!=get_const_end();++it) { float tmp=(*it)->get_strength(); if(fabs(tmp)>fabs(result)) result=tmp; } return result; } double SeqGradChanList::get_gradduration() const { Log odinlog(this,"SeqGradChanList::get_gradduration"); double result=0.0; ODINLOG(odinlog,normalDebug) << "size()=" << size() << STD_endl; for(constiter it=get_const_begin();it!=get_const_end();++it) { ODINLOG(odinlog,normalDebug) << "dur[" << (*it)->get_label() << "]=" << (*it)->get_gradduration() << STD_endl; result+=(*it)->get_gradduration(); } return result; } SeqGradInterface& SeqGradChanList::set_gradrotmatrix(const RotMatrix& matrix) { Log odinlog(this,"set_gradrotmatrix"); for(iter it=get_begin();it!=get_end();++it) (*it)->set_gradrotmatrix(matrix); return *this; } SeqGradChanList& SeqGradChanList::operator += (SeqGradChanList& sgcl) { Log odinlog(this,"SeqGradChanList::operator += (SeqGradChanList)"); if(size() && sgcl.size()) { if(get_channel()!=sgcl.get_channel()) { bad_serial(*this,sgcl); return *this; } } constiter it; // avoid redefenition error with VC6 SeqGradChanList chanlistbuff; // use buffer to avoid deadlocks for(it=sgcl.get_const_begin();it!=sgcl.get_const_end();++it) { ODINLOG(odinlog,normalDebug) << "appending >" << (*it)->get_label() << "<" << STD_endl; chanlistbuff+=(**it); } for(it=chanlistbuff.get_const_begin();it!=chanlistbuff.get_const_end();++it) { ODINLOG(odinlog,normalDebug) << "appending >" << (*it)->get_label() << "<" << STD_endl; (*this)+=(**it); } return *this; } SeqGradChanList& SeqGradChanList::operator += (SeqGradChan& sgc) { Log odinlog(this,"SeqGradChanList::operator += (SeqGradChan)"); ODINLOG(odinlog,normalDebug) << "appending >" << sgc.get_label() << "<" << STD_endl; if(size()) { if(get_channel()!=sgc.get_channel()) { bad_serial(*this,sgc); return *this; } } append(sgc); return *this; } void SeqGradChanList::clear_container() {clear();} unsigned int SeqGradChanList::event(eventContext& context) const { unsigned int result=0; for(constiter it=get_const_begin();it!=get_const_end();++it) { result+=(*it)->event(context); } return result; } void SeqGradChanList::query(queryContext& context) const { SeqTreeObj::query(context); // defaults if(context.action==count_acqs) return; // nothing to do context.treelevel++; for(constiter it=get_const_begin();it!=get_const_end();++it) { context.parentnode=this; // reset to this because it might changed by last query (*it)->query(context); } context.treelevel--; } STD_string SeqGradChanList::get_properties() const { return "NumOfChanObjs="+itos(size()); } fvector SeqGradChanList::get_switchpoints() const { Log odinlog(this,"get_switchpoints"); fvector result(size()); double elapsed_sp=0.0; unsigned int index=0; for(constiter it=get_const_begin();it!=get_const_end();++it) { elapsed_sp+=(*it)->get_gradduration(); result[index]=elapsed_sp; ODINLOG(odinlog,normalDebug) << "switchpoint(" << (*it)->get_label() << ")=" << elapsed_sp << STD_endl; index++; } return result; } SeqGradChanList& SeqGradChanList::get_chanlist4gp(const fvector& switchpoints) { Log odinlog(this,"get_chanlist4gp"); ODINLOG(odinlog,normalDebug) << "switchpoints=" << (1000.0*switchpoints).printbody() << STD_endl; SeqGradChanList *retso=new SeqGradChanList(STD_string(get_label())+"_4gp"); retso->set_temporary(); double elapsed_sp=0.0; for(unsigned int isp=0; ispget_gradduration()*1000.0+0.5)==graddur) retso->append(*chanptr); else { SeqGradChan& chanseg=chanptr->get_subchan(startelapsed-chanstart,elapsed_sp-chanstart); chanseg.set_gradrotmatrix(chanptr->gradrotmatrix); retso->append(chanseg); } } } return *retso; } SeqGradChan* SeqGradChanList::get_chan(double& chanstart, double midtime) { Log odinlog(this,"get_chan"); SeqGradChan* result=0; double elapsed_sp=0.0; for(constiter it=get_const_begin();it!=get_const_end();++it) { double startelapsed=elapsed_sp; elapsed_sp+=(*it)->get_gradduration(); if( (midtime>startelapsed) && (midtime; odin-1.8.5/odinseq/seqgradobj.cpp0000644000175000017500000000160711322062345013670 00000000000000#include "seqgradobj.h" #include "seqparallel.h" SeqGradObjInterface::SeqGradObjInterface(const STD_string& object_label) : SeqTreeObj() { set_label(object_label); } SeqGradObjInterface::SeqGradObjInterface(const SeqGradObjInterface& sgoa) { SeqGradObjInterface::operator = (sgoa); } SeqGradObjInterface& SeqGradObjInterface::operator = (const SeqGradObjInterface& sgoa) { SeqTreeObj::operator = (sgoa); return *this; } double SeqGradObjInterface::get_duration() const { Log odinlog(this,"SeqGradObjInterface::get_duration()"); SeqParallel dummy; dummy.set_gradptr(this); // will use SeqParallel to calculate duration ODINLOG(odinlog,normalDebug) << "duration=" << dummy.get_duration() << STD_endl; return dummy.get_duration(); } double SeqGradObjInterface::get_pulprogduration() const { SeqParallel dummy; return dummy.SeqParallel::get_pulprogduration(); } odin-1.8.5/odinseq/seqgradconst.cpp0000644000175000017500000000465011322062345014245 00000000000000#include "seqgradconst.h" SeqGradConst::SeqGradConst(const STD_string& object_label,direction gradchannel, float gradstrength, double gradduration) : SeqGradChan(object_label,gradchannel,gradstrength,gradduration) {} SeqGradConst::SeqGradConst(const SeqGradConst& sgc) { SeqGradConst::operator = (sgc); } SeqGradConst::SeqGradConst(const STD_string& object_label) : SeqGradChan(object_label) {} STD_string SeqGradConst::get_grdpart(float matrixfactor) const { return graddriver->get_const_program(get_strength(),matrixfactor); } SeqGradConst& SeqGradConst::operator = (const SeqGradConst& sgc) { SeqGradChan::operator = (sgc); return *this; } SeqGradChan& SeqGradConst::get_subchan(double starttime, double endtime) const { SeqGradConst* sgc= new SeqGradConst(STD_string(get_label())+"_("+ftos(starttime)+"-"+ftos(endtime)+")",get_channel(),get_strength(),endtime-starttime); sgc->set_temporary(); return *sgc; } bool SeqGradConst::prep() { Log odinlog(this,"prep"); if(!SeqGradChan::prep()) return false; double dur=get_gradduration(); float str=get_strength(); float possible_maxgrad=dur*systemInfo->get_max_slew_rate(); if(fabs(str)>possible_maxgrad) { ODINLOG(odinlog,errorLog) << "Duration=" << dur << " too short to ramp up to strength=" << str << STD_endl; return false; } return graddriver->prep_const(str,get_grdfactors_norot(),dur); } /////////////////////////////////////////////////////////////////////////////////////////// SeqGradDelay::SeqGradDelay(const STD_string& object_label,direction gradchannel, double gradduration) : SeqGradChan(object_label,gradchannel,0.0,gradduration) { } SeqGradDelay::SeqGradDelay(const SeqGradDelay& sgd) { SeqGradDelay::operator = (sgd); } SeqGradDelay::SeqGradDelay(const STD_string& object_label) : SeqGradChan(object_label) { } STD_string SeqGradDelay::get_grdpart(float matrixfactor) const { return graddriver->get_delay_program(get_strength(),matrixfactor); } SeqGradDelay& SeqGradDelay::operator = (const SeqGradDelay& sgd) { SeqGradChan::operator = (sgd); return *this; } SeqGradChan& SeqGradDelay::get_subchan(double starttime, double endtime) const { SeqGradDelay* sgd= new SeqGradDelay(STD_string(get_label())+"_("+ftos(starttime)+"-"+ftos(endtime)+")",get_channel(),endtime-starttime); sgd->set_temporary(); return *sgd; } odin-1.8.5/odinseq/seqblsiegprep.cpp0000755000175000017500000000776111625224370014432 00000000000000/* Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include "seqblsiegprep.h" SeqBlSiegPrep::SeqBlSiegPrep ( const STD_string& object_label, float dur, float fa, float off, float wd, float sl ) : SeqPulsar ( object_label ) { set_shape ( "Fermi" ); set_dim_mode ( zeroDeeMode ); set_filter ( "NoFilter" ); width = wd; width.set_description ( "Distance of turning points of Fermi shaped pulse" ).set_label ( "FermiWidth" ); width.set_minmaxval ( 0,1 ); pars.append ( width ); slope = sl; slope.set_description ( "Slope of Fermi shaped pulse" ).set_label ( "FermiSlope" ); slope.set_minmaxval ( 0,150 ); pars.append ( slope ); duration = dur; duration.set_description ( "Duration of the Fermi pulse" ).set_label ( "Duration" ); duration.set_minmaxval ( 0,100 ); pars.append ( duration ); angle = fa; angle.set_description ( "Flipangle of Fermi pulse [ deg ]" ).set_label ( "Flipangle" ); angle.set_minmaxval ( 0,1000 ); pars.append ( angle ); offset = off; offset.set_description ( "Frequency offset of Fermi pulse [ Hz ]" ).set_label ( "Offset" ); offset.set_minmaxval ( -100000,100000 ); pars.append ( offset ); // set information parameters amplitude.set_description ( "Pulse Amplitude [ uT ]" ).set_label ( "PulseAmplitude" ); amplitude.set_parmode ( noedit ); info.append ( amplitude ); weighting.set_description ( "Weighting factor (Info) in [rad / uT^2]" ).set_label ( "Weighting" ); weighting.set_parmode ( noedit ); info.append ( weighting ); info.set_description ( "Infos about Bloch-Siegert preparation" ).set_label ( "Info" ); pars.append ( info ); pars.set_description ( "Parameters for the Bloch-Siegert preparation for B1-Mapping (see Sacolick et al. MRM(65)2010: 1315-1322)" ); prep(); } SeqBlSiegPrep::SeqBlSiegPrep ( const SeqBlSiegPrep& sbsp ) { SeqBlSiegPrep::operator=(sbsp); } bool SeqBlSiegPrep::prep() { Log odinlog ( this,"prep" ); set_shape ( "Fermi" ); set_shape_parameter ( "slope",ftos ( slope ) ); set_shape_parameter ( "width",ftos ( width ) ); set_pulsduration ( duration ); set_flipangle ( angle ); set_freqoffset ( offset ); // calculate the info parameters cvector rfWave = get_B1(); weighting=0; for ( int i = 0; i< rfWave.size(); i++ ) { weighting += ( abs ( rfWave[i] ) *abs ( rfWave[i] ) ); ODINLOG ( odinlog,verboseDebug ) << "abs(rfWave[" << i << "]) = " << abs ( rfWave[i] ) << STD_endl; } weighting *= duration/ rfWave.size() * // [ ms ] pow ( get_systemInfo().get_gamma ( "1H" ),2 ) / // [ ( rad * MHz / T ) ^ 2 ] ( 2 * offset ) * // [ 1 / Hz / rad ] 0.001 ; // --> final unit : [ rad / (uT ^ 2) ] amplitude = get_B10() *1000; // [ uT ] return true; } SeqBlSiegPrep& SeqBlSiegPrep::operator= ( const SeqBlSiegPrep& sbsp ) { ( *this ).SeqPulsar::operator= ( sbsp ); ( *this ).pars = sbsp.pars; ( *this ).info = sbsp.info; return *this; } odin-1.8.5/pulsar/0000755000175000017500000000000011735135551010773 500000000000000odin-1.8.5/pulsar/pulsar.10000644000175000017500000000124311734623145012303 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH PULSAR "1" "March 2012" "pulsar 1.8.5" "User Commands" .SH NAME pulsar \- Pulse editor of ODIN .SH SYNOPSIS .B pulsar [\fIoptions\fR] [\fI\fR] .SH DESCRIPTION pulsar: Pulse editor of ODIN .SH OPTIONS .HP \fB\-noedit\fR : View\-only mode .HP \fB\-s\fR : Load system defaults .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/pulsar/pulsar.h0000644000175000017500000000331511322062353012363 00000000000000/*************************************************************************** pulsar.h - description ------------------- begin : Fri Jul 7 13:38:24 /etc/localtime 2000 copyright : (C) 2000 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PULSAR_H #define PULSAR_H #include "pulsarview.h" #define IDS_PULSAR_ABOUT "Pulsar user interface\nVersion " VERSION \ "\n(w) 2000-2005 by Thies Jochimsen\n\n" class PulsarMain : public QObject, public GuiMainWindow { Q_OBJECT public: PulsarMain(); public slots: void slotFileDone(); void slotFileQuit(); void slotHelpAbout(); void changeCaption(const char* text); private: void initMenuBar(); bool queryExit(); PulsarView *view; GuiPopupMenu* fileMenu; GuiPopupMenu* importMenu; GuiPopupMenu* exportMenu; GuiPopupMenu* viewMenu; GuiPopupMenu* settingsMenu; GuiPopupMenu* helpMenu; }; #endif odin-1.8.5/pulsar/pulsarview.h0000644000175000017500000000536211322062353013262 00000000000000/*************************************************************************** pulsarview.h - description ------------------- begin : Thu Jun 20 19:02:26 CEST 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PULSARVIEW_H #define PULSARVIEW_H #include #include #include #include //////////////////////////////////////// // for debugging Pulsar component class PulsarComp { public: static const char* get_compName(); }; //////////////////////////////////////// struct PulsarCancel {}; // exception //////////////////////////////////////// class PulsarView : public QWidget, public virtual JDXeditWidget { Q_OBJECT public: PulsarView(QWidget *parent=0); ~PulsarView(); void initPulsarView(); static void usage(); signals: void done(); void newCaption(const char* text); public slots: void slotFileNew(); void slotFileOpen(); void slotFileSave(); void slotFileSaveAs(); // void swapSliderTracking(bool); void writeBrukerRf(); void exportRfampASCII(); void exportRfphaASCII(); void exportGxASCII(); void exportGyASCII(); void exportGzASCII(); void exportMampASCII(); void exportMphaASCII(); void exportMzASCII(); void exportPulseJDX(); void exportMagJDX(); void edit_systemInfo(); private slots: void updatePulse(); void updateMagnetization(); void emitDone(); private: // Implemented function of JDXeditWidget void updateWidget(); void vriteArray(const STD_string& filename, const fvector& data); void exportASCIIpulse(const fvector& data); void exportASCIImag(const fvector& data); OdinPulse* pulse; Sample* sample; SeqSimMagsi* mag; funcMode old_mode; STD_string fileName; GuiGridLayout *grid; JDXwidget* pulseWidget[n_dimModes]; JDXwidget* sampleWidget[n_dimModes]; JDXwidget* magnWidget[n_dimModes]; GuiProgressDialog* progress; int progcount; }; #endif odin-1.8.5/pulsar/main.cpp0000644000175000017500000000055611322062353012340 00000000000000#include "pulsar.h" int main(int argc, char *argv[]) { // do this here so we do not have to query X server in order to get usage for manual if(hasHelpOption(argc, argv)) {PulsarView::usage();exit(0);} GuiApplication a(argc, argv); // debug handler will be initialized here PulsarMain *pulsar=new PulsarMain(); return a.start(pulsar->get_widget()); } odin-1.8.5/pulsar/Makefile.am0000644000175000017500000000126711322062353012744 00000000000000 if GUI_ENABLED INCLUDES = $(all_includes) # Auto-generate any needed moc files %_moc.cpp: %.h $(MOC) -o $@ $< bin_PROGRAMS = pulsar pulsar_SOURCES = \ main.cpp \ pulsar.cpp pulsar.h pulsar_moc.cpp \ pulsarview.cpp pulsarview.h pulsarview_moc.cpp pulsar_LDADD = ../odinseq/libodinseq.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = pulsar.1 dist-hook: -rm -rf $(distdir)/*_moc.cpp endif clean-local: -rm -f *_moc.cpp odin-1.8.5/pulsar/Makefile.in0000644000175000017500000005235211734622602012764 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @GUI_ENABLED_TRUE@bin_PROGRAMS = pulsar$(EXEEXT) subdir = pulsar DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__pulsar_SOURCES_DIST = main.cpp pulsar.cpp pulsar.h pulsar_moc.cpp \ pulsarview.cpp pulsarview.h pulsarview_moc.cpp @GUI_ENABLED_TRUE@am_pulsar_OBJECTS = main.$(OBJEXT) pulsar.$(OBJEXT) \ @GUI_ENABLED_TRUE@ pulsar_moc.$(OBJEXT) pulsarview.$(OBJEXT) \ @GUI_ENABLED_TRUE@ pulsarview_moc.$(OBJEXT) pulsar_OBJECTS = $(am_pulsar_OBJECTS) @GUI_ENABLED_TRUE@pulsar_DEPENDENCIES = ../odinseq/libodinseq.la \ @GUI_ENABLED_TRUE@ ../odinqt/libodinqt.la \ @GUI_ENABLED_TRUE@ ../odinpara/libodinpara.la \ @GUI_ENABLED_TRUE@ ../tjutils/libtjutils.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(pulsar_SOURCES) DIST_SOURCES = $(am__pulsar_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @GUI_ENABLED_TRUE@INCLUDES = $(all_includes) @GUI_ENABLED_TRUE@pulsar_SOURCES = \ @GUI_ENABLED_TRUE@ main.cpp \ @GUI_ENABLED_TRUE@ pulsar.cpp pulsar.h pulsar_moc.cpp \ @GUI_ENABLED_TRUE@ pulsarview.cpp pulsarview.h pulsarview_moc.cpp @GUI_ENABLED_TRUE@pulsar_LDADD = ../odinseq/libodinseq.la ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Manual pages for distribution @GUI_ENABLED_TRUE@dist_man_MANS = pulsar.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu pulsar/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu pulsar/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list pulsar$(EXEEXT): $(pulsar_OBJECTS) $(pulsar_DEPENDENCIES) @rm -f pulsar$(EXEEXT) $(CXXLINK) $(pulsar_OBJECTS) $(pulsar_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pulsar.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pulsar_moc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pulsarview.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pulsarview_moc.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @GUI_ENABLED_FALSE@dist-hook: distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags dist-hook \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags distdir dvi dvi-am html \ html-am info info-am install install-am install-binPROGRAMS \ install-data install-data-am install-dvi install-dvi-am \ install-exec install-exec-am install-html install-html-am \ install-info install-info-am install-man install-man1 \ install-pdf install-pdf-am install-ps install-ps-am \ install-strip installcheck installcheck-am installdirs \ maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \ pdf pdf-am ps ps-am tags uninstall uninstall-am \ uninstall-binPROGRAMS uninstall-man uninstall-man1 # Auto-generate any needed moc files @GUI_ENABLED_TRUE@%_moc.cpp: %.h @GUI_ENABLED_TRUE@ $(MOC) -o $@ $< # Auto-generate manual pages, only if not in srcdir @GUI_ENABLED_TRUE@%.1: % @GUI_ENABLED_TRUE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @GUI_ENABLED_TRUE@dist-hook: @GUI_ENABLED_TRUE@ -rm -rf $(distdir)/*_moc.cpp clean-local: -rm -f *_moc.cpp # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/pulsar/pulsarview.cpp0000644000175000017500000002343611363773560013635 00000000000000#include "pulsarview.h" #include #include const char* PulsarComp::get_compName() {return "Pulsar";} LOGGROUNDWORK(PulsarComp) void PulsarView::usage() { STD_cout << "pulsar: Pulse editor of ODIN" << STD_endl; STD_cout << "Usage: pulsar [options] []" << STD_endl; STD_cout << "Options:" << STD_endl; STD_cout << "\t-noedit : View-only mode" << STD_endl; STD_cout << "\t -s : Load system defaults" << STD_endl; STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } PulsarView::PulsarView(QWidget *parent) : QWidget(parent) { Log odinlog("PulsarView","PulsarView(...)"); char buff[ODIN_MAXCHAR]; pulse=new OdinPulse("Pulse",true); ODINLOG(odinlog,normalDebug) << "generation pars initialised" << STD_endl; sample=new Sample("Sample",true,true); ODINLOG(odinlog,normalDebug) << "sample pars initialised" << STD_endl; mag=new SeqSimMagsi("Magnetization"); ODINLOG(odinlog,normalDebug) << "simulation pars initialised" << STD_endl; if(isCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-noedit")) { pulse->set_parmode(noedit); } if(getCommandlineOption(GuiApplication::argc(),GuiApplication::argv(),"-s",buff,ODIN_MAXCHAR)) { SeqPlatformProxy::load_systemInfo(buff); ODINLOG(odinlog,normalDebug) << "systemInfo file >" << buff << "< loaded" << STD_endl; } if(getLastArgument(GuiApplication::argc(),GuiApplication::argv(),buff,ODIN_MAXCHAR)) { if(STD_string(buff)!="") { pulse->load(buff); fileName=buff; ODINLOG(odinlog,normalDebug) << "pulsar file >" << buff << "< loaded" << STD_endl; } } grid=new GuiGridLayout( this, 2, 2); ODINLOG(odinlog,normalDebug) << "layout created" << STD_endl; /*------------- general pulse parameters ------------------------*/ old_mode=n_dimModes; unsigned int i; for(i=0; i odinlog("PulsarView","updateWidget()"); if(!progress) { progress=new GuiProgressDialog(this, false,0); progress->set_text("Calculating Pulse"); progress->show(); progcount=0; } else { progress->set_progress(progcount); progcount++; } if(progress->was_cancelled()) throw PulsarCancel(); pulseWidget[old_mode]->updateWidget(); updateMagnetization(); GuiApplication::process_events(); // Must be called manually because Qt event handler is blocked in optimization loop } void PulsarView::updatePulse() { Log odinlog("PulsarView","updatePulse()"); ODINLOG(odinlog,normalDebug) << "calling pulse->update() ..." << STD_endl; progress=0; try { pulse->update(); } catch(PulsarCancel) { ODINLOG(odinlog,normalDebug) << " cancelled" << STD_endl; } if(progress) delete progress; progress=0; ODINLOG(odinlog,normalDebug) << "done" << STD_endl; funcMode mode=pulse->get_dim_mode(); ODINLOG(odinlog,normalDebug) << "old_mode/mode=" << old_mode << "/" << mode << STD_endl; if(old_mode!=mode) { if(old_mode!=n_dimModes) { ODINLOG(odinlog,normalDebug) << "Hiding old JDXwidget" << STD_endl; pulseWidget[old_mode]->deleteDialogs(); pulseWidget[old_mode]->hide(); } ODINLOG(odinlog,normalDebug) << "Allocating JDXwidget" << STD_endl; if(pulseWidget[mode]==0) pulseWidget[mode]=new JDXwidget(*pulse,2,this,true); ODINLOG(odinlog,normalDebug) << "Showing JDXwidget" << STD_endl; pulseWidget[mode]->show(); grid->add_widget(pulseWidget[mode], 0, 0, GuiGridLayout::Default, 2, 1); connect(pulseWidget[mode],SIGNAL(valueChanged()),this,SLOT(updatePulse())); connect(pulseWidget[mode],SIGNAL(doneButtonPressed()),this,SLOT(emitDone())); } ODINLOG(odinlog,normalDebug) << "calling pulseWidget[" << mode << "]->updateWidget() ..." << STD_endl; pulseWidget[mode]->updateWidget(); ODINLOG(odinlog,normalDebug) << "done" << STD_endl; updateMagnetization(); old_mode=mode; } void PulsarView::updateMagnetization() { Log odinlog("PulsarView","updateMagnetization"); funcMode mode=pulse->get_dim_mode(); ODINLOG(odinlog,normalDebug) << "mode=" << mode << STD_endl; if(old_mode!=mode) { ODINLOG(odinlog,normalDebug) << "Changing mode" << STD_endl; bool onlineflag=true; unsigned int xsize=1; unsigned int ysize=1; unsigned int zsize=1; unsigned int freqsize=1; if(mode==zeroDeeMode) { freqsize=255; } if(mode==oneDeeMode) { zsize=255; } if(mode>=twoDeeMode) {xsize=31; ysize=31; onlineflag=false;} ODINLOG(odinlog,normalDebug) << "xsize/ysize/zsize/freqsize=" << xsize << "/" << ysize << "/" << zsize << "/" << freqsize << STD_endl; sample->resize(1,freqsize,zsize,ysize,xsize); mag->set_online_simulation(onlineflag); sample->update(); mag->update(); mag->prepare_simulation(*sample); // call once to resize mag pulse->simulate_pulse(*mag,*sample); // simulate once to get gray scale in 2D mode if(old_mode!=n_dimModes) { ODINLOG(odinlog,normalDebug) << "Deleting old widgets ..." << STD_endl; sampleWidget[old_mode]->deleteDialogs(); sampleWidget[old_mode]->hide(); magnWidget[old_mode]->deleteDialogs(); magnWidget[old_mode]->hide(); ODINLOG(odinlog,normalDebug) << "Deleting old widgets done" << STD_endl; } if(sampleWidget[mode]==0) { ODINLOG(odinlog,normalDebug) << "Creating new sampleWidget ..." << STD_endl; sampleWidget[mode]=new JDXwidget(*sample,1,this); sampleWidget[mode]->show(); grid->add_widget(sampleWidget[mode], 0, 1); connect(sampleWidget[mode],SIGNAL(valueChanged()),this,SLOT(updateMagnetization())); ODINLOG(odinlog,normalDebug) << "Creating new sampleWidget done" << STD_endl; } if(magnWidget[mode]==0) { ODINLOG(odinlog,normalDebug) << "Creating new magnWidget ..." << STD_endl; magnWidget[mode]=new JDXwidget(*mag,1,this); magnWidget[mode]->show(); grid->add_widget(magnWidget[mode], 1, 1); connect(magnWidget[mode],SIGNAL(valueChanged()),this,SLOT(updateMagnetization())); ODINLOG(odinlog,normalDebug) << "Creating new magnWidget done" << STD_endl; } sampleWidget[mode]->show(); magnWidget[mode]->show(); } sample->update(); mag->update(); if(mag->do_simulation()) pulse->simulate_pulse(*mag,*sample); sampleWidget[mode]->updateWidget(); magnWidget[mode]->updateWidget(); } void PulsarView::emitDone() {emit done();} void PulsarView::slotFileNew() { if(message_question("Resetting to defaults will delete the current values.\n" "Do you really want a fresh pulse ?", "New Pulse", this, true)) { (*pulse)=OdinPulse("Pulse",true); updatePulse(); } } void PulsarView::slotFileOpen() { STD_string newfile=get_open_filename("Open Pulse", fileName.c_str(), "", this); if (newfile!="") { fileName=newfile; emit newCaption(fileName.c_str()); pulse->load(fileName); updatePulse(); } } void PulsarView::slotFileSave() { if (fileName!="") { pulse->write(fileName); } else slotFileSaveAs(); } void PulsarView::slotFileSaveAs() { fileName=get_save_filename("Save Pulse", fileName.c_str(), "", this); if (fileName!="") { pulse->write(fileName); } } void PulsarView::writeBrukerRf() { STD_string fname=get_save_filename("Export Bruker Pulse", "", "", this); if (fname!="") { SeqPlatformProxy::set_current_platform(paravision); pulse->write_rf_waveform(fname); SeqPlatformProxy::set_current_platform(standalone); } } void PulsarView::vriteArray(const STD_string& filename, const fvector& data) { STD_string filestr; for(unsigned int i=0; iget_B1()));} void PulsarView::exportRfphaASCII() {exportASCIIpulse(phase(pulse->get_B1()));} void PulsarView::exportGxASCII() {exportASCIIpulse(pulse->get_Grad(readDirection));} void PulsarView::exportGyASCII() {exportASCIIpulse(pulse->get_Grad(phaseDirection));} void PulsarView::exportGzASCII() {exportASCIIpulse(pulse->get_Grad(sliceDirection));} void PulsarView::exportMampASCII() {exportASCIImag(mag->get_Mamp());} void PulsarView::exportMphaASCII() {exportASCIImag(mag->get_Mpha());} void PulsarView::exportMzASCII() {exportASCIImag(mag->get_Mz());} void PulsarView::exportPulseJDX() { STD_string fname=get_save_filename("Export JCAMP-DX Pulse", "", "", this); if(fname!="") { OdinPulse sd(*pulse); sd.set_filemode(include); sd.write(fname); } } void PulsarView::exportMagJDX() { STD_string fname=get_save_filename("Export JCAMP-DX Magnetization", "", "", this); if(fname!="") { SeqSimMagsi sm(*mag); sm.set_filemode(include); sm.write(fname); } } void PulsarView::edit_systemInfo() { JDXwidgetDialog* dlg=new JDXwidgetDialog(pulse->get_systemInfo(),1,this); connect(dlg,SIGNAL(valueChanged()),this,SLOT(updatePulse())); } odin-1.8.5/pulsar/pulsar.cpp0000644000175000017500000000642311322062353012721 00000000000000#include "pulsar.h" PulsarMain::PulsarMain() { Log odinlog("PulsarMain","PulsarMain(...)"); view=new PulsarView(GuiMainWindow::get_widget()); connect(view,SIGNAL(done()),this,SLOT(slotFileDone())); connect(view,SIGNAL(newCaption(const char*)),this,SLOT(changeCaption(const char*))); view->initPulsarView(); ODINLOG(odinlog,normalDebug) << "initView() done" << STD_endl; initMenuBar(); ODINLOG(odinlog,normalDebug) << "initMenuBar() done" << STD_endl; GuiMainWindow::show(view); } void PulsarMain::initMenuBar() { Log odinlog("PulsarMain","initMenuBar"); fileMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); fileMenu->insert_item("&New", view, SLOT(slotFileNew()), Qt::CTRL+Qt::Key_N); fileMenu->insert_item("&Open...", view, SLOT(slotFileOpen()), Qt::CTRL+Qt::Key_O); fileMenu->insert_separator(); fileMenu->insert_item("&Save", view, SLOT(slotFileSave()), Qt::CTRL+Qt::Key_S); fileMenu->insert_item("Save as...", view, SLOT(slotFileSaveAs()), 0); fileMenu->insert_separator(); fileMenu->insert_item("&Quit", this, SLOT(slotFileQuit()), Qt::CTRL+Qt::Key_Q); exportMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); exportMenu->insert_item("Export Bruker RF-Pulse", view, SLOT(writeBrukerRf())); exportMenu->insert_separator(); exportMenu->insert_item("Export ASCII RF-Amplitude", view, SLOT(exportRfampASCII())); exportMenu->insert_item("Export ASCII RF-Phase", view, SLOT(exportRfphaASCII())); exportMenu->insert_item("Export ASCII Gx", view, SLOT(exportGxASCII())); exportMenu->insert_item("Export ASCII Gy", view, SLOT(exportGyASCII())); exportMenu->insert_item("Export ASCII Gz", view, SLOT(exportGzASCII())); exportMenu->insert_separator(); exportMenu->insert_item("Export ASCII Magnetization Amplitide", view, SLOT(exportMampASCII())); exportMenu->insert_item("Export ASCII Magnetization Phase", view, SLOT(exportMphaASCII())); exportMenu->insert_item("Export ASCII z-Magnetization", view, SLOT(exportMzASCII())); exportMenu->insert_separator(); exportMenu->insert_item("Export JCAMP-DX Pulse", view, SLOT(exportPulseJDX())); exportMenu->insert_item("Export JCAMP-DX Magnetization", view, SLOT(exportMagJDX())); settingsMenu = new GuiPopupMenu(GuiMainWindow::get_widget()); settingsMenu->insert_item("&System Configuration ...", view, SLOT(edit_systemInfo()),0); helpMenu=new GuiPopupMenu(GuiMainWindow::get_widget()); helpMenu->insert_item("About...", this, SLOT(slotHelpAbout()), 0); GuiMainWindow::insert_menu("&File", fileMenu); GuiMainWindow::insert_menu("Ex&port", exportMenu); GuiMainWindow::insert_menu("&Settings", settingsMenu); GuiMainWindow::insert_menu_separator(); GuiMainWindow::insert_menu("&Help", helpMenu); } bool PulsarMain::queryExit() { return(message_question("Do your really want to quit?", "Quit...", GuiMainWindow::get_widget(), true)); } void PulsarMain::slotFileDone() { view->slotFileSave(); GuiApplication::quit(); } void PulsarMain::slotFileQuit() { if(queryExit()) { GuiApplication::quit(); } } void PulsarMain::slotHelpAbout() { message_question(IDS_PULSAR_ABOUT, "About...", GuiMainWindow::get_widget()); } void PulsarMain::changeCaption(const char* text) { GuiMainWindow::set_caption((STD_string("Pulsar " VERSION) + " - " + text).c_str()); } odin-1.8.5/AUTHORS0000644000175000017500000000107511322062355010451 00000000000000Thies Jochimsen : Project founder, main developer Michael v. Mengershausen : Data evaluation, vtk support Andreas Schaefer : EPI and MQC method, ICE program, bug reports Markus Koerber : Pinwheel pulse trajectories, more bug reports Robert Trampel : Simulation with relaxation Enrico Reimer : FileIO module, Converter, Filter framework Dirk Mueller : RF spoiling, filters, even more bug reports Torsten Schlumm. Christian Ros : ICE reconstruction to store raw data Martin Kraemer : BLADE reconstruction odin-1.8.5/odin.doxygen0000644000175000017500000016455211322062355011743 00000000000000# Doxyfile 1.5.6 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project # # All text after a hash (#) is considered a comment and will be ignored # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" ") #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded # by quotes) that should identify the project. PROJECT_NAME = # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = manual/ # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Farsi, Finnish, French, German, Greek, # Hungarian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, Polish, # Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish, # and Ukrainian. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful is your file systems # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the DETAILS_AT_TOP tag is set to YES then Doxygen # will output the detailed description near the top, like JavaDoc. # If set to NO, the detailed description appears after the member # documentation. DETAILS_AT_TOP = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 4 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate getter # and setter methods for a property. Setting this option to YES (the default) # will make doxygen to replace the get and set methods by a property in the # documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespace are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = YES # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = YES # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if sectionname ... \endif. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or define consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and defines in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # If the sources in your project are distributed over multiple directories # then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy # in the documentation. The default is NO. SHOW_DIRECTORIES = NO # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = YES # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = NO # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be abled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = ./ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx # *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 FILE_PATTERNS = *.h \ gencoil.cpp \ genmakefile.cpp \ gensample.cpp \ micalc.cpp \ miconv.cpp \ swab.cpp # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. EXCLUDE = platforms \ sequences \ replacements \ docs # The EXCLUDE_SYMLINKS tag can be used select whether or not files or # directories that are symbolic links (a Unix filesystem feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = *CVS* \ *.svn* \ *_moc.cpp # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = . # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER # is applied to all files. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C and C++ comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. Otherwise they will link to the documentstion. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = YES # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If the tag is left blank doxygen # will generate a default style sheet. Note that doxygen will try to copy # the style sheet file to the HTML output directory, so don't put your own # stylesheet in the HTML output directory as well, or it will be erased! HTML_STYLESHEET = # If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, # files or namespaces will be aligned in HTML using tables. If set to # NO a bullet list will be used. HTML_ALIGN_MEMBERS = YES # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. For this to work a browser that supports # JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox # Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). HTML_DYNAMIC_SECTIONS = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # The DISABLE_INDEX tag can be used to turn on/off the condensed index at # top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. DISABLE_INDEX = NO # This tag can be used to set the number of enum values (range [1..20]) # that doxygen will group on one line in the generated HTML documentation. ENUM_VALUES_PER_LINE = 4 # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to FRAME, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, # Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are # probably better off using the HTML help feature. Other possible values # for this tag are: HIERARCHIES, which will generate the Groups, Directories, # and Class Hiererachy pages using a tree view instead of an ordered list; # ALL, which combines the behavior of FRAME and HIERARCHIES; and NONE, which # disables this behavior completely. For backwards compatibility with previous # releases of Doxygen, the values YES and NO are equivalent to FRAME and NONE # respectively. GENERATE_TREEVIEW = NO # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = NO # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = NO # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4wide # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = NO # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = NO # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load stylesheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. This is useful # if you want to understand what is going on. On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # in the INCLUDE_PATH (see below) will be search if a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all function-like macros that are alone # on a line, have an all uppercase name, and do not end with a semicolon. Such # function macros are typically used for boiler-plate code, and will confuse # the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. # Optionally an initial location of the external documentation # can be added for each tagfile. The format of a tag file without # this location is as follows: # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths or # URLs. If a location is present for each tag, the installdox tool # does not have to be run to correct the links. # Note that each tag file must have a unique name # (where the name does NOT include the path) # If a tag file is not located in the directory in which doxygen # is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option is superseded by the HAVE_DOT option below. This is only a # fallback. It is recommended to install and use dot, since it yields more # powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = YES # By default doxygen will write a font called FreeSans.ttf to the output # directory and reference it in all dot files that doxygen generates. This # font does not include all possible unicode characters however, so when you need # these (or just want a differently looking font) you can specify the font name # using DOT_FONTNAME. You need need to make sure dot is able to find the font, # which can be done by putting it in a standard location or by setting the # DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory # containing the font. DOT_FONTNAME = FreeSans # By default doxygen will tell dot to use the output directory to look for the # FreeSans.ttf font (which doxygen will put there itself). If you specify a # different font using DOT_FONTNAME you can set the path where dot # can find it using this tag. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # the CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = NO # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are png, jpg, or gif # If left blank png will be used. DOT_IMAGE_FORMAT = png # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is enabled by default, which results in a transparent # background. Warning: Depending on the platform used, enabling this option # may lead to badly anti-aliased labels on the edges of a graph (i.e. they # become hard to read). DOT_TRANSPARENT = YES # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- # The SEARCHENGINE tag specifies whether or not a search engine should be # used. If set to NO the values of all tags below this one will be ignored. SEARCHENGINE = NO odin-1.8.5/INSTALL0000644000175000017500000004055511735132611010441 00000000000000 ============= BUILD ODIN FROM SCRATCH ON WINDOWS =================== Please note that the following instructions are for building ODIN from scratch on Windows using MinGW and to create a binary distribution of ODIN. If you just want to use ODIN on Windows, possibly in combination with IDEA, I strongly recommend that you download and install the binary distribution from the ODIN Download page, since the installation described here is pretty tedious. Uninstall any ODIN binary distributions before continuing. To get the GNU tools and compiler, download the MINGW and MSYS packages/installers from http://www.mingw.org/download.shtml. At the time of writing, these were the files MinGW-5.1.3.exe and MSYS-1.0.10.exe. Specify the location of MinGW during install of MSYS. Apply the patch posted here for Vista: http://lists-archives.org/mingw-users/06921-vista-gcc-cc1plus-bug.html Download and install the Qt open source distribution, e.g. qt-win-opensource-4.5.0-mingw.exe from http://www.qtsoftware.com/downloads/windows-cpp. It seems to be save to ignore the warning during install that the current MinGW is not compatible. Set the environment variables QTDIR and PATH manually, i.e. set QTDIR to the install directory and append %QTDIR%\bin to PATH. Create a directory (e.g. c:\MR-Software) to put all the ODIN-related stuff. Use the MSYS shell to install all further stuff. Please note: A drive letter X: in this shell can be used usin /X/, e.g. c: is /c/ in the MSYS shell. Download recent GSL source code, unpack and do a ./configure --prefix=/c/MR-Software --disable-shared --enable-static make make install Compile and install Blitz++ from source: ./configure --prefix=/c/MR-Software && make lib && make install Unpack qwt5. In qwtconfig.pri, comment out the line #CONFIG += QwtDll to build a static qwt (compiling of DLL fails). Do a qmake mingw32-make After compiling of qwt_designer_plugin.dll fails, install qwt manually: cp lib/libqwt.a /c/MR-Software/lib mkdir /c/MR-Software/include/qwt cp src/*.h /c/MR-Software/include/qwt Compile dcmtk source: 1) ./configure --prefix=/c/MR-Software 2) First 'make' (for libofstd) 3) create a built-in dictionary by going into dcmdata/libsrc and do a 'make builtindict'. Fix 'mkdictbi.cc:getUserName' if necessaray. 4) Compile and install the libraries by 'make && make install-lib' For LAPACK support: Get the g77 version of the AMD Core Math Library from http://developer.amd.com/acml.jsp and install it. Use a short installation path without dots, e.g. c:/acml, otherwise configure fails. Use the -a option of install.win (see below) to specify the location of libacml.a. For NIfTI/zlib support: 1) Download zlib from http://www.zlib.net and install with ./configure --prefix=/c/MR-Software && make install 2) Download nifticlib from http://niftilib.sourceforge.net/ Hack Makefile: Add -Ic:/MR-Software/include to ZLIB_INC and -Lc:/MR-Software/lib to ZLIB_PATH Use mingw32-make to compile, ignore errors in utils Install manually: cp lib/*.a /c/MR-Software/lib/ cp include/*.h /c/MR-Software/include/ Download the notepad2 editor from http://www.flos-freeware.ch/notepad2.html and copy Notepad2.exe to /c/MR-Software/bin Download and copy doxygen.exe to c:/Programme/Doxygen/ Download graphviz from http://www.graphviz.org/pub/graphviz/ARCHIVE/ and install it under Programme/ATT. Download and install NSIS with default settings to c:/Programme/NSIS/ Compile and pack ODIN using the script 'install.win' ============= INSTALLING ODIN ON LINUX/UNIX ======================= Prerequisites: ============== The following programs and libraries are required to compile ODIN for Linux/UNIX (In parenthesis are the version numbers of the packages with which ODIN has been tested successfully): * Qt library (3.0.* or later) * Qwt library (4.2.0 or later) * Blitz++ template library (0.8 or later) * GNU Scientific Library (0.9.3 or later) * optional: Vista/Lipsia library (http://www.cbs.mpg.de/institute/software/lipsia/download.html or vista-2.2.0 from ODIN download page), use configure option --enable-vistasupport to activate Vista support in ODIN * optional: NIFTI library (http://nifti.nimh.nih.gov), use configure option --enable-niftisupport to activate NIFTI support in ODIN * optional: vtk library (4.2.5, 4.4.2), use configure option --enable-vtksupport to activate VTK support in ODIN * optional: dcmtk library (3.5.4, 3.6.0), use configure option --enable-dcmtksupport to activate DICOM support in ODIN * optional: PNG library (1.2.27, 1.5.9), use configure option --enable-pngsupport to activate PNG support in ODIN * optional: gdb debugger and xterm terminal to attach debugger to running ODIN process * optional: oil library (0.3) for fast type conversion * optional: LAPACK for fast linear algebra. Since the NetLib implementation is currently not thread safe, we recommend using the thread-safe ACML (http://developer.amd.com/cpu/Libraries/acml/). Download the GFORTRAN version, and use --with-lapack-libname=acml during configure. A note for GRAPPA users: If no LAPACK is found during configure, Odin will fall back to using GSL for linear algebra. However, the GSL implementation is very slow (several orders of magnitude compared to LAPACK) which makes GRAPPA reconstruction impractical. So, please: MAKE SURE TO USE LAPACK FOR GRAPPA RECONSTRUCTION. At the best, use a thread-safe LAPACK implementation, like ACML. The actual library name can be given by --with-lapack-libname. A short HOWTO (for the impatient): ================================== After you've unpacked the archive go into the directory where this file resides and issue: ./configure && make After compilation log in as root and type make install After that you should be able to start Odin by odin on the command line. To configure/compile ODIN with other settings, enter ./configure --help to get a list of options. Platform Specific Notes: ======================== * Debian 4.0 (etch): To compile the tar.gz from the ODIN download page, the following packages are required: 'libqt3-mt-dev, libqwt-dev, libgsl0-dev'. Qt4 packages must be de-installed. Optionally, install libniftiio0-dev for NIFTI support, libdcmtk1-dev for DICOM support, liboil0.3-dev for fast type conversion, and atlas3-base for fast linear algebra. If you check out ODIN via SVN, you will need the additional packages 'autoconf automake libtool'. Blitz++ must be installed manually and configured with '--enable-shared' because of a known bug in the Debian package, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=369753 for details. Fortunately, this bug gets fixed with the next release of Debian. * Debian 5.0 (lenny): Create and install a Debian package with 'make deb' ! * Red Hat Enterprise Linux 3 (hosting Brukers Paravision 3) ODIN was successfully installed with the following libraries and configure options: gsl-1.6: ./configure --enable-shared=yes --enable-static=no blitz-0.8: ./configure --enable-shared=yes --enable-static=no vista-2.2.0: ./configure --enable-shared=yes --enable-static=no ODIN can be compiled with following options: ./configure --enable-shared=yes --enable-static=no * MacOS X 10.4(Tiger), 10.5(Leopard) -Install the development tools from Apple, i.e. XCode 2.4 or later -Use fink 0.8.0 and set the following environment variables: export FINKDIR=/sw export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$FINKDIR/lib export LIBRARY_PATH=$LIBRARY_PATH:$FINKDIR/lib export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:$FINKDIR/include -Install qt-mac-opensource, 4.1.x or later, use the source code distribution, otherwise qwt cannot be compiled (with the qmake of the dmg binary distribution) For a minimal Qt sufficient for Odin, configure Qt with ./configure -prefix $QT_INSTALL_DIR -no-qt3support -release -no-xmlpatterns -no-phonon -no-svg -no-webkit -no-nis -no-cups -no-dbus -nomake "tools examples demos docs" Set the variable QTDIR to point to the source-code directory of Qt -Additionally, install the following libraries: -qwt5 (adapt qwtconfig.pri: INSTALLBASE and headers.path = $$INSTALLBASE/include/qwt, comment out QwtDesigner) -gsl (fink package) -blitz++ (current CVS checkout with CVSROOT=:pserver:anonymous@blitz.cvs.sourceforge.net:/cvsroot/blitz cvs co blitz), for configuration,use 'LIBTOOLIZE=glibtoolize autoreconf -fiv' (aborts with error, but creates configure which works fine) If necessary, create directory blitz/apple and therein link to blitz/gnu/bzconfig.h (also in the installed blitz headers) -Optionally, install the following libraries: -vista-2.2.0 (from ODIN download page) -dcmtk 3.5.4 (run make install-lib install-support, run ranlib manually, as requested) -Use the script ./install.macos to configure/compile/install ODIN Troubleshooting: ================ * During compilation I get a message '/usr/bin/moc: commamd not found' -> You must specify the directory where the Qt library is installed by setting the $QTDIR system variable, i.e. the headers should be found under $QTDIR/include, the libs under $QTDIR/lib and, most important for this problem the binaries (for example moc) under $QTDIR/bin. * During configuration I get a message 'configure: error: Can't find ....' or 'Please install ...' -> The configure script knows (mostly) what is needed, please install the missing packages. =============================================================================== And here are the generic installation instructions generated by the GNU autoconf package: Basic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, a file `config.cache' that saves the results of its tests to speed up reconfiguring, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.in' is used to create `configure' by a program called `autoconf'. You only need `configure.in' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes a while. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Type `make install' to install the programs and any data files and documentation. 4. You can remove the program binaries and object files from the source code directory by typing `make clean'. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. You can give `configure' initial values for variables by setting them in the environment. Using a Bourne-compatible shell, you can do that on the command line like this: CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure Or on systems that have the `env' program, you can do it like this: env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not supports the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' can not figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it can not guess the host type, give it the `--host=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name with three fields: CPU-COMPANY-SYSTEM See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are building compiler tools for cross-compiling, you can also use the `--target=TYPE' option to select the type of system they will produce code for and the `--build=TYPE' option to select the type of system on which you are compiling the package. Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Operation Controls ================== `configure' recognizes the following options to control how it operates. `--cache-file=FILE' Use and save the results of the tests in FILE instead of `./config.cache'. Set FILE to `/dev/null' to disable caching, for debugging `configure'. `--help' Print a summary of the options to `configure', and exit. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `--version' Print the version of Autoconf used to generate the `configure' script, and exit. `configure' also accepts some other, not widely useful, options. odin-1.8.5/ChangeLog0000644000175000017500000010145111735132611011153 00000000000000ChangeLog for ODIN Version 1.8.5: -------------- New Features: - Writing of multiple VTK files for dynamic data sets - Storing protocol together with z-maps in miview fMRI - Added dialect 'tcourse' to ASCII fileio - SeqSimMonteCarlo now supports multi-threaded simulation - Added gamma variate fitting function - Added filter steps 'quantilmask' and 'resample' - Filter steps 'minip', 'maxip' and 'proj' now with direction argument - Added option 'weightmask' to micalc - Added reco step 'qcspike' to detect spikes in signal - Added reco steps 'driftcalc/driftcorr' for correction of field drift - Added GSL-based DownhillSimplex optimizer Internal Changes: - Added thread-local storage to ThreadedLoop - Removed usage of liboil - Removed FileIO of Lipsia/Vista - Rewrote filter_splice - Adapted to libpng 1.5.x - New implementation of unwrap_phase() function with variable startindex Version 1.8.4: -------------- New Features: - Calculating reductions (maximum, minimum and sum projection) by one filter step - Added write option 'fnamepar' to create file names of datasets based on arbitrary protocol parameters - Added parameter to weight phase by exponent of magnitude when combining multi-channel data - Added filter 'automask' to create mask using histogram-based threshold Internal Changes: - Fixes for DCMTK 3.6.0 - Combination of files with different bit representations in autoread - Using presence of DICOM trigger time to set PhysioTrigger - Accounting for different TRs in gated mode when combining data Version 1.8.3: -------------- New Features: - PhysioTrigger flag in GUI - Partial Fourier acquisition in readout direction - Reordering of phase lists API Changes: - Changed constructors of SeqAcqRead and SeqGradEcho to allow for partial Fourier acquisition in readout direction. Internal Changes: - Now using PREFIX/share/odin to install sequences, samples and coils - Constructors of SeqGradTrapez and SeqAcqRead now account for rastered duration of of constant part - Taking SeqVecIter objects into account when creating recoInfo Version 1.8.2: -------------- New Features: - Read-only display of parameter blocks by a table - Support for time varying samples to simulate fMRI, for instance - (Re-)added SeqMagnReset to reset magnetization in simulation - New FileIO plugin for ODIN measurement protocols API Changes: - Changed parameter order of Sample::resize() - Removed obsolete B1 map in Sample - Sample has extra time dimension (frames) Internal Changes: - Fixed noise generator of MRI simulator Version 1.8.1: -------------- New Features: - 3D phase encoded PROPELLER sequence - Support for diffusion tensor imaging - New parameters for odinreco to fine-tune odinreco of PROPELLER data - Added 3D mode to SeqGradEcho API Changes: - New operators /= for SeqGradChanParallel - Moved set_gradrotmatrixvector() from SeqParallel to SeqObjList Internal Changes: - Using userdef dimension for messer/gesse sequence - Separate functor for phase correction of blades Version 1.8.0: -------------- New Features: - odinprop now possible with ramp sampling - Dialect 'siemens' for DICOM read/write plugins Internal Changes: - Removed scanner-specific drivers from public distribution. Version 1.7.3: -------------- New Features: - Auto-detecting number of cores for odinreco. - Added functor 'fmri' to odinreco (fMRI localizer). - Optimized trapezoidal gradient pulses. - Added filter 'detrend' to remove slow drift over time. - Added filter 'merge' to merge datasets into one. - Added filter 'usemask' to generate 1D array using a mask. - Multi-threaded simulation of MR signal. API Changes: - SeqPulsar::set_rephased() now accepts an optional argument to set the rephaser strength. Internal Changes: - New template class ThreadedLoop for parallelized loops. Version 1.7.2: -------------- New Features: - New sequence 'odinprop' and appropriate reconstruction for PROPPELLER acquisition. Internal Changes: - Auto-generating manpages using 'help2man'. - Added --enable/disable- to configure for 3rd part libraries. Version 1.7.1: -------------- New Features: - Added residual-based robustness filter to GRAPPA reconstruction. - New filter 'align' to register the data of one dataset to the geometry of another. Internal Changes: - Added reverseSlice to Geometry to account for different handness of coordinate system. - Removed sonames of libraries. - Filters now operate on whole maps of protocol-data pairs. Version 1.7.0: -------------- New Features: - Full support for arbitrary oversampling on all platforms. - Added ScanDate and ScanTime members to Study. - New filters for intensity masks (genmask) and slice tiling (tile). - Added SeqHalt for physiological triggering. API Changes: - Parameter for oversampling factor can now be specified in SeqAcq* constructors. - Removed obsolete 'gradshift' from SeqAcqEPI constructor. Internal Changes: - Added configure option --enable-debug, release mode is now the default Version 1.6.9: -------------- New Features: - Added common method SeqFreqChanInterface::set_phasespoiling() for RF spoiling. - Added code for iterative GRAPPA interpolation in two phase encoding directions. - New file formats in FileIO: 3db (Iris3D binary data), png (PNG image), reg (Ansoft HFSS ASCII). API Changes: - Removed obsolete get/set_attenuation() of pulse classes. - Renamed SeqPulsNdim::get/set_wave() -> SeqPulsNdim::get/set_rfwave() and SeqPulsNdim::get/set_Gx/y/z() -> SeqPulsNdim::get/set_gradwave() - Merged enums read/phase/sliceChannel and read/phase/sliceDirection into read/phase/sliceDirection - New member 'methpars' in Protocol to accomodate custom sequence parameters. Internal Changes: - The protocol is now embedded in recoInfo instead of a separate file on disk. - Using Siemens Ice(Configurator) to store raw data on disk. Version 1.6.8: -------------- New Features: - Most of the tracing is now displayed directly in the messages window of Odin instead of the console. API Changes: - Replaced Debug module (in files tjutils/tjdebug*) by Log module (in files tjutils/tjlog*) Internal Changes: - Replaced most of uses of cout/cerr by using new Log module Version 1.6.7: -------------- New Features: - Ported to Siemens IDEA VB15 - odinreco can reconstruct Twix-exported raw data from some Siemens sequences (EPI, FLASH) Internal Changes: - New ostringstream-based debugging framework which now supports standard ostream output to be redirected to the debug object Version 1.6.6: -------------- New Features: - New class SeqGradPhaseEncFlowComp for 1st order flow-compensated phase encoding. - Implemented 3D mode for SeqFieldMap. - New framework for filter steps operating on datasets-protocols pairs in odindata/filter*. Internal Changes: - Added libodinreco in order to support external recos with a custom reader. - Common template base classes for filter and reco steps in odindata/step.*. Version 1.6.5: -------------- New Features: - Support for GNU-Zip compressed files in FileIO, e.g. files ending with nii.gz can be read directly. - Oscilloscope in sequence plotter. - New Mode 'B1' in odinquant and functor b1fit to produce B1 maps. - Added true half fourier reco to odinreco/homodyne.* - Ported to Siemens Numaris4 VB12 API Changes: - JDXyesno renamed to JDXbool. Internal Changes: - Uniform handling of arguments and options of reco steps (functors) via a single set of parameters per step. - Storing and using ReadoutShape instead of RegridMatrix for ramp-sampling correction. - Using MinGW patch so that ODIN can be used on Windows Vista. - Using name 'odindebug' as a uniform name for all local Debug objects. - Renamed SeqMethodInterface/SeqPlatformInterface to SeqMethodProxy/SeqPlatformProxy. - Extra configure option to include/exclude unit test. - New simple list-based memory manager for custom heap. Version 1.6.4: -------------- New Features: - Monte-Carlo simulator 'SeqSimMonteCarlo' to simulate diffusional averaging. Both simulators, 'SeqSimMagsi' and 'SeqSimMonteCarlo', are now accessible via a common interface 'SeqSimAbstract'. - New sequence 'odinswi' and reco functor 'swi' for susceptibilty weighted imaging. - New reco functor 'filter' and 'zerofill' for k-space filtering and zero filling. - Input/output plugin for the Matlab ASCII file format in FileIO module. - Improved Vista input/output plugin which is now compatible with Lipsia. - Improved NIFTI input/output which now supports different data representation types and correctly handles slice orientations. - New LAPACK-based linear algebra functions 'pseudo_inverse' and 'eigenvalues' in odindata/linalg.h. - More filter plugins for JDXfilter API Changes: - Renamed header seqmagn.h to seqsim.h and class 'SeqMagn' to 'SeqSimMagsi'. - Data::convert_to() has more convenient autoscaleOption instead of scale/offset. - New parameter RFSpoiling in commonPars Internal Changes: - Increased efficiency of the tokenizer and STL replacement. - Using liboil when available for array conversion. Version 1.6.3: -------------- New Features: - Direct FT with conjugate-phase reconstruction for spiral imaging. - Yet another optimized spiral trajectory (BoernertSpiral) as described in Boernert et al, MAGMA 9:29-41(1999). - Support for NIFTI file format. Internal Changes: - Collected common code of different spirals into base class ArchimedianSpiral. - Simplified interface to Paravision: A scan can now be started directly from the ODIN GUI. Communication between ODIN and Paravision is now bases solely on pvcmd. Version 1.6.2: -------------- New Features: - Experimental support for VB* on Siemens. - Slice ordering of Sinc and Gauss pulses is now interleaved by default. - Added slice-time correction functor to odinreco. API Changes: - Now, the class SeqAcqEPI has an extra parameter 'reduction' in the constructor to realize GRAPPA encoding directly in the the SeqAcqEPI class in order to combine segmentation and parallel imaging of EPI. Version 1.6.1: -------------- New Features: - Graphical installer to install ODIN on IDEA. - Implemented partial Fourier acquisition: New sequence parameter 'PartialFourier', added support for partial Fourier acquisition in SeqGradPhaseEnc/SeqGradEcho and homodyne reconstruction in odinreco. API Changes: - Overloading SeqMethod::method_reco() to perform method-specific reconstruction is no longer supported. Instead, each method can register a set of functors via RecoPars::set_Recipe() and RecoPars::set_PostProc3D(). Internal Changes: - No longer providing Debian packages because of a bug in Blitz++, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=369753 for details. Version 1.6.0: -------------- New Features: - New multi-threaded pipeline-based reconstruction 'odinreco' which replaces good old 'autoreco' as the image reconstruction framework within ODIN. - Added components for multi-threading in tjutils/tjthread.h. - New class SeqVecIter to iterate manually through vectors (e.g. phaselists). API Changes: - Removed Nyquist correction for EPI in favour of simple 1D phase correction. Internal Changes: - Renamed library for data processing from 'odinreco' to 'odindata'. Version 1.5.1: -------------- New Features: - The FileIO module and the tools based on it (miconv,miview) now support datasets with differing protocols. These protocol-data pairs are now processed simultaneously. They are read from and written to a single file if the file format supports this option (e.g. Vista). - Spiral trajectories with a free parameter can be optimized for minimum readout length using downhill simplex optimization. - Various improvements to spiral reco: Faster k-space gridding, magnitude correction, optional reco by matrix inversion, ... API Changes: - Added ramp steepness as parameter to SeqGradTrapez and SeqAcqEPI. - Restructured FileIO functionality: Instea of separate 'read/write_*_file' functions for each file format, the class Data now has single functions 'autoread/autowrite' to import/export data from different file formats. - The FileIO module now handles lists of protocol-data pairs: Data with differing protocols can be read in and written out simultaneously. - New gridding and coodinate transform functors 'Gridding' and 'CoordTransformation' which are nitialized once and can be applied multiple times. Internal Changes: - Using fast(!) LAPACK routines for SVD instead of those of GSL if LAPACK is available. Version 1.5.0: -------------- New Features: - Added new sequence parameter GradientIntro which will automatically generate a 'tok tok tok' sound prior to the actual sequence if activated. - New encodind scheme 'maxDistEncoding' which creates max distance between consecutive elements of a vector, e.g. for multi-slice excitation with minimum overlap. - New class 'Study' and sub-object 'study' in class 'Protocol' to hold info about current study, i.e. patient info, study name, etc. - Fully standard-compliant DICOM export. - To allow off-center FOV in read direction, oversampling will now be used to create a shift in autoreco before the FOV-band filter is applied. Internal Changes: - Migrated to subversion source code control - Renamed internal interface classes of sequence objects from Abstract to Interface - All Seq*Interface now implement automatic marshalling of virtual functions if a marshall is specified with set_marshall(). - Restructured type interface for amd64 bit compatability: Possible integer types are now s8bit, u8bit, s16bit, u16bit, s32bit, u32bit and will be mapped to the appropriate C types during './configure'. Version 1.4.3: -------------- API Changes: - Argument for direction of ComplexData::fft(...) changed to bool value - The function do_autoreco() is obsolete, autoreco is always performed prior to calling sequence-specific method_reco(). New Features: - Added SeqPulsar::get_reph_gradintegral() to obtain rephasing integrals without creating a new gradient object. - Ported ODIN to Windows using MinGW. Internal Changes: - Using GSL FFT instead of FFTW -> No more FFTW dependency Version 1.4.2: -------------- API Changes: - Removed obsolete flag 'templateScan' from constructor of SeqAcqEPI New Features: - Added optimization code for RF pulses - New constructor flag 'rephase' for SeqAcqDeph to create post-acquisition rephasing gradients. Internal Changes: - Many bug fixes Version 1.4.1: -------------- API Changes: - Memory mapping of complex raw data has changed: The block can be reshaped at each load_block. New Features: - The EPI module now supports multiple echoes for each line in k-space. This is useful for field-map scans. - Added EPI-based module for field-map pre-scan to odinspir sequence. Internal Changes: - Better integration into the Paravision PVM framework. - Tagging of dimensions for reco is now performed mainly in autoreco for better performance. Version 1.4.0: -------------- New Features: - Added support for multi-shot (segmented) EPI. - Parallel imaging using GRAPPA. A new parameter 'ReductionFactor' can be used to specify an acceleration factor and the class 'SeqGradPhaseEnc' is able to create undersampled phase encoding with auto-calibration lines. - Embedded 1D plots (e.g. in Pulsar) can be detached by an entry in their context menu. API Changes: - The sub-elements of the Protocol class (system, geometry and seqpars) are no longer pointers, but actual objects. - All 'set_*_vector' member functions of SeqAcqAbstract derived classes are now replaced by a single function 'set_reco_vector' which takes the desired dimension as its first argument via a 'recoDim' parameter. - The simple macro ODINMETHOD_ENTRY_POINT is now used in every sequence file/module instead of the old ODINMAIN function code. - Changed constructor of SeqAcqEPI to support multi-shot (segmented) EPI - Changed constructor of 2D SeqGradEcho: More convenient constructor with matrix sizes and FOVs instead of gradient strengths. - Changed constructor of 'SeqGradPhaseEnc' to support parallel imaging. - Removed property digitizerMode from the API, i.e. from all constructors of SeqAcq* objects. Internal Changes: - Removed tjview - Using PVM instead of IMND interface on Paravision/Bruker. - Various changes to use optimum filter/digitizer settings on Paravision/Bruker. Version 1.3.2: -------------- New Features: - Added scale to all 2D plots Internal Changes: - Unit test of components is now handled by UnitTest and derived classes - Fixed broken Debian package. Version 1.3.1: -------------- API Changes: - Argument to get/set_spatial_offset of OdinPulse/SeqPulsarPinWheel is now channelNo enum instead of axis enum. - Moved image.h/image.cpp from odinreco to odinpara lib. - Renamed SeqRotMatrix to RotMatrix - The argument to set_gradrotmatrix() is now RotMatrix, instead of a 3x3 float array - Renamed set_mode/get_mode of JDX classes to set_compat_mode/get_compat_mode - The default compatability mode of parameters is now 'notBroken' instead of 'bruker' - The pre-defined frequency list 'pl90' is obsolete, use 'set_phase(90.0)' instead. New Features: - Multiple test cases are now supported for each sequence to cover more use cases during sequence test. - ODIN image file format now contains additional information about the slice geometry. - Added new program 'miview' which will eventually replace the good old, but messy 'tjview' - It is now possible to display images as color map in tjview/miview via the '-color' command-line option. - Any ImageSet (image.jdx) can be used as a background in geoedit Internal Changes: - Ported to Qt4 and Qwt5 - Ported to MacOS - The class name of a sequences/methods is now set by the define METHOD_CLASS in the method code to change the class name dynamically, which is required on MacOS. - Improved DICOM im/export - Navigator data set is now stored in ImageSet instead of obsolete PilotScan - The global parameter 'EchoTime' is now a vector of doubles internally to support multi-echo sequences. However, in the UI it still appears as a scalar parameter. - The sum immages of autoreco are now produced by averaging complex images instead of image magnitudes for better noise compensation. Version 1.3.0: -------------- API Changes: - Location and name of headers have changed: tjutils/tjdx*.h -> odinpara/jdx* tjutils/tjreco.h -> odinpara/reco.h odinseq/seqgeo.h -> odinpara/geometry.h odinseq/seqsys.h -> odinpara/system.h odinseq/seqpars.h -> odinpara/seqpars.h - Renamed classes: SeqGeo -> Geometry SeqSys -> System SeqReco -> RecoPars - Splitted SeqMagn into two separate classes Sample (in odinpara/sample.h) and SeqMagn (in odinseq/seqmagn.h) to separate the logic of sample properties and magnetization - Changed member functions of PilotScan: Now only one function with an enum 'sliceOrientation' as first argument instead of 3 functions - Constructor and redim functions of tjarray changed: Giving a dim parameter as first arg is no longer necessary, dim is determined from the number of args New Features: - A debugger can be attached to the running or newly started Odin process in order to debug sequences. It can be switched on/off under Preferences->Settings->AttachDebugger - DICOM support added via dcmtk: reading/writing of DICOM files is now possible within the Data class - new input/output functions autoread/autowrite in odinreco/fileio.h which detect the file format automatically according to the file extension - rawcalc/micalc now handles a variety of file formats - tjview is now capable of displaying DICOM files - Added new class Protocol which is used to hold the whole protocol of one experiment - Introduced new cmdline program 'miconv' which replaces the functionality of raw2vista, raw2vtk, vistasplit, etc. The file types are recognized according to file extension - Simulation of MR sequences can now be done via cmdline-action 'simulate' - Started work on drivers for GE (code generator for EPIC), drivers will be compiled in by default - Added write support for MetaImage (mhd) file format to FileIO::autowrite Internal Changes: - New library odinpara which holds JCAMP-DX implementation and parameter classes for the MR protocol (geometry, system, sequence parameters) - Added support for new version (3.x) of FFTW - Removed obsolete intermediate class SeqClassSys Misc: - Windows version of tjview no longer available - The parameters in ODIN user interface are now separated: commonPars and methodPars both have their own widget - The sequence-label prefix is removed from parameter names in commonPars when written to disk (e.g. odinepi_FlipAngle is now simply FlipAngle) - renamed command-line utilities: genphantom -> gensample rawcalc -> micalc Version 1.2.2: -------------- New Features: - rawcalc/micalc: It is now possible to use numbers instead of arrays to perform arithmetics with scalar numbers and arrays - Added RandomDist, a class to calculate random number distributions. - New header 'odinreco/linalg.h' and function 'solve_linear' to solve sets of linear equations using the singular value decomposition of GSL - New function polynomial_fit in header 'odinreco/fitting.h' to fit polynomes at each point of an array - New function transform in header 'odinreco/gridding.h' to perform coordinate transformation of Arrays (i.e. rotation, flipping, scaling, shifting) - Made sequence plotting more convenient: Empty channels are discarded and signal curves are displayed right after simulation - It is now possible to specify coil sensitivities for transmission and acquisition Internal Changes: - Now ComplexData::fft swaps quadrants before and after fftw (to obtain smooth phasemaps in the image) - Automated test of autoreco - Added unit tests for components in odinreco (gridding, fitting, statistics, fft) Version 1.2.1: -------------- New Features: - Improved simulation of intra-voxel dephasing by using intra-voxel magnetization gradients - Added vtk-support (writing 3D files) - New cmdline util raw2vtk to convert raw data to vtk files - Added TrueFISP sequence odinfisp - Improved plotting/printing of sequences: Thicker lines while printing, wheels for y-axes to select y-range - Added indication of x/y position when drawing profiles in tjview - The home page now contains a list of avaiable sequences together with their descritions. This list is automatically generated from the source code files in the sequences dir. Internal Changes: - Fixed resizing/margins of JDX widgets on newer Qt versions - Automated release and test procedure (make release / make test) Version 1.2.0: -------------- API Changes: - replaced value 'paravision1_1' of enum 'odinPlatform' by 'paravision' to indicate support of (hopefully) all Paravision versions. New Features: - Adapted ODIN to Paravision 3 - It is now possible to iterate through a list of flip angles via the set_flipangles() and get_flipangle_vector() functions of SeqPulsAbstract (and its derived classes) - Added horizontal/vertical-only zoom tool to sequence plot - Increased max number of pulses on Paravision from 16 to 32 - Printing of sequence plot is now black on white - Added Settings to sequence plot to select whether axes, grid, markers should be plotted Internal Changes: - Removed Qwt source code -> Qwt widget library has to be installed separately. - Debian Sarge is now the reference platform on Linux. Version 1.1.0: -------------- API Changes: - rewrote fitting framework in odinreco: Better usability with custom model functions via virtual functions instead of template classes New Features: - New class Image to handle image data. Data is stored on disk in compressed JCAMP-DX format. It is produced by 'autoreco' or by 'raw2image' and can be viewed with 'tjview'. - All parameters which are relevant for the measurement (systemInfo, geometryInfo, sequencePars) are now stored together with the raw data in a single file 'protocol'. The old files systemInfo, geometryInfo, and sequencePars are still available. - Added integration.* in odinreco for easy integration of functions using the GSL - New files utils.* in odinreco to hold spezialized utility functions for reconstruction Internal Changes: - Moved platform-specific processing of cmdline options to platform drivers - New class OdinProcess to encapsulate platform-specific process creation/execution - Singletons are now managed by SingletonHandler template class to solve problems with DLLs on windows - New class OdinConf to hold/manage platform-specific configuration options Version 1.0.0: -------------- - small bug fixes - Fixed geometry handling on IDEA - improved geoedit GUI - added Store/Load-Buttons to store ODIN protocols on Paravision - added -s to rels action on Paravision to set parameters via the command line Version 0.9.9: -------------- - cleaned up Paravision interface of ODIN - adaption of ODIN to NUMARIS VA25 - fixed calculation of composite pulses - added calculation of eddy currents to plotting module - added SeqSnapshot sequence object to dump magnetization at a specified point in time during simulation Version 0.9.8: -------------- - bug fixes - moved saturation pulse into separate files seqsat.* - new virtual samples for quality phantom - different modes for geometry: slicepack and 3Dvoxel - new Nyquist correction for EPI scans Version 0.9.7: -------------- - bug fixes Version 0.9.6: -------------- - Refectored magnetization class SeqSimMagn and its simulation. - Implemented new sequence plotting/simulation framework in the ODIN GUI. - Removed obsolete SeqDigitised class and audiofile generation which were formerly used to display sequences. Version 0.9.5: -------------- - Modified tjview so that it can be compiled for Windows - New plotting facility to visualize sequences using a new StandAlone platform and the QwtPlot class - Every platform has now its own systemInfo struct, but the interface does not change: systemInfo-> will be relayed to the particular systemInfo of the current platform. - Refactored reorder vector: SeqVector now contains a pointer to its reordering vector so that every vector class can now be reordered. Version 0.9.4: -------------- - Cleaned up stream replacement and debugging facility - Decreased memory usage of recoInfo structure - Support for multi-channel acquisition (phased-array coils) added - Cleaned up JCAMP-DX implementation - Replaced tjstring by STD_string, which is simply a macro for std::string on platforms with a working STL - Replaced tjcomplex by STD_complex, which is simply a macro for std::complex on platforms with a working STL Version 0.9.3: -------------- - Moved C-standard-header includes into a single new file tjcstd.h - Fixed performance problem when dealing with recoInfo of many-repetition scans Version 0.9.2: -------------- - Added recoInfo data structure to store reconstruction parameters - Added autoreco executable to perform an automatic reconstruction based on recoInfo - Improved STL-replacement: now true doubly linked list, list::sort() and list::unique() implemented - Fully implemented hardware drivers (SeqGradTrapez and SeqGradChanParallel) Version 0.9.1: -------------- - Implemented hardware drivers by pure virtual driver base classes and their derivations for each platform - Removed obsolete class SeqGradObjList and SeqGradObjLoop Version 0.9.0: -------------- - Added User Manual for ODIN user interface - Now using Qwt for plotting 1D-graphs - Improved handling of different nuclei, fixed decoupling class - Added interpolation function to Data class Version 0.8.4: -------------- - Improved ODIN user interface - Even more bug fixes Version 0.8.3: -------------- - Bug fixes! Version 0.8.2: -------------- - Improved release generation Version 0.8.1: -------------- - Bug fixes - Improved fMRI analysis in tjview Version 0.8.0: -------------- - Restructured source code tree - compilation for IDEA now uses autoconf/automake - new library odinreco instead of recopp_blitz Version 0.7.1: -------------- - improved ODIN GUI: k-space display, etc. - rewrote framework for JDXfunctions for minimal memory usage - accelerated performance in the Siemens enviroment - SeqRotMatrixVector now coupled to SeqParallel to be used with IDEA - Started spiral sequence Version 0.7.0: -------------- - ODIN now contains a nice GUI for interactive sequence design - complete rewrite of audio file generation Version 0.6.2: -------------- - Better integration of ODIN into Siemens GUI (TE/TR feedback) - Now using release compilation on Siemens host/mpcu to decrease library size - Added fMRI analysis to tjview Version 0.6.1: -------------- - Added custom memory manager for real time OS to avoid memory leaks - Finished implementation of rotation matrix vector - Reworked EPI implementation: different drivers for different platforms - EPI reco now in separate function Version 0.6.0: -------------- - Improved automatic reconstruction via ICE - Reworked implementation of reordering schemes for Bruker - Fixed serious bug in frequency list generation Version 0.5.3: -------------- - Reordering schemes introduced - Added code to ODIN that allows automatic reconstruction via the ICE framework - bug fixes Version 0.5.2: -------------- - Improved method interface - bug fixes Version 0.5.1: -------------- - New root classes SeqIdea and SeqParavision added that deal with the different scanner hardware - bug fixes - Partial fourier added to EPI module - Program 'genmakefile' added that creates Makefiles for the methods on different platforms - ICE program added that writes raw data to disk Version 0.5.0: -------------- - ODIN works together with IDEA! - bug fixes - global object 'commonPars' added that contains parameters found in nearly every sequence (TE,TR,..) Version 0.4.9: -------------- - ODIN now compiles with GCC3.2 - Various bug fixes Version 0.4.8: -------------- - Improved Pulsar Version 0.4.6: -------------- - Added ramp sampling for EPI Version 0.4.4: -------------- - Bug fixes for previous version Version 0.4.3: -------------- - Improved manual - Added more stuff for IDEA support Version 0.4.2: -------------- - subsystem for gradient channel handling replaced: gradient channel objects can now be played out asynchroniously - Improved EPI reco - Predefined fat saturation pulse added Version 0.4.1: -------------- - Support for import/export of Vista files added. - Frequency and delay lists for Bruker are now calculated by iterating through the sequence and retrieving their values. - Gradient waveforms and gradient vectors (phase encoding) are now copied to the PARX parameter space via a predefined list of float arrays to minimise IMND compilation. - Predefined sinc and Gauss pulse added. Version 0.4.0: -------------- - Support for IDEA added. ODIN now compiles with VC++ and the VxWorks cross-compiler. - Added a rough but working STL replacement for platforms where STL is broken (VxWorks). - ODIN Homepage improved: Download section now contains binaries for different platforms. - IDE for this release was KDevelop 2.1 Version 0.3.3: -------------- - Various bug fixes - Documentation updated - Composite pulses added to OdinPulse/Pulsar Version 0.3.2: -------------- - Simulation of sequences is now possible by using the 'simulate' option on the command line - Sequences can now be stored as 6 channel AIFF files by using the 'audio' command line switch - The command line switches 'events' and 'tree' for sequences print the events along the time axis or the hierachical sequence tree. - Added variable delay vector SeqDelayVector - renamed method tj_read_d to odingrech (basic gradient echo sequence) Version 0.3.1: -------------- - New debugging framework. Functions are debugged by generating a local Debug object. Additional messages can be emitted by a stream-like syntax. - The sequence library is distributed over a whole bunch of new files - The static members systemInfo and geometryInfo are now pointers due to problems in initialising the libraries when they are loaded - Added new program JdxEdit, an interactive editor for JCAMP-DX files Version 0.3.0: -------------- - Advanced pulses are now managed by a new class OdinPulse which allows adding new pulse shape, trajectory and filter functions via a plug-in style mechanism. - The Pulsar user interface has been completely rewritten to make use of the OdinPulse class and of new mechanism of automatically building a widget from a given JCAMP-DX parameter set. - Simulation of a sequence is now handled by two classes: SeqDigitised represents the digitised RF and gradient waveforms of the sequence and SeqSimMagn holds the magnetisation array. Both are then connected by a simulate function. - The simulation of relaxation effects (T1,T2) were added by Robert Trampel - The following methods are now part of ODIN: -odinmdeft : MDEFT sequence -odinonep : onepulse experiment - IDE for this release was KDevelop 2.1 odin-1.8.5/COPYING0000644000175000017500000004311011322062355010430 00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. odin-1.8.5/odin.nsi0000644000175000017500000000713311322062355011046 00000000000000; Script to generate a distributable Odin package for Windows ; using the Nullsoft installer ; odin.nsi ;-------------------------------- ; The name of the installer Name "Odin" ; The file to write OutFile "odin-VERSION.exe" SetCompressor bzip2 ; The default installation directory ;InstallDir $PROGRAMFILES\Odin InstallDir C:\Odin DirText "IMPORTANT: Please uninstall any previous version of Odin and chose a directory path name WITHOUT space characters for installation!" ;-------------------------------- Function IsUserAdmin Push $R0 Push $R1 Push $R2 ClearErrors UserInfo::GetName IfErrors Win9x Pop $R1 UserInfo::GetAccountType Pop $R2 StrCmp $R2 "Admin" 0 Continue StrCpy $R0 "true" Goto Done Continue: StrCmp $R2 "" Win9x StrCpy $R0 "false" ;MessageBox MB_OK 'User "$R1" is in the "$R2" group' Goto Done Win9x: ;MessageBox MB_OK "Error! This DLL can't run under Windows 9x!" StrCpy $R0 "true" Done: ;MessageBox MB_OK 'User= "$R1" AccountType= "$R2" IsUserAdmin= "$R0"' Pop $R2 Pop $R1 Exch $R0 FunctionEnd ;-------------------------------- ; Registry key to check for directory (so if you install again, it will ; overwrite the old one automatically) InstallDirRegKey HKLM "Software\Odin" "Install_Dir" ;-------------------------------- ; Pages Page components Page directory Page instfiles UninstPage uninstConfirm UninstPage instfiles ;-------------------------------- Section "" Call IsUserAdmin Pop $R0 ; at this point $R0 is "true" or "false" StrCmp $R0 "false" 0 +3 MessageBox MB_OK|MB_ICONEXCLAMATION "Please install with Administrator rights." Quit SectionEnd ;-------------------------------- ; The stuff to install Section "Odin (required)" SectionIn RO ; Set output path to the installation directory. SetOutPath $INSTDIR ; Put file there File /r "bin" File /r "include" File /r "lib" File /r "share" File /r "src" File /r "mingw32" File /r "msys" ; Write the installation path into the registry WriteRegStr HKLM SOFTWARE\Odin "Install_Dir" "$INSTDIR" ; Write the uninstall keys for Windows WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Odin" "DisplayName" "NSIS Odin" WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Odin" "UninstallString" '"$INSTDIR\uninstall.exe"' WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Odin" "NoModify" 1 WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Odin" "NoRepair" 1 WriteUninstaller "uninstall.exe" SectionEnd ; Optional section (can be disabled by the user) Section "Start Menu Shortcuts" CreateDirectory "$SMPROGRAMS\Odin" CreateShortCut "$SMPROGRAMS\Odin\Uninstall.lnk" "$INSTDIR\uninstall.exe" CreateShortCut "$SMPROGRAMS\Odin\Odin.lnk" "$INSTDIR\bin\odin.exe" CreateShortCut "$SMPROGRAMS\Odin\Pulsar.lnk" "$INSTDIR\bin\pulsar.exe" ; CreateShortCut "$SMPROGRAMS\Odin\MiView.lnk" "$INSTDIR\bin\miview.exe" ; CreateShortCut "$SMPROGRAMS\Odin\GeoEdit.lnk" "$INSTDIR\bin\geoedit.exe" CreateShortCut "$SMPROGRAMS\Odin\Manual.lnk" "$INSTDIR\share\doc\odin\manual\html\index.html" CreateShortCut "$SMPROGRAMS\Odin\Shell.lnk" "$INSTDIR\bin\shell.bat" "$INSTDIR" SectionEnd ;-------------------------------- ; Uninstaller Section "Uninstall" ; Remove registry keys DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Odin" DeleteRegKey HKLM SOFTWARE\Odin ; Remove files and uninstaller Delete "$INSTDIR\*.*" RMDir /r "$INSTDIR\*" ; Remove shortcuts, if any Delete "$SMPROGRAMS\Odin\*.*" ; Remove directories used RMDir "$SMPROGRAMS\Odin" RMDir "$INSTDIR" SectionEnd odin-1.8.5/odindata/0000755000175000017500000000000011735135551011250 500000000000000odin-1.8.5/odindata/filter_shift.h0000644000175000017500000000263011322062337014015 00000000000000/*************************************************************************** filter_shift.h - description ------------------- begin : Fri Nov 21 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_SHIFT_H #define FILTER_SHIFT_H #include class FilterShift : public FilterStep { JDXfloat shift[n_directions]; STD_string label() const {return "shift";} STD_string description() const {return "Shift data spatially";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterShift();} void init(); }; #endif odin-1.8.5/odindata/filter_reduction.cpp0000644000175000017500000000003611665172216015235 00000000000000#include "filter_reduction.h" odin-1.8.5/odindata/complexdata.h0000644000175000017500000002672111734622163013651 00000000000000/*************************************************************************** complexdata.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen & Michael von Mengershausen email : jochimse@cns.mpg.de mengers@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef COMPLEXDATA_H #define COMPLEXDATA_H #include #include /** * @addtogroup odindata * @{ */ /////////////////////////////////////////////////////// /** * This template class holds multidimensional complex data, most suitable for NMR signal. * In addition to functionality provided by the Data Array class, * it offers advanced numerical routines (FFT) and block-wise * processing of large data files. */ template class ComplexData : public Data { public: /** * Default constructor */ ComplexData() {} /** * Constructs a complex array with the given dimensionality */ ComplexData(const TinyVector& dimvec, const STD_complex& val=0) : Data(dimvec) {(*this)=val;} /** * Constructor with a variable list of arguments to specify the extend * in each dimension, the number of args must match N_rank */ // resolve ambiguities due to other constructors ComplexData(int extent1) : Data(extent1) {} ComplexData(int extent1, int extent2) : Data(extent1,extent2) {} ComplexData(int extent1, int extent2,int extent3) : Data(extent1,extent2,extent3) {} ComplexData(int extent1, int extent2,int extent3,int extent4) : Data(extent1,extent2,extent3,extent4) {} ComplexData(int extent1, int extent2,int extent3,int extent4,int extent5) : Data(extent1,extent2,extent3,extent4,extent5) {} ComplexData(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6) : Data(extent1,extent2,extent3,extent4,extent5,extent6) {} ComplexData(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7) : Data(extent1,extent2,extent3,extent4,extent5,extent6,extent7) {} ComplexData(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8) : Data(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8) {} ComplexData(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8,int extent9) : Data(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8,extent9) {} /** * Copy constructor */ ComplexData(const ComplexData& cd) : Data(cd) {} /** * Copy constructor from Data */ ComplexData(const Data& a) : Data(a) {} /** * Assignment operator */ ComplexData& operator = (const ComplexData& d) {Data::operator=(d); return *this;} /** * Assignment operator from Blitz::Array */ ComplexData& operator = (const Array& a) {Array::operator=(a); return *this;} /** * Fills all elements with 'val' */ ComplexData& operator = (const STD_complex& val) {Data::operator=(val); return *this;} /** * Assignment operator for expression templates */ template inline ComplexData& operator = (BZ_ETPARM(_bz_ArrayExpr) expr) { typedef _bz_typename T_expr::T_numtype T_numtype; evaluate(expr, _bz_update()); return *this; } /** * Element-wise + operator for 2 arrays */ Array operator + (const ComplexData& b) const { return Array(Array(*this)+Array(b)); } /** * Element-wise - operator for 2 arrays */ Array operator - (const ComplexData& b) const { return Array(Array(*this)-Array(b)); } /** * Element-wise * operator for 2 arrays */ Array operator * (const ComplexData& b) const { return Array(Array(*this)*Array(b)); } /** * Element-wise / operator for 2 arrays */ Array operator / (const ComplexData& b) const { return Array(Array(*this)/Array(b)); } /** * Performs an in-place FFT with the following properties: * - forward: Whether to do a forward (true) or backward (false) FFT * - cyclic_shift: Whether to shift data cyclically so that zero frequency * is in the middle of the array after FFT */ void fft(bool forward=true, bool cyclic_shift=true); /** * Performs an in-place FFT over a partial number of dimensions with the following properties: * - do_fft: A vector where the index should be set to 'true' if the FFT should be performed for the corresponding dimension * - forward: Whether to do a forward (true) or backward (false) FFT * - cyclic_shift: Whether to shift data cyclically so that zero frequency * is in the middle of the array after FFT */ void partial_fft(const TinyVector& do_fft, bool forward=true, bool cyclic_shift=true); /** * Modulate a phase gradient onto the array so that after FFT, the data will be shifted * in each dimension by 'rel_offset' which is given as a fraction relative to the full size, * i.e. a value of 0.5 shifts the array by half its size. * */ void modulate_offset(const TinyVector& rel_offset); /** * Shift the data by the number of pixels given in 'shiftvec' for each dimension using the FFT, * i.e. this is possible even with fractions. */ void shift_subpixel(const TinyVector& shiftvec); /** * Returns the phase of the complex array, whereby the phase is unwrapped in the last dimension */ Data phasemap() const; }; /** @} */ /////////////////////////////////////////////////////// template void ComplexData::fft(bool forward, bool cyclic_shift) { Log odinlog("ComplexData","fft"); TinyVector do_fft=true; ComplexData::partial_fft(do_fft, forward, cyclic_shift); } /////////////////////////////////////////////////////// // call FFT of GSL struct GslFftWorkSpace; // forward declaration class GslFft { public: GslFft(int length); ~GslFft(); void fft1d(double* complex_data, bool forward_fft); private: GslFftWorkSpace* ws; }; /////////////////////////////////////////////////////// template void ComplexData::partial_fft(const TinyVector& do_fft, bool forward, bool cyclic_shift) { Log odinlog("ComplexData","partial_fft"); TinyVector myshape(Array::shape()); TinyVector cyclshift=(ComplexData::shape())/2; // Shift (back) prior to FFT to get flat phasemap if(cyclic_shift) { for(int irank=0; irank::shift(irank,-cyclshift(irank)); } } TinyVector indexvec; for(int irank=0; irank ortho_shape(myshape); ortho_shape(irank)=1; int oneline_size=myshape(irank); double *complex_data= new double[2*oneline_size]; GslFft gslfft(oneline_size); // The total number of elements in the orthogonal subspace unsigned long n_ortho=product(ortho_shape); ODINLOG(odinlog,normalDebug) << "oneline_size/irank/n_ortho=" << oneline_size << "/" << irank << "/" << n_ortho << STD_endl; for(unsigned long iortho=0; iortho(ortho_shape,iortho); for(int j=0; j index; for(int i=0; i::numElements(); i++) { index=Data::create_index(i); (*this)(index)*=exp(float2imag(-2.0*PII*sum(rel_offset*index))); } } /////////////////////////////////////////////////////// template void ComplexData::shift_subpixel(const TinyVector& shiftvec) { fft(true); unsigned int totalsize=Array::numElements(); TinyVector index; for(unsigned int i=0; i::create_index(i); float im=0.0; for(int idim=0; idim::extent(idim)); } STD_complex phase(0,im); (*this)(index)*=exp(phase); } fft(false); } /////////////////////////////////////////////////////// template Data ComplexData::phasemap() const { Range all=Range::all(); const ComplexData& indata=*this; TinyVector myshape(indata.shape()); Data result(myshape); TinyVector ortho_shape(myshape); ortho_shape(N_rank-1)=1; int nlast=myshape(N_rank-1); Data phasevec(nlast); Data unwrapped(nlast); TinyVector indexvec; for(int iortho=0; iortho(ortho_shape,iortho); int ilast; for(ilast=0; ilast& data, Protocol& prot) const { data=where(Array(data)(data)); return true; } /////////////////////////////////////////////////// void FilterMax::init(){ thresh.set_description("Maximum value"); append_arg(thresh,"thresh"); } bool FilterMax::process(Data& data, Protocol& prot) const { data=where(Array(data)>thresh, float(thresh), Array(data)); return true; } /////////////////////////////////////////////////// void FilterType::init(){ type.set_description("Datatype"); append_arg(type,"type"); } float FilterType::getThresh(bool upper)const{ if( IS_TYPE( u8bit,type)) return upper ? std::numeric_limits::max(): std::numeric_limits::min(); else if(IS_TYPE( s8bit,type)) return upper ? std::numeric_limits::max(): std::numeric_limits::min(); else if(IS_TYPE(u16bit,type)) return upper ? std::numeric_limits::max():std::numeric_limits::min(); else if(IS_TYPE(s16bit,type)) return upper ? std::numeric_limits::max():std::numeric_limits::min(); else if(IS_TYPE(u32bit,type)) return upper ? std::numeric_limits::max():std::numeric_limits::min(); else if(IS_TYPE(s32bit,type)) return upper ? std::numeric_limits::max():std::numeric_limits::min(); else if(IS_TYPE(float,type)) return upper ? std::numeric_limits::max(): std::numeric_limits::min(); else if(IS_TYPE(double,type)) return upper ? std::numeric_limits::max():std::numeric_limits::min(); return 0.0; } bool FilterTypeMax::process(Data& data, Protocol& prot) const { float thresh=getThresh(true); data=where(Array(data)>thresh, thresh, Array(data)); return true; } bool FilterTypeMin::process(Data& data, Protocol& prot) const { float thresh=getThresh(false); data=where(Array(data)(data)); return true; } odin-1.8.5/odindata/fileio_raw.cpp0000644000175000017500000000624511322062337014014 00000000000000#include "fileio.h" #include "complexdata.h" ////////////////////////////////////////////////////////////// template struct RawFormat : public FileFormat { STD_string description() const { STD_string descr=TypeTraits::type2label((T)0); if(descr.find("bit")!=STD_string::npos) { descr=replaceStr(descr, "s", "signed "); descr=replaceStr(descr, "u", "unsigned "); descr=replaceStr(descr, "bit", " bit"); } descr+=" raw data"; return descr; } svector suffix() const { svector result; result.resize(1); result[0]=TypeTraits::type2label((T)0); return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("RawFormat","read"); TinyVector newshape; newshape=1; unsigned long typesize=sizeof(T); if( int(opts.cplx)>0 ) typesize*=2; int fsize=filesize(filename.c_str())-opts.skip; newshape(0)=prot.seqpars.get_NumOfRepetitions(); newshape(3)=prot.seqpars.get_MatrixSize(readDirection); newshape(2)=prot.seqpars.get_MatrixSize(phaseDirection); newshape(1)=(unsigned int)secureDivision(fsize,typesize*product(newshape)); ODINLOG(odinlog,normalDebug) << "fsize/typesize/newshape(1)=" << fsize << "/" << typesize << "/" << newshape(1) << STD_endl; if(!product(newshape)) { ODINLOG(odinlog,errorLog) << "wrong size: " << newshape << STD_endl; return -1; } data.resize(newshape); if(int(opts.cplx)>0 ) { ComplexData<4> data_cplx(newshape); if(data_cplx.Data::read(filename,opts.skip)<0) return -1; // extra scop for MinGW if(opts.cplx=="abs") data=cabs(data_cplx); if(opts.cplx=="pha") data=phase(data_cplx); if(opts.cplx=="real") data=creal(data_cplx); if(opts.cplx=="imag") data=cimag(data_cplx); } else { prot.system.set_data_type(TypeTraits::type2label((T)0)); if(data.Data::read(filename,opts.skip)<0) return -1; // extra scop for MinGW } return data.extent(0)*data.extent(1); } int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { autoscaleOption scaleopt=autoscale; const STD_string type(prot.system.get_data_type()); if(type!="float" && type!="double")scaleopt=noupscale; if(opts.append) { Data data_copy; data.Data::convert_to(data_copy,scaleopt); return data_copy.write(filename,appendMode); } else return data.Data::write(filename,scaleopt); } }; ////////////////////////////////////////////////////////////// void register_raw_format() { static RawFormat s8f; static RawFormat u8f; static RawFormat s16f; static RawFormat u16f; static RawFormat s32f; static RawFormat u32f; static RawFormat floatf; static RawFormat doublef; s8f.register_format(); u8f.register_format(); s16f.register_format(); u16f.register_format(); s32f.register_format(); u32f.register_format(); floatf.register_format(); doublef.register_format(); } odin-1.8.5/odindata/step_code.h0000644000175000017500000001273611322062337013310 00000000000000#include template T* Step::clone() const { T* result=allocate(); result->init(); result->args.copy_ldr_vals(args); return result; } template void Step::set_args(const STD_string& argstr) { Log odinlog(c_label(),"set_args"); unsigned int nargs=args.numof_pars(); if(!nargs) return; // Just a flag svector toks(tokens(argstr,',','(',')')); for(unsigned int i=0; i STD_string Step::args_description() const { int nargs=args.numof_pars(); STD_string result; for(int i=0; i void Step::append_opts(JcampDxBlock& parblock) { parblock.merge(args); } template void Step::append_arg(JcampDxClass& arg, const STD_string& arglabel) { arg.set_label(label()+"_"+arglabel); args.append(arg); } /////////////////////////////////////////////////////////////////////////////////// template StepFactory::StepFactory(JcampDxBlock* parblock) { STD_list steplist; T::create_templates(steplist); for(typename STD_list::const_iterator it=steplist.begin(); it!=steplist.end(); ++it) { T* p=(*it); p->init(); if(parblock) p->append_opts(*parblock); templates[p->label()]=p; } } template StepFactory::~StepFactory() { for(typename StepMap::iterator it=templates.begin(); it!=templates.end(); ++it) delete it->second; for(typename STD_list::iterator it=garbage.begin(); it!=garbage.end(); ++it) delete (*it); } template T* StepFactory::create(const STD_string& label) const { Log odinlog("StepFactory","create"); T* result=0; typename StepMap::const_iterator it=templates.find(label); if(it!=templates.end()) { result=it->second->clone(); } else { ODINLOG(odinlog,errorLog) << "Step with label >" << label << "< not found" << STD_endl; return 0; } garbage.push_back(result); return result; } // Helper class for managing step entries in the manual struct StepDoc { STD_string label; STD_string description; STD_string in; STD_string out; STD_string options; }; template STD_string StepFactory::manual() const { STD_string result; STD_map > strmap; for(typename StepMap::const_iterator it=templates.begin(); it!=templates.end(); ++it) { const char* classtype=typeid(*(it->second)).name(); while( (*classtype) >='0' && (*classtype) <='9' ) classtype++; // strip off leading numbers (GCC) STD_string classname(classtype); classname=rmblock(classname,"IL",""); // strip off template parameters (GCC) StepDoc doc; doc.label=it->first; doc.description=it->second->description(); T::interface_description(it->second, doc.in, doc.out); JcampDxBlock parblock; it->second->append_opts(parblock); int nargs=parblock.numof_pars(); for(int i=0; i >::const_iterator it=strmap.begin(); it!=strmap.end(); ++it) { result+="/**\n"; result+=" * \\class "+it->first+"\n"; STD_string labels; STD_string descr; // assume the same for all for(STD_list::const_iterator docit=it->second.begin(); docit!=it->second.end(); ++docit) { if(labels!="") labels+=", "; labels+="\\b "+docit->label; descr=docit->description; } result+=" * \\brief "+labels+": "+descr+"\n\n"; for(STD_list::const_iterator docit=it->second.begin(); docit!=it->second.end(); ++docit) { result+=" * Functor label: \\b "+docit->label+"\n\n"; if(docit->in!="" || docit->out!="") { result+=" * Interface of \\b "+docit->label+":\n"; result+=" * - input: "+docit->in+"\n"; result+=" * - output: "+docit->out+"\n"; } result+=" *\n"; result+=" *\n"; if(docit->options!="") { result+=" * Options of \\b "+docit->label+":\n"; result+=" * \\verbatim \n"; result+=docit->options; result+=" \\endverbatim \n\n"; } } result+=" */\n\n"; } result+="/** @}\n"; result+=" */\n"; return result; } template STD_string StepFactory::get_cmdline_usage(const STD_string& lineprefix)const{ STD_string ret; for(typename StepMap::const_iterator it=templates.begin(); it!=templates.end(); ++it) { const T* st=it->second; ret += lineprefix+"-"+st->label(); STD_string argsdescr=st->args_description(); if(argsdescr!="") ret += " <"+argsdescr+">"; ret += " : "+st->description()+"\n"; } return ret; } odin-1.8.5/odindata/filter_merge.h0000644000175000017500000000264211322062337014002 00000000000000/*************************************************************************** filter_merge.h - description ------------------- begin : Mon May 25 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_MERGE_H #define FILTER_MERGE_H #include class FilterMerge: public FilterStep { STD_string label() const {return "merge";} STD_string description() const {return "Merge datasets into a single dataset by expanding the time dimension";} bool process(FileIO::ProtocolDataMap& pdmap) const; FilterStep* allocate() const {return new FilterMerge();} void init() {} }; #endif odin-1.8.5/odindata/data.cpp0000644000175000017500000003375211734622163012616 00000000000000#include "data.h" #include "fileio.h" #include "utils.h" #include ////////////////////////////////////////////////// int fileio_autowrite(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol* prot) { FileIO::ProtocolDataMap pdmap; if(prot) { pdmap[*prot].reference(data); } else { Protocol prot; // set extensions in the protocol prot.seqpars.set_NumOfRepetitions(data.extent(0)); prot.geometry.set_nSlices(data.extent(1)); prot.seqpars.set_MatrixSize(phaseDirection,data.extent(2)); prot.seqpars.set_MatrixSize(readDirection,data.extent(3)); pdmap[prot].reference(data); } return FileIO::autowrite(pdmap, filename, opts); } int fileio_autoread(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol* prot, ProgressMeter* progmeter) { Log odinlog("","fileio_autoread"); FileIO::ProtocolDataMap pdmap; ODINLOG(odinlog,normalDebug) << "data/filename/prot=" << data.shape() << "/" << filename << "/" << prot << STD_endl; Protocol protocol_template; // set defaults for reading raw data protocol_template.seqpars.set_MatrixSize(readDirection,1); protocol_template.seqpars.set_MatrixSize(phaseDirection,1); protocol_template.seqpars.set_MatrixSize(sliceDirection,1); if(prot) protocol_template=(*prot); int result=FileIO::autoread(pdmap, filename, opts, protocol_template, progmeter); if(result<0) return -1; FileIO::ProtocolDataMap::const_iterator it=pdmap.begin(); if(it!=pdmap.end()) { if(prot) (*prot)=it->first; data.reference(it->second); } else { ODINLOG(odinlog,errorLog) << "Empty protocol-data map" << STD_endl; return -1; } return result; } ////////////////////////////////////////////////// // Unit Test #ifndef NO_UNIT_TEST class DataTest : public UnitTest { public: DataTest() : UnitTest("Data") {} private: template bool conversion_test(const Data& testarray) const { Log odinlog(this,"conversion_test"); Data dst; testarray.convert_to(dst); STD_string prefix=STD_string("convert_to<")+TypeTraits::type2label((Type)0)+","+itos(Rank)+"> failed, "; TinyVector expected_shape; expected_shape=1; expected_shape(Rank-1)*=testarray.extent(1); expected_shape(STD_max(0,Rank-2))*=testarray.extent(0); if(expected_shape!=dst.shape()) { ODINLOG(odinlog,errorLog) << prefix << "wrong shape=" << dst.shape() << ", but expected " << expected_shape << STD_endl; return false; } if(std::numeric_limits::is_integer) { // just check whether numeric range is fully covered for full-scale mode float minnum=std::numeric_limits::min(); float maxnum=std::numeric_limits::max(); float deltanum=maxnum-minnum; float minval=min(dst); float maxval=max(dst); float relmaxdiff_plus=fabs(maxval-maxnum)/deltanum; float relmaxdiff_minus=fabs(minval-minnum)/deltanum; if(relmaxdiff_plus>.02 && relmaxdiff_minus>.02) { ODINLOG(odinlog,errorLog) << prefix << "auto-scale range relmaxdiff=" << relmaxdiff_minus << "/" << relmaxdiff_plus << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } // Convert back to float Data dstfloat; dst.convert_to(dstfloat); minval=min(dstfloat); maxval=max(dstfloat); relmaxdiff_plus=fabs(maxval-maxnum)/deltanum; relmaxdiff_minus=fabs(minval-minnum)/deltanum; if(relmaxdiff_plus>.02 && relmaxdiff_minus>.02) { ODINLOG(odinlog,errorLog) << prefix << "convert-back relmaxdiff=" << relmaxdiff_minus << "/" << relmaxdiff_plus << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } // Test down-scaling separately Data largevals(testarray.copy());largevals(3,3)=minnum-100.0;largevals(2,2)=maxnum+100.0; // Make sure data is out of range of Type largevals.convert_to(dst); minval=min(dst); maxval=max(dst); relmaxdiff_plus=fabs(maxval-maxnum)/deltanum; relmaxdiff_minus=fabs(minval-minnum)/deltanum; if(relmaxdiff_plus>.02 && relmaxdiff_minus>.02) { ODINLOG(odinlog,errorLog) << prefix << "down-scale range relmaxdiff=" << relmaxdiff_minus << "/" << relmaxdiff_plus << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } // Test up-scaling Data smallvals(testarray.copy()); smallvals*=0.001/STD_max(fabs(min(testarray)),fabs(max(testarray))); smallvals.convert_to(dst); minval=min(dst); maxval=max(dst); relmaxdiff_plus=fabs(maxval-maxnum)/deltanum; relmaxdiff_minus=fabs(minval-minnum)/deltanum; if(relmaxdiff_plus>.02 && deltanum>.02) { ODINLOG(odinlog,errorLog) << prefix << "up-scale range relmaxdiff=" << relmaxdiff_minus << "/" << relmaxdiff_plus << STD_endl; ODINLOG(odinlog,errorLog) << "smallvals=" << smallvals << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } // Test non-upscaled conversion of small numbers smallvals.convert_to(dst,noupscale); minval=min(dst); maxval=max(dst); if(minval || maxval) { // should be zero ODINLOG(odinlog,errorLog) << prefix << "noupscale failed" << STD_endl; ODINLOG(odinlog,errorLog) << "smallvals=" << smallvals << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } // do an additional test without auto-scaling if data is signed if(std::numeric_limits::is_signed) { testarray.convert_to(dst,noscale); float sumdiff=sum(dst)-sum(testarray); if(fabs(sumdiff)>0.1) { ODINLOG(odinlog,errorLog) << prefix << "no-scale sum sumdiff=" << sumdiff << STD_endl; ODINLOG(odinlog,errorLog) << "dst=" << dst << STD_endl; ODINLOG(odinlog,errorLog) << "testarray=" << testarray << STD_endl; return false; } } } else { for(int i=0; i testindex=testarray.create_index(i); TinyVector dstindex=dst.create_index(i); if(testarray(testindex)!=dst(dstindex)) { ODINLOG(odinlog,errorLog) << prefix << "value mismatch at index " << testindex << STD_endl; ODINLOG(odinlog,errorLog) << testarray(testindex) << " != " << dst(dstindex) << STD_endl; return false; } } } return true; } template bool readwrite_mmap_test(const Data& testarray) const { Log odinlog(this,"readwrite_mmap_test"); Data dst; testarray.convert_to(dst); STD_string prefix=STD_string("read/write/mmap<")+TypeTraits::type2label((Type)0)+"> failed, "; STD_string testfname(tempfile()); // Testing (f)write against filemap int testoffset=10000; // bytes Data(testfname, false, testoffset); // Create offset if(dst.write(testfname, appendMode)) { // append to offset ODINLOG(odinlog,errorLog) << prefix << "write(" << testfname <<")" << STD_endl; return false; } Data mmappedarray(testfname, true, testarray.shape(), testoffset); if(!mmappedarray.is_filemapped()) { ODINLOG(odinlog,errorLog) << prefix << "filemap of >" << testfname << "<" << STD_endl; return false; } if(mmappedarray.shape()!=dst.shape()) { ODINLOG(odinlog,errorLog) << prefix << "wrong shape=" << mmappedarray.shape() << ", but expected " << dst.shape() << STD_endl; return false; } for(int i=0; i index=dst.create_index(i); if(mmappedarray(index)!=dst(index)) { ODINLOG(odinlog,errorLog) << prefix << "mmap value mismatch at index " << index << STD_endl; ODINLOG(odinlog,errorLog) << mmappedarray(index) << " != " << dst(index) << STD_endl; return false; } } // Cross-wise testing of template vs. format read/write if(testarray.write(TypeTraits::type2label((Type)0),testfname,autoscale)) { // implicit conversion, use full range of integer ODINLOG(odinlog,errorLog) << prefix << "write(" << TypeTraits::type2label((Type)0) << "," << testfname <<")" << STD_endl; return false; } #if __GNUC__ > 3 // The following gives parse error on earlier GCC versions Data testread(testarray.shape()); testread=0.0; if(testread.read(testfname)) { ODINLOG(odinlog,errorLog) << "read<" << TypeTraits::type2label((Type)0) << ">(" << testfname <<")" << STD_endl; return false; } if(std::numeric_limits::is_integer) { // Check wheter full range was used float minnum=std::numeric_limits::min(); float maxnum=std::numeric_limits::max(); float deltanum=maxnum-minnum; float minval=min(testread); float maxval=max(testread); float relmaxdiff_plus=fabs(maxval-maxnum)/deltanum; float relmaxdiff_minus=fabs(minval-minnum)/deltanum; if(relmaxdiff_plus>.02 && relmaxdiff_minus>.02) { ODINLOG(odinlog,errorLog) << prefix << "read relmaxdiff=" << relmaxdiff_minus << "/" << relmaxdiff_plus << STD_endl; ODINLOG(odinlog,errorLog) << "minval/maxval=" << minval << "/" << maxval << STD_endl; ODINLOG(odinlog,errorLog) << "minnum/maxnum=" << minnum << "/" << maxnum << STD_endl; return false; } } else { if(testarray.shape()!=testread.shape()) { ODINLOG(odinlog,errorLog) << prefix << "shape mismatch: " << testarray.shape() << " != " << testread.shape() << STD_endl; return false; } for(int i=0; i index=testarray.create_index(i); if(testarray(index)!=testread(index)) { ODINLOG(odinlog,errorLog) << prefix << "read/write value mismatch at index " << index << STD_endl; ODINLOG(odinlog,errorLog) << testarray(index) << " != " << testread(index) << STD_endl; return false; } } } #endif return true; } bool check() const { Log odinlog(this,"check"); int testsize=10; Data testarray(testsize,testsize); // checking create_index against create_linear_index, thereby filling testarray TinyVector indexvec; for(int i=0; i testarray_copy(testarray); testarray_copy.makeUnique(); // test cyclical identitiy shift testarray.shift(1,3); float diff=sum(abs(testarray-testarray_copy)); if(!diff) { ODINLOG(odinlog,errorLog) << "shift ineffective, zero diff" << STD_endl; return false; } testarray.shift(1,4); testarray.shift(1,3); diff=sum(abs(testarray-testarray_copy)); if(diff) { ODINLOG(odinlog,errorLog) << "cyclical shift failed, diff=" << diff << STD_endl; return false; } if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; if(!conversion_test(testarray)) return false; // Testing complex conversion and convert_from_ptr() simultaneously Data cmplxarr; testarray.convert_to(cmplxarr); Data testarray2; convert_from_ptr(testarray2, cmplxarr.c_array(), testarray.shape()); diff=sum(testarray-testarray2); if(diff) { ODINLOG(odinlog,errorLog) << "convert_to/from_ptr failed, diff=" << diff << STD_endl; ODINLOG(odinlog,errorLog) << "testarray=" << testarray << STD_endl; ODINLOG(odinlog,errorLog) << "cmplxarr="; for(int i=0; i3) result.z=0.5*sqrt(double(n-3))*log(argument); // http://www.fmrib.ox.ac.uk/~stuart/thesis/chapter_6/section6_4.html } return result; } ///////////////////////////////////////////////////////////////////////// /** * Kendall's rank-correlation between vectors 'x' and 'y' re-implemented from NRC, section 14.6 * */ template correlationResult kendall(const Array& x, const Array& y) { Log odinlog("","kendall"); correlationResult result; if(x.shape()!=y.shape()) { ODINLOG(odinlog,errorLog) << "Shape mismatch" << STD_endl; return result; } int n=x.size(); int nx=0; int ny=0; int diff=0; for(int j=0; j ii=index2extent(x.shape(),i); TinyVector jj=index2extent(x.shape(),j); float dx=x(jj)-x(ii); float dy=y(jj)-y(ii); if(dx) nx++; if(dy) ny++; float dd=dx*dy; if(dd>0.0) diff++; if(dd<0.0) diff--; } } double tau=secureDivision(diff,sqrt(double(nx))*sqrt(double(ny))); result.r=tau; result.z=3.0*tau*sqrt( secureDivision(n*(n-1),2*(2*n+5) ) ); // Eq. 30.4 in Handbook of Parametric and Nonparametric Statistical Procedures return result; } ///////////////////////////////////////////////////////////////////////// /** * Results of an fMRI analysis * */ struct fmriResult { fmriResult() : Sbaseline(0.0), Srest(0.0), Sstim(0.0), rel_diff(0.0), rel_err(0.0) {} /** * Signal during baseline (leading timesteps with zeroes in design file) */ float Sbaseline; /** * Signal during rest */ float Srest; /** * Signal during stimulation */ float Sstim; /** * Relative signal change */ float rel_diff; /** * Error of relative signal change */ float rel_err; }; ///////////////////////////////////////////////////////////////////////// /** * Returns an fMRI analysis of 'timecourse' using 'designvec' * */ fmriResult fmri_eval(const Data& timecourse, const Data& designvec); /** @} */ #endif odin-1.8.5/odindata/filter_nan.cpp0000644000175000017500000000113511322062337014006 00000000000000// // C++ Implementation: filter_nan // // Description: // // // Author: , (C) 2007 // // Copyright: See COPYING file that comes with this distribution // // #include "filter_nan.h" void FilterNaN::init(){ replace=0; replace.set_description("Replacement value"); append_arg(replace,"replace"); } bool FilterNaN::process(Data& data, Protocol& prot)const{ //replace all elements by replace where element does NOT equal itself (which is only true for NaN) data=where(Array(data) == Array(data), Array(data), (float)replace ); return true; } odin-1.8.5/odindata/complexdata.cpp0000644000175000017500000001107011670202076014167 00000000000000#include "complexdata.h" #include #ifdef HAVE_LIBGSL #include struct GslFftWorkSpace { int length_cache; gsl_fft_complex_wavetable* wavetable; gsl_fft_complex_workspace* workspace; }; GslFft::GslFft(int length) : ws(new GslFftWorkSpace) { ws->length_cache=length; ws->wavetable=gsl_fft_complex_wavetable_alloc(length); ws->workspace=gsl_fft_complex_workspace_alloc(length); } GslFft::~GslFft() { gsl_fft_complex_wavetable_free(ws->wavetable); gsl_fft_complex_workspace_free(ws->workspace); delete ws; } void GslFft::fft1d(double* complex_data, bool forward_fft) { if(forward_fft) gsl_fft_complex_forward (complex_data, 1, ws->length_cache, ws->wavetable, ws->workspace); else gsl_fft_complex_backward(complex_data, 1, ws->length_cache, ws->wavetable, ws->workspace); } #else #error "GNU Scientific library is missing!" #endif ////////////////////////////////////////////////// // Unit Test #ifndef NO_UNIT_TEST class ComplexDataTest : public UnitTest { public: ComplexDataTest() : UnitTest("ComplexData") {} private: bool check() const { Log odinlog(this,"check"); int testsize=11; // Use odd number for more thourough testing ComplexData<2> testarray(testsize,testsize); TinyVector index; for(int i=0; i original(testarray); original.makeUnique(); // test FFT by back and forth transform testarray.fft(true); testarray.fft(false); float diff=sum(cabs(testarray-original)); if(diff>1e-4) { // Data(cabs(testarray)).autowrite("testarray.jdx"); // Data(cabs(original)).autowrite("original.jdx"); ODINLOG(odinlog,errorLog) << "FFT test failed, diff=" << diff << STD_endl; return false; } // Test Data::shift against ComplexData::modulate_offset ComplexData<2> shifttest1(original.shape()); shifttest1=original; ComplexData<2> shifttest2(original.shape()); shifttest2=original; int shiftpix=3; shifttest1.shift(0, shiftpix); shifttest2.fft(true); float relshift=float(shiftpix)/float(testsize); shifttest2.modulate_offset(TinyVector(relshift, 0.0)); shifttest2.fft(false); diff=sum(cabs(shifttest1)-cabs(shifttest2)); // take magnitude difference as modulate_offset adds extra phase if(diff>0) { // Data(cabs(shifttest1)).autowrite("shifttest1.jdx"); // Data(cabs(shifttest2)).autowrite("shifttest2.jdx"); ODINLOG(odinlog,errorLog) << "modulate_offset failed, diff=" << diff << STD_endl; return false; } // Test Data::convert_to complex->complex ComplexData<3> data3d; original.convert_to(data3d); ComplexData<2> convtest; data3d.convert_to(convtest); diff=sum(cabs(original-convtest)); if(diff>0.0) { ODINLOG(odinlog,errorLog) << "convert_to(complex->complex) failed, diff=" << diff << STD_endl; ODINLOG(odinlog,errorLog) << "original " << original << STD_endl; ODINLOG(odinlog,errorLog) << "convtest " << convtest << STD_endl; return false; } // Testing convert_to with byte->complex->float int nbytes=4; Data bytedata(nbytes); for(int i=0; i cplxdst; bytedata.convert_to(cplxdst); Data floatdst; cplxdst.convert_to(floatdst); for(int i=0; i& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterResize();} void init(); }; ///////////////////////////////////////////////////////////////////////// class FilterResample : public FilterStep { JDXint newsize; STD_string label() const {return "resample";} STD_string description() const {return "Temporal resize of image data";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterResample();} void init(); }; ///////////////////////////////////////////////////////////////////////// class FilterIsotrop : public FilterStep { JDXfloat size; STD_string label() const {return "isotrop";} STD_string description() const {return "make image voxels isotrop through interpolation (image geometry will not change)";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterIsotrop();} void init(); }; #endif odin-1.8.5/odindata/filter_scale.cpp0000644000175000017500000000051111322062337014316 00000000000000#include "filter_scale.h" void FilterScale::init(){ slope=1.0; slope.set_description("Slope"); append_arg(slope,"slope"); offset=0.0; offset.set_description("Offset"); append_arg(offset,"offset"); } bool FilterScale::process(Data& data, Protocol& prot) const { data=slope*data+offset; return true; } odin-1.8.5/odindata/fileio_hfss.cpp0000644000175000017500000000624711322062337014170 00000000000000#include "fileio.h" #ifndef STREAM_REPLACEMENT struct HFSSFormat : public FileFormat { STD_string description() const {return "Ansoft HFSS ASCII";} svector suffix() const { svector result; result.resize(1); result[0]="reg"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("HFSSFormat","read"); STD_ifstream ifs(filename.c_str()); if(ifs.bad()) { ODINLOG(odinlog,errorLog) << "Cannot open file " << filename << STD_endl; return -1; } // Read header STD_string firstline,secondline; if(!(getline(ifs,firstline) && getline(ifs,secondline)) ) { ODINLOG(odinlog,errorLog) << "Cannot read header" << STD_endl; return -1; } ODINLOG(odinlog,normalDebug) << "firstline=" << firstline << STD_endl; ODINLOG(odinlog,normalDebug) << "secondline=" << secondline << STD_endl; svector dimstrings=tokens(firstline,':'); if(dimstrings.size()!=4) { ODINLOG(odinlog,errorLog) << "Format error in 1st line" << STD_endl; return -1; } svector minstring =tokens(extract(dimstrings[1],"[","]")); svector maxstring =tokens(extract(dimstrings[2],"[","]")); svector gridstring=tokens(extract(dimstrings[3],"[","]")); TinyVector hfss_minpos, hfss_maxpos, hfss_res, hfss_FOV; TinyVector hfss_size; float scale_factor=1000.0; // convert m to mm for(int i=0; i<3; i++) { hfss_res[2-i]=scale_factor*atof(gridstring[i].c_str()); hfss_minpos[2-i]=scale_factor*atof(minstring[i].c_str())-0.5*hfss_res[2-i]; hfss_maxpos[2-i]=scale_factor*atof(maxstring[i].c_str())+0.5*hfss_res[2-i]; hfss_FOV[2-i]=fabs(hfss_maxpos[2-i]-hfss_minpos[2-i]); hfss_size(2-i)=int( hfss_FOV[2-i]/hfss_res[2-i]+0.5); } ODINLOG(odinlog,normalDebug) << "hfss_minpos=" << hfss_minpos << STD_endl; ODINLOG(odinlog,normalDebug) << "hfss_maxpos=" << hfss_maxpos << STD_endl; ODINLOG(odinlog,normalDebug) << "hfss_res=" << hfss_res << STD_endl; ODINLOG(odinlog,normalDebug) << "hfss_FOV=" << hfss_FOV << STD_endl; ODINLOG(odinlog,normalDebug) << "hfss_size=" << hfss_size << STD_endl; // Fill Grid data.resize(1,hfss_size(0),hfss_size(1),hfss_size(2)); data=0.0; TinyVector index; index(0)=0; TinyVector pos; float val; while(ifs >> pos[2] >> pos[1] >> pos[0] >> val) { for(int i=0; i<3; i++) index(1+i)=int((scale_factor*pos[i]-hfss_minpos[i])/hfss_res[i]); data(index)=val; } // Adjust protocol prot.geometry.set_Mode(voxel_3d) .set_FOV(sliceDirection, hfss_FOV[0]) .set_FOV(phaseDirection, hfss_FOV[1]) .set_FOV(readDirection, hfss_FOV[2]) .set_offset(sliceDirection, 0.5*(hfss_minpos[0]+hfss_maxpos[0])) .set_offset(phaseDirection, 0.5*(hfss_minpos[1]+hfss_maxpos[1])) .set_offset(readDirection, 0.5*(hfss_minpos[2]+hfss_maxpos[2])); return hfss_size(0); } }; #endif ////////////////////////////////////////////////////////////// void register_hfss_format() { #ifndef STREAM_REPLACEMENT static HFSSFormat hf; hf.register_format(); #endif } odin-1.8.5/odindata/filter_reslice.cpp0000644000175000017500000001150111322062337014656 00000000000000#include "filter_reslice.h" bool swapdim(Data& data, Geometry& geo,const direction newread,const direction newphase,const direction newslice,const int newread_mult,const int newphase_mult,const int newslice_mult) { Log odinlog("","swapdim"); ODINLOG(odinlog,normalDebug) << "newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl; // Checking input if(newread==newphase || newread==newslice || newphase==newslice) { ODINLOG(odinlog,errorLog) << "Direction used more than once: newread/newphase/newslice=" << newread << "/" << newphase << "/" << newslice << STD_endl; return false; } const dvector vects[n_directions]={geo.get_readVector(),geo.get_phaseVector(),geo.get_sliceVector()}; double fov[n_directions]; //store i,j and k of the image coordinate system in scanner coordinate system ODINLOG(odinlog,normalDebug) << "get_readVector:" << vects[readDirection] << " => " << (vects[newread]*newread_mult).printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_phaseVector:" << vects[phaseDirection] << " => " << (vects[newphase]*newphase_mult).printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_sliceVector:" << vects[sliceDirection] << " => " << (vects[newslice]*newslice_mult).printbody() << STD_endl; //switch to 3d mode (we cannot deal with slice gaps) geo.set_Mode(voxel_3d); //get the size of the image for(direction i=readDirection;i& data, Protocol& prot)const{ direction read,phase,slice; int swap[3]; if(! (selChannel( newslice,slice,swap[0]) && selChannel( newphase,phase,swap[1]) && selChannel(newread,read,swap[2])) ) return false; return swapdim(data,prot.geometry,read,phase,slice,swap[2],swap[1],swap[0]); } bool FilterSwapdim::selChannel(STD_string name, direction &dir, int& sign){ Log odinlog("FilterSwapdim","selChannel"); sign=1; dir=readDirection; bool result=true; if(name.length()>0) { size_t minus=name.find('-'),plus=name.find('+'); if(plus!=STD_string::npos)name.erase(plus,1); else if(minus!=STD_string::npos){ name.erase(minus,1); sign=-1; } if(name[0]=='r')dir=readDirection; else if(name[0] == 'p')dir=phaseDirection; else if(name[0] == 's')dir=sliceDirection; else result=false; } else { result=false; } if(!result) ODINLOG(odinlog,errorLog) << "Error parsing direction string >" << name << "<" << STD_endl; return result; } ///////////////////////////////////////////////////////////////////////////// void FilterReSlice::init(){ orient.add_item("axial",axial); orient.add_item("sagittal",sagittal); orient.add_item("coronal",coronal); orient.set_description("requested orientation"); append_arg(orient,"orientation"); } bool FilterReSlice::process(Data& data, Protocol& prot)const{ sliceOrientation sorient=prot.geometry.get_orientation(); if(sorient==int(orient)) return true; Geometry &geo=prot.geometry; switch(int(orient)) { case axial: if(sorient == sagittal) return swapdim(data,geo,sliceDirection,readDirection,phaseDirection,1,1,1); else if(sorient == coronal) return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,1,-1); break; case sagittal: if(sorient==axial) return swapdim(data,geo,phaseDirection,sliceDirection,readDirection,-1,-1,1); else if(sorient==coronal) return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1); break; case coronal: if(sorient==axial) return swapdim(data,geo,readDirection,sliceDirection,phaseDirection,1,-1,1); else if(sorient==sagittal) return swapdim(data,geo,sliceDirection,phaseDirection,readDirection,-1,1,1); break; } return true; } odin-1.8.5/odindata/fileio_dicom.cpp0000644000175000017500000013030311712547771014324 00000000000000#include "fileio.h" #include "utils.h" #include #ifdef DICOMSUPPORT /////////////////////////////////////////////////////////////////////////// // Because we have 2 config.h files, one from ODIN and one from DCMTK, // Undefine doubly defined before include of DCMTK headers #undef PACKAGE_BUGREPORT #undef PACKAGE_NAME #undef PACKAGE_STRING #undef PACKAGE_TARNAME #undef PACKAGE_VERSION //#include #include #include #include #include #include #include #include #include #include #include // fix for use of possesive 's' across different versions of dcmtk #ifdef DCM_PatientsName #define DCM_PAT_NAME DCM_PatientsName #else #define DCM_PAT_NAME DCM_PatientName #endif #ifdef DCM_PatientsBirthDate #define DCM_PAT_BIRTHDATE DCM_PatientsBirthDate #else #define DCM_PAT_BIRTHDATE DCM_PatientBirthDate #endif #ifdef DCM_PatientsSex #define DCM_PAT_SEX DCM_PatientsSex #else #define DCM_PAT_SEX DCM_PatientSex #endif #ifdef DCM_PatientsWeight #define DCM_PAT_WEIGHT DCM_PatientsWeight #else #define DCM_PAT_WEIGHT DCM_PatientWeight #endif #ifdef DCM_PerformingPhysiciansName #define DCM_PERF_PHYS DCM_PerformingPhysiciansName #else #define DCM_PERF_PHYS DCM_PerformingPhysicianName #endif #ifdef DCM_ReferringPhysiciansName #define DCM_REF_PHYS DCM_ReferringPhysiciansName #else #define DCM_REF_PHYS DCM_ReferringPhysicianName #endif /////////////////////////////////////// enum dicom_field_importance{optional=0,warning,error}; bool check_status(const char* func, const char* call, const OFCondition& status, const dicom_field_importance severity=error) { Log odinlog("DicomFormat","check_status"); if(status.bad()) { logPriority loglevel=noLog; switch(severity){ case optional: loglevel=normalDebug;break; case warning: loglevel=warningLog;break; case error: loglevel=errorLog;break; } ODINLOG(odinlog,loglevel) << func << "(" << call << ")" << ": " << status.text() << STD_endl; return true; } return false; } /////////////////////////////////////// bool check_dict(const char* func) { Log odinlog("DicomFormat",func); if (!dcmDataDict.isDictionaryLoaded()) { ODINLOG(odinlog,errorLog) << "No data dictionary loaded, check environment variable " << DCM_DICT_ENVIRONMENT_VARIABLE << STD_endl; return true; } return false; } /////////////////////////////////////// bool insert_uint16_hack(DcmDataset *dataset, const DcmTagKey &key, u16bit value) { // Hack to insert uint16 numbers on pre-3.5.4 dcmtk versions, code taken from dcmtk forum // the preprocessor directive of the following line does not work with DCMTK 3.6.0 where OFFIS_DCMTK_VERSION_NUMBER is a string //#if OFFIS_DCMTK_VERSION_NUMBER > 353 dataset->putAndInsertUint16(key,value); //#else // DcmElement *us = new DcmUnsignedShort(DcmTag(key, EVR_US)); // if (us != NULL) { // if(check_status("insert_uint16_hack","putUint16",us->putUint16(value))) {return false;} // if(check_status("insert_uint16_hack","insert",dataset->insert(us, OFTrue /*replaceOld*/))) {return false;} // } else return false; //#endif return true; } template void copy(const DiPixel *pix, Data &dst,const TinyVector &shape,int mosaic_mult){ Log odinlog("DicomFormat","copy"); T* src=(T*)pix->getData(); const Range all=Range::all(); if(shape(1)>1) { // Sort Siemens Mosaic data dst.resize(shape); Data indata; TinyVector inshape(mosaic_mult,shape(2),mosaic_mult,shape(3)); convert_from_ptr(indata,src,inshape); for(int n=0; n DST endian(const BASE *b){ DST ret=0; #if __BYTE_ORDER == __LITTLE_ENDIAN for(short i=0;i<(short)sizeof(DST);i++) #elif __BYTE_ORDER == __BIG_ENDIAN for(short i=(short)sizeof(DST)-1;i>=0;i--) #else #error "Sorry your endianess is not supported. What the heck are you comiling on ??" #endif ret+=b[i]< odinlog("DicomFormat","fetch_from_MR_CSA_Header"); svector ret; Uint8 *array; csaHeader->getUint8Array(array); for(STD_string::size_type pos=0;pos<=csaHeader->getLength();){ STD_string dummy((char*)array+pos); STD_string::size_type found=dummy.find(label); if(found==STD_string::npos) { pos+=dummy.length()+1; } else { pos+=found+0x40; //len of the name is 0x20 plus 0x20 "I dont know what the hell this is supposed to be" /*Sint32 &vm=*((Sint32*)array+pos);*/pos+=sizeof(Sint32); /*char *vr=(char*)array+pos;*/pos+=0x4; /*Sint32 syngodt=endian(array+pos);*/pos+=sizeof(Sint32); Sint32 nitems=endian(array+pos);pos+=sizeof(Sint32); if(nitems) { pos+=sizeof(Sint32); //77 Sint32 len=0; for(unsigned short n=0;n(array+pos);pos+=sizeof(Sint32);//the length of this element pos+=3*sizeof(Sint32); //whatever if(!len)continue; const unsigned s=ret.size();ret.resize(s+1); ret[s]=STD_string((char*)array+pos);//store the text if the is some pos+=((len+sizeof(Sint32)-1)/sizeof(Sint32))*sizeof(Sint32);//increment pos by len aligned to sizeof(Sint32) } ODINLOG(odinlog,normalDebug) << "Found \""+label+"\" in CSA header: \"" << ret.printbody() << "\"" << STD_endl; } else { ODINLOG(odinlog,normalDebug) << "Found empty \""+label+"\" in CSA header" << STD_endl; } return ret; } } ODINLOG(odinlog,normalDebug) << "Could not find\""+label+"\" in CSA header: " << STD_endl; return ret; } ////////////////////////////////////////////////////////////// struct DicomFormat : public FileFormat { STD_string description() const {return "DICOM";} svector suffix() const { svector result; result.resize(4); result[0]="dcm"; result[1]="mag"; result[2]="ph"; result[3]="ima"; return result; } svector dialects() const { svector result; result.resize(1); result[0]="siemens"; return result; } int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("DicomFormat","read"); ODINLOG(odinlog,normalDebug) << "filename=" << filename << STD_endl; Range all=Range::all(); const char* func="DicomFormat::read"; if(check_dict(func)) return -1; if(JDXfileName(filename).get_basename()=="DICOMDIR") return 0; // ignore DICOMDIR #ifdef OFLOG_H OFLog::configure(OFLogger::WARN_LOG_LEVEL); // reset logging (in dcmtk 3.6.0 info logging is somehow enabled sometimes) #endif DcmFileFormat fileformat; DcmDataset* dset=0; if(check_status(func,"loadFile",fileformat.loadFile(filename.c_str()))) { ODINLOG(odinlog,errorLog) << "Unable to get dataset" << STD_endl; return -1; } dset=fileformat.getDataset(); if(!dset) { ODINLOG(odinlog,errorLog) << "fileformat.getDataset() failed" << STD_endl; return -1; } DcmElement* csaHeader=0; if(dset->findAndGetElement(DcmTagKey(0x0029,0x1010),csaHeader).good()) { ODINLOG(odinlog,normalDebug) << "found Siemens-specific CSA Header" << STD_endl; /* Uint8* array=0; csaHeader->getUint8Array(array); if(array) { DcmElement* csaData=0; if(dset->findAndGetElement(DcmTagKey(0x7fe1,0x1010),csaData).good()) { ODINLOG(odinlog,infoLog) << "csaData->getLength()=" << csaData->getLength() << STD_endl; STD_string csaHeaderStr((const char*)array, csaHeader->getLength()); STD_cout << csaHeaderStr << STD_endl; } } */ } DicomImage img(dset, EXS_Unknown, CIF_IgnoreModalityTransformation); // apply modality transform manually to get higher floating point accuracy EI_Status status=img.getStatus(); if(status!=EIS_Normal) { const char* errmsg="Unknown Error"; if(status==EIS_NoDataDictionary) errmsg="NoDataDictionary"; if(status==EIS_InvalidDocument) errmsg="InvalidDocument"; if(status==EIS_MissingAttribute) errmsg="MissingAttribute"; if(status==EIS_InvalidValue) errmsg="InvalidValue"; if(status==EIS_NotSupportedValue) errmsg="NotSupportedValue"; if(status==EIS_MemoryFailure) errmsg="MemoryFailure"; if(status==EIS_InvalidImage) errmsg="InvalidImage"; if(status==EIS_OtherError) errmsg="OtherError"; ODINLOG(odinlog,errorLog) << "Unable to load DICOM image " << filename << " - " << errmsg << STD_endl; return -1; } TinyVector shape; shape=1; // default shape(2)=img.getHeight(); shape(3)=img.getWidth(); ODINLOG(odinlog,normalDebug) << "shape=" << shape << STD_endl; OFString valstr; STD_string image_type; if(!check_status(func,"ImageType",dset->findAndGetOFStringArray(DCM_ImageType, valstr),warning)) image_type=valstr.c_str(); ODINLOG(odinlog,normalDebug) << "image_type=" << image_type << STD_endl; // Hack for Siemens Mosaic int mosaic_mult=1; Sint16 mosaic_slices=1; //try to find 0x0019,100a (images per mosaic) if(image_type.find("MOSAIC")!=STD_string::npos) { if(dset->findAndGetSint16(DcmTagKey(0x0019,0x100a),mosaic_slices).good()){ ODINLOG(odinlog,normalDebug) << "Found \"NumberOfImagesInMosaic\" in 0x0019,0x100a: " << mosaic_slices << STD_endl; } else { if(csaHeader) { //othwise find NumberOfImagesInMosaic in Siemens shadow Header 0x0029,0x1010 svector csa_mosaic=fetch_from_MR_CSA_Header(csaHeader,"NumberOfImagesInMosaic"); if(csa_mosaic.size()) { mosaic_slices=atoi(csa_mosaic[0].c_str()); ODINLOG(odinlog,normalDebug) << "Found \"NumberOfImagesInMosaic\" in CSADataInfo: " << mosaic_slices << STD_endl; } } } if(mosaic_slices>1) { mosaic_mult=(int)ceil(sqrt((double)mosaic_slices)); ODINLOG(odinlog,normalDebug) << "mosaic_mult=" << mosaic_mult << STD_endl; ODINLOG(odinlog,normalDebug) << "mosaic_slices=" << mosaic_slices << STD_endl; shape(3)/=mosaic_mult; shape(2)/=mosaic_mult; shape(1)=mosaic_slices; } else { ODINLOG(odinlog,warningLog) << "\"NumberOfImagesInMosaic\" not available. Mosaic won't be split up" << STD_endl; shape(1)=1; } } //Get Diffusion Data Float64 Bvalue; OFCondition foundB=dset->findAndGetFloat64(DCM_DiffusionBValue,Bvalue); //in case someone actually used the right Tag if(foundB.bad() && opts.dialect=="siemens"){//fallback for siemens OFString buff; foundB=dset->findAndGetOFString(DcmTagKey(0x0019,0x100c), buff); Bvalue=atof(buff.c_str()); } //@todo fallback for GE/Philips if(foundB.good()){//we got the b_value JDXtriple bvector(0,0,0,"Diffusion_bVector"); if(Bvalue){ const Float64 *dir;unsigned long count; OFCondition foundD=dset->findAndGetFloat64Array(DCM_DiffusionGradientOrientation,dir,&count); //in case someone actually used the right Tag if(foundD.bad() && opts.dialect=="siemens") foundD=dset->findAndGetFloat64Array( DcmTagKey(0x0019,0x100e),dir,&count);//siemens fallback if(foundD.good()) { for(unsigned long i=0;i" << filename << "<"<< STD_endl; } else ODINLOG(odinlog,warningLog) << "no diffusion direction found in >" << filename << "<"<< STD_endl; } prot.methpars.append_copy(bvector); } //detect pixel datatype and copy pixel data //@todo: Transpose data and geometry in plane according to DCM_InPlanePhaseEncodingDirection if(!img.isMonochrome()){ ODINLOG(odinlog,errorLog) << "only gray value images are supportet"<< STD_endl; return -1; } const DiPixel *pix=img.getInterData(); switch(pix->getRepresentation()){ case EPR_Uint8: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((u8bit)0)); break; case EPR_Uint16: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((u16bit)0)); break; case EPR_Uint32: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((u32bit)0)); break; case EPR_Sint8: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((s8bit)0)); break; case EPR_Sint16: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((s16bit)0)); break; case EPR_Sint32: copy (pix,data,shape,mosaic_mult); prot.system.set_data_type(TypeTraits::type2label((s32bit)0)); break; default: ODINLOG(odinlog,errorLog) << "pixel representation not supportet"<< STD_endl; } #ifdef ODIN_DEBUG double min,max; img.getMinMaxValues(min,max); ODINLOG(odinlog,normalDebug) << "image range is " << min << " - " << max << STD_endl; ODINLOG(odinlog,normalDebug) << "datatype set to " << prot.system.get_data_type() << STD_endl; #endif //ODIN_DEBUG // rescale data, if necessary float intercept=0; float slope=1.0; if(!check_status(func,"RescaleIntercept",dset->findAndGetOFString(DCM_RescaleIntercept, valstr),optional)) { intercept=atof(valstr.c_str()); } if(!check_status(func,"RescaleSlope",dset->findAndGetOFString(DCM_RescaleSlope, valstr),optional)) { slope=atof(valstr.c_str()); } if(intercept!=0.0 || slope!=1.0) { ODINLOG(odinlog,normalDebug) << "rescaling data with intercept/slope=" << intercept << "/" << slope << STD_endl; data=data*slope+intercept; } STD_string unknown="Unknown"; // Date/time stuff STD_string scandate; STD_string scantime; if(!check_status(func,"SeriesDate",dset->findAndGetOFString(DCM_SeriesDate, valstr),warning)) { scandate=valstr.c_str(); } if(!check_status(func,"SeriesTime",dset->findAndGetOFString(DCM_SeriesTime, valstr),warning)) { svector toks=tokens(valstr.c_str(), '.'); if(toks.size()) scantime=toks[0]; } prot.study.set_DateTime(scandate,scantime); // Get patient stuff STD_string pname(unknown); if(!check_status(func,"PatientsName",dset->findAndGetOFString(DCM_PAT_NAME, valstr),warning)) { pname=valstr.c_str(); pname=replaceStr(pname,"^"," "); pname=valstr.c_str(); } STD_string pid(unknown); if(!check_status(func,"PatientID",dset->findAndGetOFString(DCM_PatientID, valstr),warning)) { pid=valstr.c_str(); } STD_string pdbirth(ODIN_DATE_LENGTH,'0'); if(!check_status(func,"PatientsBirthDate",dset->findAndGetOFString(DCM_PAT_BIRTHDATE, valstr),warning)) { pdbirth=valstr.c_str(); } char psex='M'; if(!check_status(func,"PatientsSex",dset->findAndGetOFString(DCM_PAT_SEX, valstr),warning)) { if(valstr.length()) psex=valstr[0]; } float pweight=50.0; if(!check_status(func,"PatientsWeight",dset->findAndGetOFString(DCM_PAT_WEIGHT, valstr),warning)) { if(valstr.length()) pweight=atof(valstr.c_str()); } prot.study.set_Patient(pid, pname, pdbirth, psex, pweight); // Get study stuff STD_string studydescr(unknown); if(!check_status(func,"StudyDescription",dset->findAndGetOFString(DCM_StudyDescription, valstr),warning)) { studydescr=valstr.c_str(); } STD_string physician(unknown); if(!check_status(func,"PerformingPhysiciansName",dset->findAndGetOFString(DCM_PERF_PHYS, valstr),optional)) { physician=valstr.c_str(); } prot.study.set_Context(studydescr,physician); // Get series stuff STD_string seriesdescr(unknown); if(!check_status(func,"SeriesDescription",dset->findAndGetOFString(DCM_SeriesDescription, valstr),warning)) { seriesdescr=valstr.c_str(); } int seriesno=1; if(!check_status(func,"SeriesNumber",dset->findAndGetOFString(DCM_SeriesNumber, valstr),warning)) { seriesno=atoi(valstr.c_str()); } if(opts.dialect=="siemens") { // Quick hack to produce different datasets for different channels on Siemens if(dset->findAndGetOFString(DcmTagKey (0x0051, 0x100f), valstr).good()) { seriesdescr+="_"+STD_string(valstr.c_str()); } } prot.study.set_Series(seriesdescr,seriesno); // get Pixel Spacing and FOV float FOVread=200.0,psize_read; if(!check_status(func,"PixelSpacing(read)",dset->findAndGetOFString(DCM_PixelSpacing, valstr, 0), warning)) { psize_read=atof(valstr.c_str()); FOVread=psize_read*shape(3); prot.geometry.set_FOV(readDirection, FOVread); }else psize_read=FOVread/shape(3); float FOVphase=200.0,psize_phase; if(!check_status(func,"PixelSpacing(phase)",dset->findAndGetOFString(DCM_PixelSpacing, valstr, 1), warning)) { psize_phase=atof(valstr.c_str()); FOVphase=psize_phase*shape(2); prot.geometry.set_FOV(phaseDirection, FOVphase); }else psize_phase=FOVphase/shape(2); // Get the slice orientation, i.e. the vectors of read and phase direction dvector readvec(3); readvec[0]=1.0; dvector phasevec(3); phasevec[1]=1.0; dvector slicevec(3); slicevec[2]=1.0; // The following does not work with dcmtk since we can only access the first 3 elements of ImageOrientationPatient dvector offset(3); offset = -0.5*(FOVread-psize_read)*readvec - 0.5*(FOVphase-psize_phase)*phasevec; for(int i=0; i<3; i++) { if(!check_status(func,("ImageOrientationPatient("+itos(i)+")").c_str(),dset->findAndGetOFString(DCM_ImageOrientationPatient, valstr,i))) { readvec[i]=atof(valstr.c_str()); } // Does not work in dcmtk if(!check_status(func,("ImageOrientationPatient("+itos(3+i)+")").c_str(),dset->findAndGetOFString(DCM_ImageOrientationPatient, valstr,3+i))) { phasevec[i]=atof(valstr.c_str()); } if(!check_status(func,("ImagePositionPatient("+itos(i)+")").c_str(),dset->findAndGetOFString(DCM_ImagePositionPatient, valstr,i))) { offset[i]=atof(valstr.c_str()); } } //remove the additional mosaic offset //eg. if there is a 10x10 Mosaic, substract the half size of 9 Images from the offset for(int i=0;i<3;i++) { offset[i]+=(mosaic_mult-1)*FOVread*.5*readvec[i] + (mosaic_mult-1)*FOVphase*.5*phasevec[i]; } //Following DICOM standard ImagePositionPatient is the _middle_ of the first vector so we would //use (FOV-voxelsize)/2 to get the center. dvector center_offset= offset + 0.5*(FOVread-psize_read)*readvec + 0.5*(FOVphase-psize_phase)*phasevec; //But siemens seems to store the outer edge of the first voxel. So... if(opts.dialect=="siemens") center_offset= offset + 0.5*FOVread*readvec + 0.5*FOVphase*phasevec; dvector transform(3); transform[0]=-1.0; transform[1]=-1.0; transform[2]=1.0; // default: x- and y-axis are inverted when converting from DICOM coord system to ODIN coord system (as defined in geometry.h) if(!check_status(func,"PatientPosition",dset->findAndGetOFString(DCM_PatientPosition, valstr),optional)) { bool known_position=false; if(valstr=="HFP") { transform[0]=-transform[0]; transform[1]=-transform[1]; known_position=true; } if(valstr=="HFS") { // use default known_position=true; } if(!known_position) { ODINLOG(odinlog,normalDebug) << "Unknown PatientPosition=" << valstr << STD_endl; } } readvec*=transform; phasevec*=transform; center_offset*=transform; slicevec=Data(vector_product(Data(readvec), Data(phasevec))); // has correct handness for ODIN ODINLOG(odinlog,normalDebug) << "psize_read/phase=" << psize_read << "/" << psize_phase << STD_endl; ODINLOG(odinlog,normalDebug) << "offset=" << offset.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "center_offset=" << center_offset.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "readvec=" << readvec.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "phasevec=" << phasevec.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "slicevec=" << slicevec.printbody() << STD_endl; prot.geometry.set_orientation_and_offset(readvec, phasevec, slicevec, center_offset); if(!check_status(func,"SliceThickness",dset->findAndGetOFString(DCM_SliceThickness, valstr),warning)) { prot.geometry.set_sliceThickness(atof(valstr.c_str())); } float space=0; if(!check_status(func,"SpacingBetweenSlices",dset->findAndGetOFString(DCM_SpacingBetweenSlices, valstr),optional)) { space+=atof(valstr.c_str()); prot.geometry.set_sliceDistance(space); } // Calculate slice offset, do not use DCM_SliceLocation since it is based on variable handness // also take in account, that for mosaic the slice position is given for the first image of the mosaic float sliceproj=(slicevec*center_offset).sum(); prot.geometry.set_offset(sliceDirection,sliceproj+(mosaic_slices-1)*space/2); STD_string modality("MR"); if(!check_status(func,"Modality",dset->findAndGetOFString(DCM_Modality, valstr),warning)) { modality=valstr.c_str(); } if(modality=="MR") { // avoid useles error messages with non-MR modalities // Get system stuff if(!check_status(func,"ImagingFrequency",dset->findAndGetOFString(DCM_ImagingFrequency, valstr),warning)) { prot.system.set_B0_from_freq(1000.0*atof(valstr.c_str())); } if(!check_status(func,"TransmitCoilName",dset->findAndGetOFString(DCM_TransmitCoilName, valstr),warning)) { prot.system.set_transmit_coil_name(valstr.c_str()); } // Sequence stuff if(!check_status(func,"PixelBandwidth",dset->findAndGetOFString(DCM_PixelBandwidth, valstr),warning)) { prot.seqpars.set_AcqSweepWidth(0.001*atof(valstr.c_str())*shape(3)); } if(!check_status(func,"RepetitionTime",dset->findAndGetOFString(DCM_RepetitionTime, valstr),warning)) { prot.seqpars.set_RepetitionTime(atof(valstr.c_str())); } if(!check_status(func,"EchoTime",dset->findAndGetOFString(DCM_EchoTime, valstr),warning)) { prot.seqpars.set_EchoTime(atof(valstr.c_str())); } if(!check_status(func,"FlipAngle",dset->findAndGetOFString(DCM_FlipAngle, valstr),warning)) { prot.seqpars.set_FlipAngle(atof(valstr.c_str())); } prot.seqpars.set_PhysioTrigger(dset->findAndGetOFString(DCM_TriggerTime, valstr).good()); // presence of TriggerTime indicates gating, at least on Siemens if(!check_status(func,"SequenceName",dset->findAndGetOFString(DCM_SequenceName, valstr),warning)) { STD_string seqname(valstr.c_str()); // Add sequence variant/options STD_string seqopts; if(!check_status(func,"ScanningSequence",dset->findAndGetOFString(DCM_ScanningSequence, valstr),warning)) { seqopts+=valstr.c_str(); } if(!check_status(func,"SequenceVariant",dset->findAndGetOFStringArray(DCM_SequenceVariant, valstr),warning)) { if(seqopts!="" && valstr!="") seqopts+="_"; seqopts+=replaceStr(valstr.c_str(),"\\","_"); } if(!check_status(func,"ScanOptions",dset->findAndGetOFStringArray(DCM_ScanOptions, valstr),warning)) { if(seqopts!="" && valstr!="") seqopts+="_"; seqopts+=replaceStr(valstr.c_str(),"\\","_"); } if(seqopts!="") seqname+="_"+seqopts; prot.seqpars.set_Sequence(seqname); } } // Timestamp temporal sorting of multi-file DICOMs prot.seqpars.set_AcquisitionStart(-1.0); // inidicates no useful value if(dset->findAndGetOFString(DCM_FrameReferenceTime, valstr).good()){ // for dynamic PET data prot.seqpars.set_AcquisitionStart(atof(valstr.c_str())); } else { if(dset->findAndGetOFString(DCM_InstanceNumber, valstr).good()) { prot.seqpars.set_AcquisitionStart(atof(valstr.c_str())); } else { if(dset->findAndGetOFString(DCM_AcquisitionTime, valstr).good()){// Try timestamp field first //@todo backward compatibility missing (http://idlastro.gsfc.nasa.gov/idl_html_help/Value_Representations.html#TM) int hh=atoi(valstr.substr(0,2).c_str()); int mm=atoi(valstr.substr(2,2).c_str()); double ss=atof(valstr.substr(4,7).c_str()); ODINLOG(odinlog,normalDebug) << "hh/mm/ss=" << hh << "/" << mm << "/" << ss << STD_endl; prot.seqpars.set_AcquisitionStart( 1000.0*(ss + 60*mm + 3600*hh) ); } } } return shape(0)*shape(1); } /////////////////////////////////////////////////////// int write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { Log odinlog("DicomFormat","write"); Range all=Range::all(); STD_string delimiter("\\"); const char* func="DicomFormat::write"; if(check_dict(func)) return -1; JDXfileName fname(filename); #ifdef OFLOG_H OFLog::configure(OFLogger::WARN_LOG_LEVEL); // reset logging (in dcmtk 3.6.0 info logging is somehow enabled sometimes) #endif // Create directory to store DICOMS DicomDirInterface dicomdir; JDXfileName dstdir; dstdir.set_dir(true); dstdir=fname.get_dirname()+SEPARATOR_STR+fname.get_basename_nosuffix()+STD_string("_dcm"); if( createdir(dstdir.c_str()) && (!checkdir(dstdir.c_str())) ) { ODINLOG(odinlog,errorLog) << "Cannot create directoy " << dstdir << STD_endl; return -1; } STD_string dcmdirfname=dstdir+SEPARATOR_STR+"DICOMDIR"; if(check_status(func,"createNewDicomDir",dicomdir.createNewDicomDir(DicomDirInterface::AP_GeneralPurpose,dcmdirfname.c_str()))) return -1; // Iterate over protocol-data pairs unsigned int index=0; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { Protocol prot(pdit->first); // writable copy to adjust FOV const Data& data=pdit->second; DcmFileFormat fileformat; // The meta-info stuff not provided by dcmtk DcmMetaInfo* metainfo=fileformat.getMetaInfo(); if(check_status(func,"MediaStorageSOPClassUID", metainfo->putAndInsertString(DCM_MediaStorageSOPClassUID,UID_MRImageStorage))) return -1; // The dataset stuff DcmDataset *dataset=fileformat.getDataset(); // The static UIDs char uid[100]; if(check_status(func,"SOPClassUID", dataset->putAndInsertString(DCM_SOPClassUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)))) return -1; if(check_status(func,"FrameOfReferenceUID", dataset->putAndInsertString(DCM_FrameOfReferenceUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)))) return -1; if(check_status(func,"SeriesInstanceUID", dataset->putAndInsertString(DCM_SeriesInstanceUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)))) return -1; // Common stuff if(check_status(func,"ImageType", dataset->putAndInsertString(DCM_ImageType,("ORIGINAL"+delimiter+"PRIMARY"+delimiter+"OTHER").c_str()))) return -1; if(check_status(func,"SpecificCharacterSet", dataset->putAndInsertString(DCM_SpecificCharacterSet,"ISO_IR 100"))) return -1; if(check_status(func,"SOPClassUID", dataset->putAndInsertString(DCM_SOPClassUID,UID_MRImageStorage))) return -1; // Pixel data stuff if(check_status(func,"SamplesPerPixel", dataset->putAndInsertUint16(DCM_SamplesPerPixel, 1))) return -1; if(check_status(func,"PhotometricInterpretation",dataset->putAndInsertString(DCM_PhotometricInterpretation, "MONOCHROME2"))) return -1; if(check_status(func,"BitsAllocated", dataset->putAndInsertString(DCM_BitsAllocated, "16"))) return -1; if(check_status(func,"BitsStored", dataset->putAndInsertString(DCM_BitsStored, "16"))) return -1; if(check_status(func,"HighBit", dataset->putAndInsertString(DCM_HighBit, "15"))) return -1; if(check_status(func,"PixelRepresentation", dataset->putAndInsertString(DCM_PixelRepresentation, "0"))) return -1; // Sequence type stuff if(check_status(func,"ScanningSequence", dataset->putAndInsertString(DCM_ScanningSequence, "RM"))) return -1; // research mode if(check_status(func,"SequenceVariant", dataset->putAndInsertString(DCM_SequenceVariant, "NONE"))) return -1; if(check_status(func,"ScanOptions", dataset->putAndInsertString(DCM_ScanOptions, ""))) return -1; // bogus value if(check_status(func,"MRAcquisitionType", dataset->putAndInsertString(DCM_MRAcquisitionType, "2D"))) return -1; if(check_status(func,"EchoTrainLength", dataset->putAndInsertString(DCM_EchoTrainLength, "1"))) return -1; // bogus value // date/time of scan, will be used for all DICOM timestamps STD_string scandate; STD_string scantime; prot.study.get_DateTime(scandate,scantime); // Patient stuff STD_string pname; STD_string pid; STD_string pdbirth; char psex; float pweight; prot.study.get_Patient(pid, pname, pdbirth, psex, pweight); pdbirth[ODIN_DATE_LENGTH]='\0'; pname=replaceStr(pname," ","^"); if(pid=="") pid="Zero"; // dicomdir.addDicomFile does not like zero-size string if(check_status(func,"PatientsName", dataset->putAndInsertString(DCM_PAT_NAME, pname.c_str()))) return -1; if(check_status(func,"PatientID", dataset->putAndInsertString(DCM_PatientID, pid.c_str()))) return -1; if(check_status(func,"PatientsBirthDate", dataset->putAndInsertString(DCM_PAT_BIRTHDATE, pdbirth.c_str()))) return -1; if(check_status(func,"PatientsSex", dataset->putAndInsertString(DCM_PAT_SEX, STD_string(1,psex).c_str()))) return -1; if(check_status(func,"PatientsWeight", dataset->putAndInsertString(DCM_PAT_WEIGHT, ftos(pweight).c_str()))) return -1; // Study stuff STD_string studydescr; STD_string physician; prot.study.get_Context(studydescr, physician); studydescr=replaceStr(studydescr," ","^"); physician=replaceStr(physician," ","^"); STD_string studyid(studydescr); if(studyid=="") studyid="0"; // Mangle date, PatientID and study description into unique Study UID STD_string studyinstanceuid; studyinstanceuid+=scandate; for(unsigned int i=0; i64) studyinstanceuid=studyinstanceuid.substr(0,64); if(check_status(func,"StudyInstanceUID", dataset->putAndInsertString(DCM_StudyInstanceUID, studyinstanceuid.c_str()))) return -1; if(check_status(func,"StudyDate", dataset->putAndInsertString(DCM_StudyDate, scandate.c_str()))) return -1; if(check_status(func,"StudyTime", dataset->putAndInsertString(DCM_StudyTime, scantime.c_str()))) return -1; if(check_status(func,"PerformingPhysiciansName", dataset->putAndInsertString(DCM_PERF_PHYS, physician.c_str()))) return -1; if(check_status(func,"ReferringPhysiciansName", dataset->putAndInsertString(DCM_REF_PHYS, physician.c_str()))) return -1; if(check_status(func,"StudyID", dataset->putAndInsertString(DCM_StudyID, studyid.c_str()))) return -1; if(check_status(func,"StudyDescription", dataset->putAndInsertString(DCM_StudyDescription, studydescr.c_str()))) return -1; if(check_status(func,"AccessionNumber", dataset->putAndInsertString(DCM_AccessionNumber, ""))) return -1; // Series stuff STD_string seriesdescr; int seriesno; prot.study.get_Series(seriesdescr, seriesno); seriesdescr=replaceStr(seriesdescr," ","^"); if(seriesno<=0) seriesno=1; if(check_status(func,"Modality", dataset->putAndInsertString(DCM_Modality, "MR"))) return -1; if(check_status(func,"SeriesDescription",dataset->putAndInsertString(DCM_SeriesDescription, seriesdescr.c_str()))) return -1; // must have value for DICOMDIR if(check_status(func,"ProtocolName",dataset->putAndInsertString(DCM_ProtocolName, seriesdescr.c_str()))) return -1; if(check_status(func,"SeriesNumber",dataset->putAndInsertString(DCM_SeriesNumber, itos(seriesno).c_str()))) return -1; // must have value for DICOMDIR if(check_status(func,"SeriesDate", dataset->putAndInsertString(DCM_SeriesDate, scandate.c_str()))) return -1; if(check_status(func,"SeriesTime", dataset->putAndInsertString(DCM_SeriesTime, scantime.c_str()))) return -1; // Other date/time stuff if(check_status(func,"AcquisitionDate", dataset->putAndInsertString(DCM_AcquisitionDate, scandate.c_str()))) return -1; if(check_status(func,"ContentDate", dataset->putAndInsertString(DCM_ContentDate, scandate.c_str()))) return -1; if(check_status(func,"ContentTime", dataset->putAndInsertString(DCM_ContentTime, scantime.c_str()))) return -1; // Frame of Reference stuff if(check_status(func,"PositionReferenceIndicator",dataset->putAndInsertString(DCM_PositionReferenceIndicator, ""))) return -1; int xsize=data.extent(3); int ysize=data.extent(2); if(opts.dialect=="siemens") { // Siemens screws up with some non-quadratic image sizes, so we will use next-power-of-2-sized quadratic images int quadsize = 1 << (int)(ceil( log(double(STD_max(data.extent(2),data.extent(3))))/ log(2.0))); ODINLOG(odinlog,normalDebug) << "Fixing matrix size for siemens: " << xsize << "x" << ysize << " -> " << quadsize << "x" << quadsize << STD_endl; xsize=ysize=quadsize; } int xoffset=(xsize-data.extent(3))/2; int yoffset=(ysize-data.extent(2))/2; ODINLOG(odinlog,normalDebug) << "xsize/ysize/xoffset/yoffset=" << xsize << "/" << ysize << "/" << xoffset << "/" << yoffset << STD_endl; // adjust FOV in protocol to new matrix size float FOVread= secureDivision(xsize,data.extent(3))*prot.geometry.get_FOV(readDirection); float FOVphase=secureDivision(ysize,data.extent(2))*prot.geometry.get_FOV(phaseDirection); prot.geometry.set_FOV(readDirection, FOVread); prot.geometry.set_FOV(phaseDirection, FOVphase); // Matrix size if(check_status(func,"Rows", dataset->putAndInsertUint16(DCM_Rows, ysize))) return -1; if(check_status(func,"Columns",dataset->putAndInsertUint16(DCM_Columns, xsize))) return -1; // seqpars stuff if(check_status(func,"RepetitionTime", dataset->putAndInsertString(DCM_RepetitionTime, ftos(prot.seqpars.get_RepetitionTime()).c_str()))) return -1; if(check_status(func,"TemporalResolution",dataset->putAndInsertString(DCM_TemporalResolution, ftos(prot.seqpars.get_RepetitionTime()).c_str()))) return -1; if(check_status(func,"EchoTime", dataset->putAndInsertString(DCM_EchoTime, ftos(prot.seqpars.get_EchoTime()).c_str()))) return -1; // if(check_status(func,"NumberOfAverages",dataset->putAndInsertString(DCM_NumberOfAverages, itos(prot.seqpars.get_NumOfRepetitions()).c_str()))) return -1; float pixelbw=secureDivision(1000.0*prot.seqpars.get_AcqSweepWidth(),prot.seqpars.get_MatrixSize(readDirection)); if(check_status(func,"PixelBandwidth", dataset->putAndInsertString(DCM_PixelBandwidth, ftos(pixelbw).c_str()))) return -1; if(check_status(func,"FlipAngle", dataset->putAndInsertString(DCM_FlipAngle, ftos(prot.seqpars.get_FlipAngle()).c_str()))) return -1; if(check_status(func,"SequenceName", dataset->putAndInsertString(DCM_SequenceName, prot.seqpars.get_Sequence().c_str()))) return -1; // system stuff if(check_status(func,"TransmitCoilName", dataset->putAndInsertString(DCM_TransmitCoilName, prot.system.get_transmit_coil_name().c_str()))) return -1; if(check_status(func,"ImagedNucleus", dataset->putAndInsertString(DCM_ImagedNucleus, prot.system.get_main_nucleus().c_str()))) return -1; if(check_status(func,"MagneticFieldStrength",dataset->putAndInsertString(DCM_MagneticFieldStrength, ftos(0.001*prot.system.get_B0()).c_str()))) return -1; if(check_status(func,"ImagingFrequency", dataset->putAndInsertString(DCM_ImagingFrequency, ftos(0.001*prot.system.get_nuc_freq()).c_str()))) return -1; STD_string swstring=STD_string(PACKAGE)+"-"+VERSION; if(check_status(func,"SoftwareVersions", dataset->putAndInsertString(DCM_SoftwareVersions, swstring.c_str()))) return -1; // Manufacturer stuff if(check_status(func,"Manufacturer",dataset->putAndInsertString(DCM_Manufacturer, prot.system.get_platform_str().c_str()))) return -1; STD_string fieldstr=ftos(0.001*prot.system.get_B0(),1)+" Tesla"; // Use field strength to label station if(check_status(func,"StationName",dataset->putAndInsertString(DCM_StationName, fieldstr.c_str()))) return -1; // geometry stuff float xspacing=secureDivision(FOVread, xsize); float yspacing=secureDivision(FOVphase, ysize); STD_string pixstr=ftos(xspacing)+delimiter+ftos(yspacing); if(check_status(func,"PixelSpacing",dataset->putAndInsertString(DCM_PixelSpacing, pixstr.c_str()))) return -1; if(check_status(func,"NumberOfSlices",dataset->putAndInsertString(DCM_NumberOfSlices, itos(prot.geometry.get_nSlices()).c_str()))) return -1; if(check_status(func,"SliceThickness",dataset->putAndInsertString(DCM_SliceThickness, ftos(prot.geometry.get_sliceThickness()).c_str()))) return -1; if(check_status(func,"SpacingBetweenSlices",dataset->putAndInsertString(DCM_SpacingBetweenSlices, ftos(prot.geometry.get_sliceDistance()).c_str()))) return -1; // DTI JcampDxClass* bptr=prot.get_parameter("Diffusion_bVector"); if(bptr) { JDXtriple* bvec=0; bvec=bptr->cast(bvec); if(bvec) { fvector fbvec(*bvec); float bval=norm3(fbvec[0],fbvec[1],fbvec[2]); ODINLOG(odinlog,normalDebug) << "bval=" << bval << STD_endl; if(check_status(func,"DiffusionBValue",dataset->putAndInsertString(DCM_DiffusionBValue, ftos(bval).c_str()))) return -1; if(bval) fbvec/=bval; STD_string borient=ftos(fbvec[0])+delimiter+ftos(fbvec[1])+delimiter+ftos(fbvec[2]); if(check_status(func,"DiffusionGradientOrientation", dataset->putAndInsertString(DCM_DiffusionGradientOrientation, borient.c_str()))) return -1; } } // for SliceLocation dvector slice_offset=prot.geometry.get_sliceOffsetVector(); // Image orientation // Note: x- and y-axis are inverted when converting from ODIN coord system (as defined in geometry.h) to DICOM coord system int digits=12; // Need high accuracy, otherwise DICOMs won't import on Siemens... dvector linvec=prot.geometry.get_readVector(); dvector colvec=prot.geometry.get_phaseVector(); STD_string patort=ftos(-linvec[0],digits)+delimiter+ ftos(-linvec[1],digits)+delimiter+ ftos( linvec[2],digits)+delimiter+ ftos(-colvec[0],digits)+delimiter+ ftos(-colvec[1],digits)+delimiter+ ftos( colvec[2],digits); if(check_status(func,"ImageOrientationPatient", dataset->putAndInsertString(DCM_ImageOrientationPatient, patort.c_str()))) return -1; // fixed position in odin: head first supine if(check_status(func,"PatientPosition", dataset->putAndInsertString(DCM_PatientPosition, "HFS"))) return -1; // use get_cornerPoints() for ImagePositionPatient // account for DICOM's convention that the position is center of the 1st voxel: prot.geometry.set_FOV(readDirection, FOVread - xspacing); prot.geometry.set_FOV(phaseDirection, FOVphase - yspacing); darray cornerpoints=prot.geometry.get_cornerPoints(Geometry(),0); ODINLOG(odinlog,normalDebug) << "cornerpoints" << STD_string(cornerpoints.get_extent()) << "=" << cornerpoints.printbody() << STD_endl; Data u16bitdata; const STD_string type(prot.system.get_data_type()); if(type!="float" && type!="double")data.convert_to(u16bitdata,noupscale); else data.convert_to(u16bitdata); if(opts.dialect=="siemens") { // clip data for viewer on host u16bit thresh=std::numeric_limits::max()-10; Array u16bitdata_copy(u16bitdata); u16bitdata_copy=where(u16bitdata_copy>thresh, thresh, u16bitdata_copy); u16bitdata=u16bitdata_copy; } u16bit minval=min(u16bitdata); u16bit maxval=max(u16bitdata); Data oneslice_padded(ysize,xsize); for(int iframe=0; iframeputAndInsertString(DCM_SOPInstanceUID, dcmGenerateUniqueIdentifier(uid, SITE_INSTANCE_UID_ROOT)))) return -1; if(check_status(func,"InstanceNumber",dataset->putAndInsertString(DCM_InstanceNumber, itos(index+1).c_str()))) return -1; // timestamp double timestamp_s=double(iframe)*0.001*prot.seqpars.get_RepetitionTime(); int hours=int(timestamp_s)/3600; timestamp_s-=hours*3600; int minutes=int(timestamp_s)/60; timestamp_s-=minutes*60; int seconds=int(timestamp_s); timestamp_s-=seconds; int fract=int(timestamp_s*1.0e6); char timestr[100]; snprintf(timestr, 100, "%02i%02i%02i.%06i", hours, minutes, seconds, fract); if(check_status(func,"AcquisitionTime",dataset->putAndInsertString(DCM_AcquisitionTime, timestr))) return -1; // Set slice location of this image // Note: x- and y-axis are inverted when converting from ODIN coord system (as defined in geometry.h) to DICOM coord system STD_string patpos=ftos(-cornerpoints(iplane,0,0,0,0))+delimiter+ftos(-cornerpoints(iplane,0,0,0,1))+delimiter+ftos(cornerpoints(iplane,0,0,0,2)); ODINLOG(odinlog,normalDebug) << "patpos(" << iframe << "," << iplane << ")=" << patpos << STD_endl; if(check_status(func,"ImagePositionPatient", dataset->putAndInsertString(DCM_ImagePositionPatient, patpos.c_str()))) return -1; if(check_status(func,"SliceLocation",dataset->putAndInsertString(DCM_SliceLocation, ftos(slice_offset[iplane]).c_str()))) return -1; oneslice_padded=0; oneslice_padded(Range(yoffset,yoffset+data.extent(2)-1), Range(xoffset,xoffset+data.extent(3)-1))=u16bitdata(iframe,iplane,all,all); if(!insert_uint16_hack(dataset, DCM_SmallestImagePixelValue, minval)) return -1; if(!insert_uint16_hack(dataset, DCM_LargestImagePixelValue, maxval)) return -1; if(check_status(func,"PixelData",dataset->putAndInsertUint16Array(DCM_PixelData, oneslice_padded.c_array(), oneslice_padded.numElements()))) return -1; STD_string basename(itos(index,10000000)); // Filenames with eight digits STD_string singlefname=dstdir+SEPARATOR_STR+basename; // only upper-case letters, no dot, max 8 chars allowed here if(check_status(func,"saveFile",fileformat.saveFile(singlefname.c_str(), EXS_LittleEndianExplicit))) return -1; // file must be stored before adding to DCOMDIR if(check_status( func, (STD_string("addDicomFile \"")+dstdir+"/"+basename+"\"").c_str(), dicomdir.addDicomFile(basename.c_str(),dstdir.c_str()) )) return -1; index++; } } } // End iterating over protocol-data pairs if(check_status(func,"writeDicomDir",dicomdir.writeDicomDir())) return -1; return index; } }; #endif void register_dicom_format() { #ifdef DICOMSUPPORT static DicomFormat df; df.register_format(); #endif } odin-1.8.5/odindata/filter_range.cpp0000644000175000017500000000207111713467630014337 00000000000000#include "filter_range.h" bool str2range(const STD_string& str, Range& range, int srcsize) { Log odinlog("","str2range"); if(str=="") return false; int increment=1; svector tokscol=tokens(str,':'); int colsize=tokscol.size(); if(colsize<1 || colsize>2) return false; if(colsize==2) increment=atoi(tokscol[1].c_str()); svector toks=tokens(tokscol[0],'-'); bool result=false; if(toks.size()==2) {range=Range(atoi(toks[0].c_str()),atoi(toks[1].c_str()),increment); result=true;} if(toks.size()==1) {range=Range(atoi(toks[0].c_str()),atoi(toks[0].c_str()),increment); result=true;} if(!result) { ODINLOG(odinlog,errorLog) << "Error parsing range string >" << str << "<" << STD_endl; } if(result) { if(range.first()>range.last()) result=false; if(range.first()<0 || range.first()>=srcsize) result=false; if(range.last()<0 || range.last()>=srcsize) result=false; if(!result) { ODINLOG(odinlog,errorLog) << "selected " << range << " out of valid range (0," << (srcsize-1) << ")" << STD_endl; } } return result; } odin-1.8.5/odindata/fileio_mat.cpp0000644000175000017500000002404011322062337013775 00000000000000#include "fileio.h" #ifdef MATLABSUPPORT #include #include #include #include #include #include "complexdata.h" ////////////////////////////////////////////////////////////// typedef std::pair > PDpair; class LibMatSingleton{ public: bool initialized; LibMatSingleton(){ Log odinlog("LibMatSingleton","LibMatSingleton"); /* Initialize Matlab */ const char *oplist[]={"-nojvm"}; if (!mclInitializeApplication((const char **)oplist,1)){ ODINLOG(odinlog,errorLog) << "Could not initialize MATLAB interface" << STD_endl; initialized=false; } else { ODINLOG(odinlog,infoLog) << "MATLAB interface initialized " << STD_endl; initialized=true; } } ~LibMatSingleton(){ Log odinlog("LibMatSingleton","~LibMatSingleton"); ODINLOG(odinlog,infoLog) << "Shuting down MATLAB interface" << STD_endl; mclTerminateApplication(); } }; struct MatlabBinFormat : public FileFormat { MATFile *fp; mxArray *root; FileWriteOpts w_opts; static bool initialized; MatlabBinFormat():fp(0){} STD_string description() const {return "binary data for Matlab";} svector suffix() const { svector result; result.resize(1); result[0]="mat"; return result; } svector dialects() const {return svector();} bool init() { static LibMatSingleton single; return single.initialized; } template mxArray *dat2array(Data dat,mxClassID classID) { Log odinlog("MatlabBinFormat","dat2array"); mxArray *ret; const TinyVector shape(dat.shape()); unsigned short dims; if(shape(0)>1) dims=4; else if(shape(1)>1) dims=3; else if(shape(2)>1) dims=2; else dims=1; mwSize size[dims]; for(int i=0;i odinlog("MatlabBinFormat","createMetaDataArray"); mxArray *ret; const mwSize dims[]={ydim,xdim}; if(!(ret=mxCreateNumericArray(2,dims,mxDOUBLE_CLASS,mxREAL))) { ODINLOG(odinlog,errorLog) << "could not create " << xdim << "x" << ydim << " array for Metadata" << STD_endl; return NULL; } else return ret; } bool saveVar(const mxArray *arr,STD_string name){ Log odinlog("MatlabBinFormat","saveVar"); if(matPutVariable(fp,name.c_str(),arr)!=0){ ODINLOG(odinlog,errorLog) << "could not add " << name << STD_endl; return false; } return true; } mxArray* vector2Array(const dvector vect){ const mwSize dim=vect.size(); mxArray *arr=createMetaDataArray(dim); if(!arr)return NULL; double* ptr=(double*)mxGetData(arr); for(unsigned short i=0;i odinlog("MatlabBinFormat","triple2Array"); mxArray *arr=createMetaDataArray(3); if(!arr){ ODINLOG(odinlog,errorLog) << "array creation failed" << STD_endl; return NULL; } double* ptr=(double*)mxGetData(arr); for(unsigned short i=0;i<3;i++) ptr[i]=triple[i]; return arr; } mxArray* rotMatrix2Array(const RotMatrix rot){ Log odinlog("MatlabBinFormat","rotMatrix2Array"); mxArray *arr=createMetaDataArray(3,3); if(!arr){ ODINLOG(odinlog,errorLog) << "array creation failed" << STD_endl; return NULL; } double* ptr=(double*)mxGetData(arr); for(unsigned short i=0;i<3*3;i++) ptr[i]=rot[i%3][i/3]; return arr; } mxArray *dat2mat(const PDpair &pdpair, const FileWriteOpts& opts){ Log odinlog("MatlabBinFormat","dat2mat"); const Protocol &prot=pdpair.first; const Data &dat=pdpair.second; mxArray *matArray=NULL; STD_string type=selectDataType(prot,opts); if(type=="s8bit") matArray=dat2array (dat,mxINT8_CLASS); else if(type=="u8bit") matArray=dat2array (dat,mxUINT8_CLASS); else if(type=="s16bit") matArray=dat2array(dat,mxINT16_CLASS); else if(type=="u16bit") matArray=dat2array(dat,mxUINT16_CLASS); else if(type=="s32bit") matArray=dat2array(dat,mxINT32_CLASS); else if(type=="u32bit") matArray=dat2array(dat,mxUINT32_CLASS); else if(type=="float") matArray=dat2array (dat,mxSINGLE_CLASS); else if(type=="double") matArray=dat2array(dat,mxDOUBLE_CLASS); else ODINLOG(odinlog,errorLog) << "datatype >" << type << "< unknown/unhandled" << STD_endl; return matArray; } template void array2dat(mxArray *matArray,Protocol &prot,Data &dat) { prot.system.set_data_type(TypeTraits::type2label(T())); //copy/convert data, scale only down and only when converted to integers convert_from_ptr(dat,(T*)mxGetData(matArray),dat.shape()); } const unsigned int mat2dat(Protocol &prot,Data &dat){ Log odinlog("MatlabBinFormat","mat2dat"); const char *name; mxArray *matArray= matGetNextVariable(fp, &name); if(!matArray)return 0; prot.seqpars.set_description(name); size_t dims=mxGetNumberOfDimensions(matArray); const mwSize *dim=mxGetDimensions(matArray); if(dims>2) { prot.seqpars.set_NumOfRepetitions(dim[2]); prot.geometry.set_nSlices(dim[2]); } if(dims>1) prot.seqpars.set_MatrixSize(phaseDirection,dim[1]); if(dims >0) prot.seqpars.set_MatrixSize(readDirection,dim[0]); switch(dims) { case 4:dat.resize(dim[3], dim[2], dim[1], dim[0]);break; case 3:dat.resize(dim[2], dim[1], dim[0], 1);break; case 2:dat.resize(dim[1], dim[0], 1, 1);break; case 1:dat.resize(dim[0], 1, 1, 1);break; default:ODINLOG(odinlog,errorLog) << dims << " Dimensions not (yet) supportted" << STD_endl; } switch(mxGetClassID(matArray)) { case mxINT8_CLASS: array2dat (matArray, prot, dat);break; case mxUINT8_CLASS: array2dat (matArray, prot, dat);break; case mxINT16_CLASS: array2dat (matArray, prot, dat);break; case mxUINT16_CLASS:array2dat (matArray, prot, dat);break; case mxINT32_CLASS: array2dat (matArray, prot, dat);break; case mxUINT32_CLASS:array2dat (matArray, prot, dat);break; /* case mxINT64_CLASS: array2dat (matArray, prot, dat);break; case mxUINT64_CLASS:array2dat (matArray, prot, dat);break;*/ case mxSINGLE_CLASS:array2dat (matArray, prot, dat);break; case mxDOUBLE_CLASS:array2dat (matArray, prot, dat);break; default: ODINLOG(odinlog,errorLog) << "Datatype \""<< mxGetClassName(matArray) << "\" not (yet) supportted" << STD_endl; dat.resize(0,0,0,0); break; } // matlab uses column-major ordering dat.transposeSelf(fourthDim,thirdDim,secondDim,firstDim); prot.geometry.set_Mode(voxel_3d); prot.geometry.set_FOV(readDirection,dat.shape()(3)); prot.geometry.set_FOV(phaseDirection,dat.shape()(2)); prot.geometry.set_FOV(sliceDirection,dat.shape()(1)); mxDestroyArray(matArray); return 1; } bool open(STD_string name,const char mode[]){ if(init() && (fp=matOpen(name.c_str(),mode)))return true; else return false; } void close(){ matClose(fp); } int read(FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template) { Log odinlog("MatlabBinFormat","read"); if(!open(filename,"r")){ ODINLOG(odinlog,errorLog) << "could not open " << filename << " for reading: " << strerror(errno) << STD_endl; return -1; } Data dat; Protocol prot(protocol_template); while(mat2dat(prot,dat)) { FileIO::ProtocolDataMap::const_iterator found=pdmap.find(prot); if(found!=pdmap.end()) ODINLOG(odinlog,warningLog) << "equal Protocols found, skipping" << STD_endl; else pdmap[prot].reference(dat); } close(); return 1; } void write(const PDpair &pair,unsigned short index, const FileWriteOpts& opts){ Log odinlog("MatlabBinFormat","write"); STD_string seqDesc; int seqNum; pair.first.study.get_Series(seqDesc,seqNum); mxSetField(root, index, "seqDesc", mxCreateString(seqDesc.c_str())); mxSetField(root, index, "seqNum", mxCreateDoubleScalar(seqNum)); mxSetField(root, index, "voxel", dat2mat(pair,opts)); mxSetField(root, index, "center",vector2Array(pair.first.geometry.get_center())); mxSetField(root, index, "rotation",rotMatrix2Array(pair.first.geometry.get_gradrotmatrix())); JDXtriple *diff=dynamic_cast(const_cast(pair.first).methpars.get_parameter("Diffusion_bVector")); if(diff)mxSetField(root, index, "bVector",triple2Array(*diff)); } int write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { Log odinlog("MatlabBinFormat","write"); const char *field_names[] = {"bVector","voxel", "center","rotation","seqDesc","seqNum"}; if(!open(filename,"w")){ ODINLOG(odinlog,errorLog) << "could not open " << filename << " for writing: " << strerror(errno) << STD_endl; return -1; } unsigned short cnt=0; const mwSize dim = pdmap.size(); root=mxCreateStructArray(1, &dim, sizeof(field_names)/sizeof(char*), field_names); w_opts=opts; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit,cnt++) write(*pdit,cnt,opts); saveVar(root,"root"); close(); return pdmap.size(); } }; bool MatlabBinFormat::initialized=0; #endif //MATLABSUPPORT ////////////////////////////////////////////////////////////// void register_mat_format() { #ifdef MATLABSUPPORT static MatlabBinFormat mat; mat.register_format(); #endif //MATLABSUPPORT } odin-1.8.5/odindata/filter_lowpass.cpp0000644000175000017500000000313011725203122014713 00000000000000#include "filter_lowpass.h" #include "complexdata.h" #include void FilterLowPass::init(){ freq=0.0; freq.set_unit("Hz").set_description("Cut-off frequency"); append_arg(freq,"freq"); } bool FilterLowPass::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Range all=Range::all(); TinyVector shape=data.shape(); int nrep=shape(timeDim); ComplexData<4> cdata(float2real(data)); cdata.partial_fft( TinyVector(true,false,false,false), true); int centindex=nrep/2; float maxfreq_Hz=1000.0*secureDivision(1.0, prot.seqpars.get_RepetitionTime()); int cutoffindex=int(secureDivision(freq, maxfreq_Hz)*centindex+0.5); int plateauindex=int(0.8*cutoffindex+0.5); ODINLOG(odinlog,normalDebug) << "plateauindex/cutoffindex=" << plateauindex << "/" << cutoffindex << STD_endl; JDXfilter transition; transition.set_function("Gauss"); for(int i=0; i<(centindex+1); i++) { if(i>=plateauindex && i<=cutoffindex) { float relpos=secureDivision(i-plateauindex, cutoffindex-plateauindex); STD_complex factor(transition.calculate(relpos)); if((centindex-i)>=0) cdata(centindex-i, all, all, all)*=factor; if((centindex+i)cutoffindex) { if((centindex-i)>=0) cdata(centindex-i, all, all, all)=STD_complex(0.0); if((centindex+i)(true,false,false,false), false); data=creal(cdata); return true; } odin-1.8.5/odindata/filter_splice.h0000644000175000017500000000262711725203122014161 00000000000000/*************************************************************************** filter_reduction.h - description ------------------- begin : Fri Feb 17 2012 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_SPLICE_H #define FILTER_SPLICE_H #include "filter_step.h" class FilterSplice: public FilterStep { JDXenum dir; STD_string label() const {return "splice";} STD_string description() const {return "splices the image in the given direction";} bool process(FileIO::ProtocolDataMap& pdmap)const; FilterStep* allocate() const {return new FilterSplice();} void init(); }; #endif odin-1.8.5/odindata/filter_shift.cpp0000644000175000017500000000121211322062337014343 00000000000000#include "filter_shift.h" void FilterShift::init(){ for(int idir=0; idir& data, Protocol& prot) const { TinyVector subpixel_shift(0.0,shift[sliceDirection],shift[phaseDirection],shift[readDirection]); data.congrid(data.shape(), &subpixel_shift); for(int idir=0; idir #include #include /** * @addtogroup odindata * @{ */ /** * Options for autoread */ struct FileReadOpts : JcampDxBlock { FileReadOpts(); JDXenum format; JDXstring jdx; JDXenum cplx; JDXint skip; JDXstring dset; JDXstring filter; JDXstring dialect; JDXbool fmap; }; ////////////////////////////////////////////////////////////////////////// /** * Options for autowrite */ struct FileWriteOpts : JcampDxBlock { FileWriteOpts(); JDXenum format; JDXbool append; JDXstring wprot; JDXbool split; JDXstring dialect; JDXenum datatype; JDXstring fnamepar; }; /** @} */ #endif odin-1.8.5/odindata/filter_merge.cpp0000644000175000017500000000316611322062337014337 00000000000000#include "filter_merge.h" bool FilterMerge::process(FileIO::ProtocolDataMap& pdmap) const { Log odinlog(c_label(),"process"); Range all=Range::all(); STD_map acqstartmap; // Create a temporary protocol-data pair for each AcquisitionStart TinyVector shape=0; for(FileIO::ProtocolDataMap::const_iterator it=pdmap.begin();it!=pdmap.end();it++) { const Protocol& prot=it->first; const Data& data=it->second; shape(timeDim)+=data.extent(timeDim); for(int idim=sliceDim; idim result(shape); int repoffset=0; Protocol prot; bool prot_set=false; for(STD_map::const_iterator acqit=acqstartmap.begin();acqit!=acqstartmap.end();acqit++) { const FileIO::ProtocolDataMap& acqpdmap=acqit->second; for(FileIO::ProtocolDataMap::const_iterator it=acqpdmap.begin();it!=acqpdmap.end();it++) { if(!prot_set) {prot=it->first; prot_set=true;} // Use first protocol for dataset Data oneset(it->second); TinyVector newshape(shape); int nrep=oneset.extent(timeDim); newshape(timeDim)=nrep; oneset.congrid(newshape); ODINLOG(odinlog,normalDebug) << "newshape" << newshape << STD_endl; result(Range(repoffset,repoffset+nrep-1),all,all,all)=oneset; repoffset+=nrep; } } pdmap[prot].reference(result); return true; } odin-1.8.5/odindata/fileio.h0000644000175000017500000001362211734622163012613 00000000000000/*************************************************************************** fileio.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILEIO_H #define FILEIO_H //shortcut to check for type from string (templated function doesn work well with mingw - so we use macro) #define IS_TYPE(type, name) (name==TypeTraits::type2label((type)0)) #include #include #define AUTODETECTSTR "autodetect" #define AUTOTDATAYPESTR "automatic" /** * @addtogroup odindata * @{ */ /** * The 4 dimensions of data arrays used in FileIO and Filter components, these dimensions are * - timeDim: Time direction * - sliceDim: Slice direction * - phaseDim: Phase direction * - readDim: Read direction */ enum dataDim { timeDim=0, sliceDim, phaseDim, readDim, n_dataDim }; static const char* dataDimLabel[]={"time", "slice", "phase", "read"}; /** * Structure to accomodate autoread/autwrite functionality. Please refer to (\ref fileio_doc ) for a detailed description of this module. */ class FileIO { public: /** * Type to associate protocols with tempo-spatial raw data via std::map */ typedef STD_map > ProtocolDataMap; /** * Reads in file 'filename' and appends all data sets found to protocol-data map 'pdmap', autodetects file format according to file extension. * Read options are given by 'opts' and 'protocol_template' contains defaults used by the decoder/encoder of the particular file format. * The progress meter 'progmeter' can be optionally specified to monitor the progress of the operation. * Returns number of slices, or -1 if it fails. */ static int autoread(ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template,ProgressMeter* progmeter=0); /** * Writes out protocol-data map 'pdmap' to file(s) filename, autodetects file format according to file extension. * Write options are given by 'opts'. * Returns number of slices sucessfully written, or -1 if it fails. */ static int autowrite(const ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts); /** * Returns possible file formats/extensions to autoread autowrite */ static svector autoformats(); /** * Returns possible file formats as string with comment */ static STD_string autoformats_str(const STD_string& indent=""); /** * Returns whether tracing via stdout is enabled/disabled */ static bool get_trace_status() {return do_trace;} /** * Enables/disables tracing via stdout */ static void set_trace_status(bool stat) {do_trace=stat;} static const char* get_compName(); // For debugging FilieIO component private: static logPriority loglevel() {if(do_trace) return infoLog; else return normalDebug;} static bool do_trace; static int read_dir(ProtocolDataMap& pdmap, const STD_string& dirname, const FileReadOpts& opts, const Protocol& protocol_template,ProgressMeter* progmeter=0); }; ////////////////////////////////////////////////////////////////////////// /** * Base class for file formats */ class FileFormat { public: /** * Use this function on a static instance to register the corresponding file format */ void register_format(); /** * creates unique filenames based on 'filename' for the protocol-data pairs in 'pdmap' using comma-separated list of additional parameters in 'par' */ static svector create_unique_filenames(const STD_string& filename, const FileIO::ProtocolDataMap& pdmap, const STD_string& par); /** * returns the voxel extent of the 'geometry' in the given 'direction' using a matrix size 'size'. */ static float voxel_extent(const Geometry& geometry, direction direction, int size); protected: virtual ~FileFormat() {} // avoid compiler warnings /** * Returns the spatial voxel extent in the given direction assuming the given size */ static STD_string selectDataType(const Protocol &prot,const FileWriteOpts& opts); private: // limit access friend class FileIO; virtual STD_string description() const = 0; virtual svector suffix() const = 0; virtual svector dialects() const = 0; virtual int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot); virtual int read(FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template); virtual int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot); virtual int write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts); static STD_map formats; static STD_string analyze_suffix(const STD_string& filename); static FileFormat* get_format(const STD_string& filename, const STD_string& override_suffix); static svector possible_formats(); static STD_string formats_str(const STD_string& indent); static void format_error(const STD_string& filename); }; /** @} */ #endif odin-1.8.5/odindata/filter.h0000644000175000017500000000245011322062337012620 00000000000000// // C++ Interface: filter // // Description: // // // Author: , (C) 2008 // // Copyright: See COPYING file that comes with this distribution // // #ifndef FILTER_H #define FILTER_H #include /** * @addtogroup odindata * @{ */ // helper class for debugging the filter component struct Filter { static const char* get_compName(); }; ///////////////////////////////////////////////////////////////////////////// /** * A chain of filter functors. */ class FilterChain { public: /** * Create empty filter chain */ FilterChain() {} /** * Create filter chain from command line string. */ FilterChain(const STD_string& argstr) {init(argstr);} /** * Create filter chain from command line. */ FilterChain(int argc,char *argv[]); /** * Initialize filter chain using given command-line string. */ bool init(const STD_string& argstr) {return create(tokens(argstr,' ','\"','\"'));} /** * Apply filter chain to all elements in 'pdmap'. */ bool apply(FileIO::ProtocolDataMap& pdmap) const; /** * Apply filter chain to protocol-data pair. */ bool apply(Protocol& prot, Data& data) const; private: FilterFactory factory; STD_list filters; bool create(const svector& args); }; /** @} */ #endif odin-1.8.5/odindata/fileio_mhd.cpp0000644000175000017500000001102511322062337013763 00000000000000#include "fileio.h" ///////////////////////////////////////////////////////////// struct MhdFormat : public FileFormat { STD_string description() const {return "MetaImage";} svector suffix() const { svector result; result.resize(1); result[0]="mhd"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("MhdFormat","read"); STD_string mhdfile; ::load(mhdfile,filename); mhdfile=replaceStr(mhdfile,"=", " = "); // make sure key, value and '=' are separated by whitespaces svector toks=tokens(mhdfile); int ndims=-1; int i; int ntoks=toks.size(); for(i=0; i shape=data.shape(); farray fa(data); ndim nn=fa.get_extent(); nn.autosize(); // get rid of 1-size dims fvector res(nn.dim()); res=1.0; ODINLOG(odinlog,normalDebug) << "fa.dim()=" << fa.dim() << STD_endl; if(fa.dim()>2) { dvector soffset=prot.geometry.get_sliceOffsetVector(); ODINLOG(odinlog,normalDebug) << "soffset=" << soffset.printbody() << STD_endl; if(soffset.size()>1) res[nn.dim()-3]=fabs(soffset[1]-soffset[0]); else res[nn.dim()-3]=prot.geometry.get_sliceThickness(); } if(nn.dim()>1) res[nn.dim()-2]=secureDivision(prot.geometry.get_FOV(phaseDirection),prot.seqpars.get_MatrixSize(phaseDirection)); if(nn.dim()>0) res[nn.dim()-1]=secureDivision(prot.geometry.get_FOV(readDirection), prot.seqpars.get_MatrixSize(readDirection)); JDXfileName fname(filename); STD_string rawfname=fname.get_basename_nosuffix()+".raw"; STD_string header; header+="NDims = "+itos(nn.dim())+"\n"; header+="DimSize ="; for(unsigned int idim=0; idim(fname.get_dirname()+rawfname); } }; ////////////////////////////////////////////////////////////// void register_mhd_format() { static MhdFormat mf; mf.register_format(); } odin-1.8.5/odindata/fitting.h0000644000175000017500000004306111735132611013003 00000000000000/*************************************************************************** fitting.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen & Michael von Mengershausen email : jochimse@cns.mpg.de mengers@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FITTING_H #define FITTING_H #include // for MinimizationFunction #include #include #include /** * @addtogroup odindata * @{ */ /** * Structure representing a fitting paramater. */ struct fitpar { fitpar() : val(0.0), err(0.0) {} /** * Value of the fitting parameter which is varied during the fit. */ float val; /** * The error interval of the final result. */ float err; }; //////////////////////////////////////////////////////////////////////// /** * Base class of all multi-dimensional function classes which * are used for fitting. * The function has an independent variable 'x' (the argument to evaluate_f), * a dependent variable 'y' (the result of evaluate_f) and a number of * function parameters. * To use this class, derive from it and overload the virtual * functions 'evaluate_f' (function value), 'evaluate_df' (first derivative), * 'numof_fitpars', and 'get_fitpar'. * Parameters which are modified during the fit should be * members of type fitpar. */ class ModelFunction { public: /** * Returns the function value at position 'x'. */ virtual float evaluate_f(float x) const = 0; /** * Returns the first derivatives at position 'x'. */ virtual fvector evaluate_df(float x) const = 0; /** * Returns the number of independent fitting parameters. */ virtual unsigned int numof_fitpars() const = 0; /** * Returns reference to the i'th fitting parameter. */ virtual fitpar& get_fitpar(unsigned int i) = 0; /** * Fit the function to the given dataset. * The current parameters are taken as starting values. * Fits the function to the y-values 'yvals', and optionally * to the corresponding y-error bars 'ysigma' and x-vals 'xvals'. * If no error-bars are given, they are all set to 0.1 and if no * x-vals are given equidistant points with an increment of one are chosen, * i.e. xvals(i)=i; * A maximum of 'max_iterations' iterations and the given 'tolerance' * is used for the fit. * Returns true on success. */ bool fit(const Array& yvals, const Array& ysigma=defaultArray, const Array& xvals=defaultArray, unsigned int max_iterations=500, double tolerance=1.0e-4); /** * Returns the function values for x-values 'xvals'. */ Array get_function(const Array& xvals) const; // dummy array used for default arguments static const Array defaultArray; protected: ModelFunction() {} virtual ~ModelFunction() {} fitpar dummy_fitpar; }; //////////////////////////////////////////////////////////////////////// class ModelData; // forward declaration class GslData4Fit; // forward declaration /** * Class which is used for fitting of functions. */ class FunctionFit { public: /** * Prepare a non-linear least-square fit of function 'model_func' for 'nvals' values with a * maximum of 'max_iterations' iterations and the given 'tolerance'. */ FunctionFit(ModelFunction& model_func, unsigned int nvals, unsigned int max_iterations=500, double tolerance=1.0e-4); /** * Destructor */ ~FunctionFit(); /** * The fitting routine that takes the starting values from the model function, * y-values 'yvals', and optionally the corresponding y-error bars 'ysigma' * and x-vals 'xvals'. If no error-bars are given, they are all set to 0.1 and if no * x-vals are given equidistant points with an increment of one are chosen, * i.e. xvals(i)=i; * Returns true on success. */ bool fit(const Array& yvals, const Array& ysigma=defaultArray, const Array& xvals=defaultArray); // dummy array used for default arguments static const Array defaultArray; private: void print_state (size_t iter); ModelFunction& func; unsigned int max_it; double tol; GslData4Fit* gsldata; ModelData* data4fit; }; /////////////////////////////////////////////////////////////////////// /** * A function to fit an exponential curve to an 1D data set. * It uses the function * * A * exp(lambda * x) */ struct ExponentialFunction : public ModelFunction { fitpar A; fitpar lambda; // implementing virtual functions of ModelFunction float evaluate_f(float x) const; fvector evaluate_df(float x) const; unsigned int numof_fitpars() const; fitpar& get_fitpar(unsigned int i); }; /////////////////////////////////////////////////////////////////////// /** * A function to fit an exponential curve to an 1D data set. * It uses the function * * A * exp(lambda * x) + C */ struct ExponentialFunctionWithOffset : public ModelFunction { fitpar A; fitpar lambda; fitpar C; // implementing virtual functions of ModelFunction float evaluate_f(float x) const; fvector evaluate_df(float x) const; unsigned int numof_fitpars() const; fitpar& get_fitpar(unsigned int i); }; /////////////////////////////////////////////////////////////////////// /** * A function to fit an Gaussian curve to an 1D data set. * It uses the function * * A * exp( - 2 * ( (x-x0) / fwhm )^2 ) */ struct GaussianFunction : public ModelFunction { fitpar A; fitpar x0; fitpar fwhm; // implementing virtual functions of ModelFunction float evaluate_f(float x) const; fvector evaluate_df(float x) const; unsigned int numof_fitpars() const; fitpar& get_fitpar(unsigned int i); }; /////////////////////////////////////////////////////////////////////// /** * * Class for fitting sinus function to a 1D curve * * y= A*sin(m*x + c) */ struct SinusFunction : public ModelFunction { fitpar A; fitpar m; fitpar c; // implementing virtual functions of ModelFunction float evaluate_f(float x) const; fvector evaluate_df(float x) const; unsigned int numof_fitpars() const; fitpar& get_fitpar(unsigned int i); }; /////////////////////////////////////////////////////////////////////// /** * * Class for fitting gamma variate function to a 1D curve * * y= A*x^alpha*exp(-x/beta) */ struct GammaVariateFunction : public ModelFunction { /** * * Set parameters from a simplified set of parameters: xmax and ymax are the x- and y-values of the maximum (see Madsen, Phys. Med. Biol. 37, 1992) */ void set_pars(float alphaval, float xmax, float ymax); fitpar A; fitpar alpha; fitpar beta; // implementing virtual functions of ModelFunction float evaluate_f(float x) const; fvector evaluate_df(float x) const; unsigned int numof_fitpars() const; fitpar& get_fitpar(unsigned int i); }; /////////////////////////////////////////////////////////////////////// /** * * Class for polynomial fitting of function * * y= Sum_i a[i] x^i, with i in [0,N_rank] * * N_rank is the degree of the polynome to be fitted */ template struct PolynomialFunction { fitpar a[N_rank+1]; /** * * polynomial fitting routine. * Fits the function to the y-values 'yvals', and optionally * the corresponding error bars 'ysigma' and x-values 'xvals'. * If no error-bars are given they are all set to 1.0 and if no * x-vals are given equidistant points with an increment of one * are chosen, i.e. xvals(i)=i; * Returns true on success. */ bool fit(const Array& yvals, const Array& ysigma, const Array& xvals); bool fit(const Array& yvals, const Array& ysigma){ firstIndex fi; Array xvals(yvals.size()); xvals=fi; return fit(yvals,ysigma,xvals); }; bool fit(const Array& yvals){ Array ysigma(yvals.size()); ysigma=1.; return fit(yvals,ysigma); }; /** * Returns the polynomial function values for x-values 'xvals' * using the current polynomial coefficients. */ Array get_function(const Array& xvals) const; }; template bool PolynomialFunction::fit(const Array& yvals, const Array& ysigma, const Array& xvals) { int npol=N_rank+1; for(int i=0; i sigma(npts); if(ysigma.size()==npts) sigma=ysigma; else sigma=1.0; Array x(npts); if(xvals.size()==npts) x=xvals; else for(int ipt=0; ipt A(npts,npol); Array b(npts); for(int ipt=0; ipt coeff(solve_linear(A,b)); for(int ipol=0; ipol Array PolynomialFunction::get_function(const Array& xvals) const { int npts=xvals.size(); Array result(npts); result=0.0; for(int ipt=0; ipt& yvals, const Array& ysigma=defaultArray, const Array& xvals=defaultArray); /** * Returns the linear function values for x-values 'xvals' * using the current fit parameters. */ Array get_function(const Array& xvals) const; // dummy array used for default arguments static const Array defaultArray; }; /////////////////////////////////////////////////////////////////////// class GslData4DownhillSimplex; // forward declaration /** * downhill simplex optimizer */ class DownhillSimplex { public: /** * Construct downhill simplex optimizer * - function: Function to evaluate/minimize */ DownhillSimplex(MinimizationFunction& function); /** * Destructor */ ~DownhillSimplex(); /** * Returns parameter values which minimize function * - starting_points: Starting from this initial point * - step_size: The size of the initial trial steps * - ftol: Tolerannce * - nmax: Max number of iterations */ fvector get_minimum_parameters(const fvector& starting_points, const fvector& step_size, float ftol=1e-3, unsigned int nmax=1000); private: unsigned int ndim; GslData4DownhillSimplex* gsldata; }; /////////////////////////////////////////////////////////////////////// /** * Fits an N_rank-dimensional polynomial of order 'polynom_order' to each point of the * array using the values of its neighbours regarding their reliability * (i.e. their relative weight for the fit). Parameters are: * - value_map: The array to be fitted * - reliability_map: The reliability of each point * - polynom_order: Order of the polynom * - kernel_size: Size of the neighbourhood of the pixel which is * considered for the fit (using a Gaussian kernel with this FWHM) * - only_zero_reliability: Fit only pixel with zero reliabiliy * * This function returns the fitted array */ template Array polyniomial_fit(const Array& value_map, const Array& reliability_map, unsigned int polynom_order, float kernel_size, bool only_zero_reliability=false) { Log odinlog("","polyniomial_fit"); Data result(value_map.shape()); result=0.0; if(!same_shape(value_map,reliability_map)) { ODINLOG(odinlog,errorLog) << "size mismatch (value_map.shape()=" << value_map.shape() << ") != (reliability_map.shape()=" << reliability_map.shape() << ")" << STD_endl; return result; } if(min(reliability_map)<0.0) { ODINLOG(odinlog,errorLog) << "reliability_map must be non-negative" << STD_endl; return result; } int minsize=max(value_map.shape()); for(int idim=0; idim1) && (dimsize valshape(value_map.shape()); int nvals=value_map.numElements(); TinyVector polsize; polsize=polynom_order+1; Data polarr(polsize); int npol=polarr.numElements(); if(pow(kernel_size,float(N_rank)) neighbsize; neighbsize=2*neighb_pixel+1; TinyVector neighboffset; neighboffset=-neighb_pixel; Data neighbarr(neighbsize); // neighbour grid around root pixel int nneighb=neighbarr.numElements(); ODINLOG(odinlog,normalDebug) << "nvals/npol/nneighb=" << nvals << "/" << npol << "/" << nneighb << STD_endl; if(npol>nneighb) { ODINLOG(odinlog,warningLog) << "polynome order (" << npol << ") larger than number of neighbours (" << nneighb << ")" << STD_endl; } Array A(npol,npol); Array c(npol); Array b(npol); TinyVector valindex; TinyVector neighbindex; TinyVector currindex; TinyVector diffindex; TinyVector polindex; TinyVector polindex_sum; float epsilon=0.01; float relevant_radius=0.5*kernel_size*sqrt(double(N_rank))+epsilon; // iterate through pixels of value_map for(int ival=0; ival=valshape(irank)) valid_pixel=false; } // does the pixel have non-vanishing reliability float reliability=0.0; if(valid_pixel) reliability=reliability_map(currindex); if(reliability<=0.0) valid_pixel=false; if(valid_pixel) { diffindex=currindex-valindex; // (xk-x0,yk-y0,...) float radiussqr=sum(diffindex*diffindex); float weight=reliability*exp(-2.0*radiussqr/(kernel_size*kernel_size)); if(weight>0.0) { if(sqrt(radiussqr)<=relevant_radius) n_relevant_neighb_pixel++; // create b_i,j for(int ipol=0; ipol=npol) { // do we have enough pixel for the fit ? c=solve_linear(A,b); result(valindex)=c(0); } } else result(valindex)=value_map(valindex); } return result; } /** @} */ #endif odin-1.8.5/odindata/filter_align.cpp0000644000175000017500000000646511322062337014337 00000000000000#include "filter_align.h" #include "gridding.h" void FilterAlign::init(){ fname.set_description("filename"); append_arg(fname,"fname"); blowup.set_description("In-plane blowup factor"); append_arg(blowup,"blowup"); } bool FilterAlign::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Range all=Range::all(); TinyVector inshape3d(data.extent(sliceDim),data.extent(phaseDim),data.extent(readDim)); int blowup_factor=STD_max(1,int(blowup)); // Load external file Data extdata; Protocol alignprot; if(extdata.autoread(fname, FileReadOpts(), &alignprot)<0) return false; TinyVector dst_shape(extdata.shape()(sliceDim),blowup_factor*extdata.shape()(phaseDim),blowup_factor*extdata.shape()(readDim)); ODINLOG(odinlog,normalDebug) << "dst_shape=" << dst_shape << STD_endl; extdata.free(); TinyVector dst_extent; for(int i=0; i<3; i++) dst_extent(2-i)=alignprot.geometry.get_FOV(direction(i)); ODINLOG(odinlog,normalDebug) << "dst_extent=" << dst_extent << STD_endl; int npts3d=product(inshape3d); ODINLOG(odinlog,normalDebug) << "npts3d=" << npts3d << STD_endl; STD_vector > src_coords(npts3d); dvector srcfov(3); dvector dstfov(3); dvector srcsize(3); dvector dstsize(3); for(int i=0; i index=index2extent(inshape3d, ipt); for(int i=0; i<3; i++) relpos[2-i]=secureDivision(0.5+index(i), inshape3d(i)); srcpos=srcfov*(relpos-0.5); dstpos=alignprot.geometry.transform( prot.geometry.transform(srcpos,false), true); src_coords[ipt].coord=TinyVector(dstpos[2],dstpos[1],dstpos[0]); ODINLOG(odinlog,normalDebug) << "src_coords(" << ipt << ")=" << src_coords[ipt].coord << STD_endl; } JDXfilter gridkernel; gridkernel.set_function("Gauss"); // Calculate kernel which covers both grids for(int i=0; i #ifdef HAVE_LIBGSL #include #include #include // data struct to be passed through GSL functions struct ModelData { ModelData(unsigned int size) {n=size; y=new float[size]; sigma=new float[size]; x=new float[size];} ~ModelData() {delete[] y; delete[] sigma; delete[] x;} ModelFunction* modelfunc; // model function unsigned int n; // number of points float* y; // function values float* sigma; // uncertainty of function values float* x; // arguments of function }; struct GslData4Fit { gsl_multifit_fdfsolver *solver; gsl_matrix *covar; }; //////////////////////////////////////////////////////////////// bool ModelFunction::fit(const Array& yvals, const Array& ysigma, const Array& xvals, unsigned int max_iterations, double tolerance) { FunctionFit ff(*this,yvals.extent(firstDim),max_iterations,tolerance); return ff.fit(yvals,ysigma,xvals); } Array ModelFunction::get_function(const Array& xvals) const { int n=xvals.extent(firstDim); Array result(n); for(int i=0; i ModelFunction::defaultArray; //////////////////////////////////////////////////////////////// // functions to be used by GSL solver int FunctionFit_func_f (const gsl_vector * gv, void *params, gsl_vector * f) { // get current model function ModelData* data=(ModelData*)params; ModelFunction* modelfunc=data->modelfunc; unsigned int n_fitpars=modelfunc->numof_fitpars(); // set the fitting parameters in the model function for(unsigned int i=0; iget_fitpar(i).val=gsl_vector_get(gv, i); } // calculate vector of values for this set of parameters for (unsigned int i = 0; i < data->n; i++) { float Yi = modelfunc->evaluate_f(data->x[i]); gsl_vector_set (f, i, (data->y[i] - Yi)/data->sigma[i]); } return GSL_SUCCESS; } int FunctionFit_func_df (const gsl_vector * gv, void *params, gsl_matrix * df) { // get current model function ModelData* data=(ModelData*)params; ModelFunction* modelfunc=data->modelfunc; unsigned int n_fitpars=modelfunc->numof_fitpars(); // set the fitting parameters in the model function for(unsigned int i=0; iget_fitpar(i).val=gsl_vector_get(gv, i); } // calculate vector of derivative values for this set of parameters fvector dYi(n_fitpars); for (unsigned int i = 0; i < data->n; i++) { dYi = modelfunc->evaluate_df(data->x[i]); float s = data->sigma[i]; for(unsigned int j=0; jmodelfunc=&model_func; gsldata=new GslData4Fit; // allocate and initialize GSL stuff gsldata->covar = gsl_matrix_alloc (func.numof_fitpars(), func.numof_fitpars()); gsldata->solver = gsl_multifit_fdfsolver_alloc (gsl_multifit_fdfsolver_lmsder, data4fit->n, func.numof_fitpars()); } FunctionFit::~FunctionFit() { // free GSL stuff gsl_multifit_fdfsolver_free(gsldata->solver); gsl_matrix_free(gsldata->covar); delete data4fit; delete gsldata; } bool FunctionFit::fit(const Array& yvals, const Array& ysigma, const Array& xvals) { Log odinlog("FunctionFit","fit"); bool haveSigma; bool haveXvals; // check input if(data4fit->n!=(unsigned)yvals.size() || data4fit->n<=0) { ODINLOG(odinlog,errorLog) << "size mismatch in yvals" << STD_endl; return false; } if((unsigned)ysigma.size()==data4fit->n) haveSigma=true; else { haveSigma=false; ODINLOG(odinlog,normalDebug) << "no error bars provided, taking uniform interval for all x" << STD_endl; } if((unsigned)xvals.size()==data4fit->n) haveXvals=true; else { haveXvals=false; ODINLOG(odinlog,normalDebug) << "no x values provided, taking index as x value" << STD_endl; } ODINLOG(odinlog,normalDebug) << "n/numof_fitpars=" << data4fit->n << "/" << func.numof_fitpars() << STD_endl; // copy Blitz arrays to data4fit for (unsigned long i=0;in;i++) { data4fit->y[i]=yvals(i); if(haveSigma) data4fit->sigma[i]=ysigma(i); else data4fit->sigma[i]=0.1; if(haveXvals) data4fit->x[i]=xvals(i); else data4fit->x[i]=(float)i; } ODINLOG(odinlog,normalDebug) << "copy arrays done" << STD_endl; // initialize GSL fitting function gsl_multifit_function_fdf gsl_func; gsl_func.f=&FunctionFit_func_f; gsl_func.df=&FunctionFit_func_df; gsl_func.fdf=&FunctionFit_func_fdf; gsl_func.n=data4fit->n; gsl_func.p=func.numof_fitpars(); gsl_func.params=(void *)data4fit; ODINLOG(odinlog,normalDebug) << "gsl_func done" << STD_endl; // starting values double x_init[func.numof_fitpars()]; for(unsigned int i=0; isolver, &gsl_func, &initial_guess.vector); ODINLOG(odinlog,normalDebug) << "initialize solver done" << STD_endl; unsigned int iter = 0; int status; do { // main loop ODINLOG(odinlog,normalDebug) << "iter= " << iter << STD_endl; iter++; status = gsl_multifit_fdfsolver_iterate (gsldata->solver); ODINLOG(odinlog,normalDebug) << "status(fit)= " << gsl_strerror (status) << STD_endl; print_state (iter); if (status!=GSL_SUCCESS) break; status = gsl_multifit_test_delta (gsldata->solver->dx, gsldata->solver->x, tol, tol); ODINLOG(odinlog,normalDebug) << "status(test)= " << gsl_strerror (status) << STD_endl; ODINLOG(odinlog,normalDebug) << "iter/max_it= " << iter << "/" << max_it << STD_endl; } while (status == GSL_CONTINUE && iter < max_it); if(status!=GSL_SUCCESS && status!=GSL_ENOPROG) { // ignoring error 'iteration is not making progress towards solution' and taking intermediate result as best fit ODINLOG(odinlog,errorLog) << gsl_strerror(status) << STD_endl; return false; } gsl_multifit_covar (gsldata->solver->J, 0.0, gsldata->covar); // copy results for(unsigned int i=0;isolver->x, i); func.get_fitpar(i).err=sqrt(gsl_matrix_get(gsldata->covar,i,i)); } return true; } void FunctionFit::print_state (size_t iter) { #ifdef ODIN_DEBUG Log odinlog("FunctionFit","fit"); ODINLOG(odinlog,normalDebug) << "iter=" << iter << STD_endl; for(unsigned int i=0;i s(n); Array x(n); if(haveSigma) s=ysigma; else s=1.0; if(haveXvals) x=xvals; else for(int i=0; i s2(n); s2=s*s; float S= sum(1.0/(s2)); float Sx= sum(x /(s2)); float Sxx=sum(x*x/(s2)); ODINLOG(odinlog,normalDebug) << "S/Sx/Sxx=" << S << "/" << Sx << "/" << Sxx << STD_endl; float Sy= sum(yvals/(s2)); float Sxy=sum(x*yvals/(s2)); ODINLOG(odinlog,normalDebug) << "Sy/Sxy=" << Sy << "/" << Sxy << STD_endl; float Delta=S*Sxx - Sx*Sx; ODINLOG(odinlog,normalDebug) << "Delta=" << Delta << STD_endl; float beta=secureDivision(S*Sxy-Sx*Sy, Delta); float alpha=secureDivision(Sxx*Sy-Sx*Sxy, Delta); ODINLOG(odinlog,normalDebug) << "alpha/beta=" << beta << "/" << beta << STD_endl; Array summand(n); summand=(yvals-beta*x-alpha); summand*=summand; float ystdev=sqrt(secureInv(double(n)-2.0)*sum( summand )); ODINLOG(odinlog,normalDebug) << "ystdev=" << ystdev << STD_endl; float betastdev=ystdev*sqrt(1.0/( sum(x*x) - secureInv(n)*sum(x)*sum(x) )); ODINLOG(odinlog,normalDebug) << "betastdev=" << betastdev << STD_endl; float alphastdev=betastdev*sqrt( secureInv(n)*sum(x*x) ); ODINLOG(odinlog,normalDebug) << "alphastdev=" << alphastdev << STD_endl; m.val=beta; m.err=betastdev; c.val=alpha; c.err=alphastdev; return true; } Array LinearFunction::get_function(const Array& xvals) const { return Array(m.val * xvals + c.val); } const Array LinearFunction::defaultArray; ////////////////////////////////////////////////////////////// struct GslData4DownhillSimplex { gsl_vector* x; gsl_vector* ss; gsl_multimin_function minex_func; gsl_multimin_fminimizer* s; }; double DownhillSimplex_func_f(const gsl_vector * gv, void *params) { // get current model function const MinimizationFunction* minfunc=(const MinimizationFunction*)params; unsigned int n_fitpars=minfunc->numof_fitpars(); fvector x(n_fitpars); for(unsigned int i=0; ievaluate(x); } DownhillSimplex::DownhillSimplex(MinimizationFunction& function) { ndim=function.numof_fitpars(); gsldata=new GslData4DownhillSimplex; gsldata->x = gsl_vector_alloc(ndim); gsldata->ss = gsl_vector_alloc(ndim); gsldata->minex_func.n = ndim; gsldata->minex_func.f = &DownhillSimplex_func_f; gsldata->minex_func.params = &function; gsldata->s = gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex2, ndim); // newer algorithm, only available in recent GSL // gsldata->s = gsl_multimin_fminimizer_alloc(gsl_multimin_fminimizer_nmsimplex, ndim); } DownhillSimplex::~DownhillSimplex() { // free GSL stuff gsl_vector_free(gsldata->x); gsl_vector_free(gsldata->ss); gsl_multimin_fminimizer_free(gsldata->s); delete gsldata; } fvector DownhillSimplex::get_minimum_parameters(const fvector& starting_points, const fvector& step_size, float ftol, unsigned int nmax) { Log odinlog("DownhillSimplex","get_minimum_parameters"); fvector result(ndim); if(starting_points.size()!=ndim) { ODINLOG(odinlog,errorLog) << "size mismatch: starting_points.size()=" << starting_points.size() << ", ndim=" << ndim << STD_endl; return result; } if(step_size.size()!=ndim) { ODINLOG(odinlog,errorLog) << "size mismatch: starting_points.size()=" << starting_points.size() << ", ndim=" << ndim << STD_endl; return result; } for(unsigned int idim=0; idimx, idim, starting_points[idim]); gsl_vector_set (gsldata->ss, idim, step_size[idim]); } gsl_multimin_fminimizer_set (gsldata->s, &(gsldata->minex_func), gsldata->x, gsldata->ss); unsigned int niterations=0; int status; double size; do { niterations++; status = gsl_multimin_fminimizer_iterate(gsldata->s); if (status) break; size = gsl_multimin_fminimizer_size(gsldata->s); status = gsl_multimin_test_size(size, ftol); /* if (status == GSL_SUCCESS) { printf ("converged to minimum at\n"); } printf ("%5d %10.3e %10.3e f() = %7.3f size = %.3f\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), s->fval, size); */ } while (status == GSL_CONTINUE && niterations < nmax); for(unsigned int idim=0; idims->x, idim); ODINLOG(odinlog,normalDebug) << "result" << result << STD_endl; ODINLOG(odinlog,normalDebug) << "min value=" << gsldata->s->fval << STD_endl; return result; } ////////////////////////////////////////////////////////////// // Unit test #ifndef NO_UNIT_TEST class DownhillSimplexTestFunction : public MinimizationFunction { unsigned int numof_fitpars() const {return 2;} float evaluate(const fvector& xvec) const {return pow(xvec[0]-2.0,2)+pow(xvec[1]-3.0,2);} }; class FunctionFitTest : public UnitTest { public: FunctionFitTest() : UnitTest("FunctionFit") {} private: bool check() const { Log odinlog(this,"check"); int numoftestvals=5; ExponentialFunctionWithOffset expf_offset; FunctionFit expfit_offset(expf_offset,numoftestvals); Array yvals(numoftestvals); Array ysigma(numoftestvals); Array xvals(numoftestvals); // some arbitrary values for testing xvals(0)=0.1; yvals(0)=12.4; ysigma(0)=0.7; xvals(1)=1.2; yvals(1)=8.4; ysigma(1)=1.2; xvals(2)=1.9; yvals(2)=6.1; ysigma(2)=0.9; xvals(3)=3.0; yvals(3)=5.0; ysigma(3)=0.8; xvals(4)=4.1; yvals(4)=5.0; ysigma(4)=1.0; expf_offset.A.val=1.0; // starting value expf_offset.lambda.val=-1.0; // starting value expf_offset.C.val=1.0; // starting value if(!expfit_offset.fit(yvals,ysigma,xvals)) { ODINLOG(odinlog,errorLog) << "ExponentialFunctionWithOffset fit failed" << STD_endl; return false; } float A_expected=8.74419; float A_err_expected=1.32811; float lambda_expected=-0.76985; float lambda_err_expected=0.37922; float C_expected=4.33682; float C_err_expected=1.31881; STD_string A_str =ftos(expf_offset.A.val) +"+-"+ftos(expf_offset.A.err); STD_string A_expected_str =ftos(A_expected ) +"+-"+ftos(A_err_expected); STD_string lambda_str =ftos(expf_offset.lambda.val) +"+-"+ftos(expf_offset.lambda.err); STD_string lambda_expected_str=ftos(lambda_expected)+"+-"+ftos(lambda_err_expected); STD_string C_str =ftos(expf_offset.C.val) +"+-"+ftos(expf_offset.C.err); STD_string C_expected_str =ftos(C_expected) +"+-"+ftos(C_err_expected); /* // gives different results depending on the GSL version if(A_str !=A_expected_str) {ODINLOG(odinlog,errorLog) << "FunctionFit_check: ExponentialFunctionWithOffset failed: A=" << A_str << ", but expected A=" << A_expected_str << STD_endl; return false;} if(lambda_str!=lambda_expected_str) {ODINLOG(odinlog,errorLog) << "FunctionFit_check: ExponentialFunctionWithOffset failed: lambda=" << lambda_str << ", but expected lambda=" << lambda_expected_str << STD_endl; return false;} if(C_str !=C_expected_str) {ODINLOG(odinlog,errorLog) << "FunctionFit_check: ExponentialFunctionWithOffset failed: C=" << C_str << ", but expected C=" << C_expected_str << STD_endl; return false;} */ ///////////////////////////////////////////////////// int numoftestvals2=100; ExponentialFunction expf; FunctionFit expfit(expf,numoftestvals2); // arbitrary values for testing A_expected=44.5; lambda_expected=0.78; expf.A.val=A_expected; expf.lambda.val=lambda_expected; yvals.resize(numoftestvals2); ysigma.resize(numoftestvals2); xvals.resize(numoftestvals2); for(int i=0; i(ysigma3).autowrite("ysigma3.asc"); if(!polyf.fit(yvals3,ysigma3,xvals3)) { ODINLOG(odinlog,errorLog) << "PolynomialFunction fit failed" << STD_endl; return false; } for(int i=0; i1.0e-3) { ODINLOG(odinlog,errorLog) << "PolynomialFunction failed: a[" << i << "]=" << fitval << ", but expected " << expval << STD_endl; return false; } } ///////////////////////////////////////////////////// Array values(3,3); values=10.0; values(1,1)=0.0; Array reliability(3,3); reliability=1.0; reliability(1,1)=0.0; Data pfresult(3,3); pfresult=polyniomial_fit(values,reliability,1,2.0); if(fabs(pfresult(1,1)-10.0)>1.0e-3) { ODINLOG(odinlog,errorLog) << "values=" << values << STD_endl; ODINLOG(odinlog,errorLog) << "reliability=" << reliability << STD_endl; ODINLOG(odinlog,errorLog) << "pfresult=" << pfresult << STD_endl; ODINLOG(odinlog,errorLog) << "polyniomial_fit failed" << STD_endl; return false; } int testsize=20; Data testarray(testsize,testsize); Data testrelia(testsize,testsize); TinyVector index; for(int i=0; i1.0e-3) { ODINLOG(odinlog,errorLog) << "polyniomial_fit failed, diff=" << diff << STD_endl; return false; } ///////////////////////////////////////////////////// DownhillSimplexTestFunction dstf; DownhillSimplex ds(dstf); fvector starting_points(2); starting_points=0.0; fvector step_size(2); step_size=1.0; fvector dsresult=ds.get_minimum_parameters(starting_points, step_size); fvector dsexpected(2); dsexpected[0]=2.0; dsexpected[1]=3.0; float maxdiff=(dsresult-dsexpected).maxabs(); ODINLOG(odinlog,normalDebug) << "maxdiff=" << maxdiff << STD_endl; if((dsresult-dsexpected).maxabs()>1.0e-3) { ODINLOG(odinlog,errorLog) << "DownhillSimplex failed, result" << dsresult << ", but expected" << dsexpected << STD_endl; return false; } return true; } }; void alloc_FunctionFitTest() {new FunctionFitTest();} // create test instance #endif ////////////////////////////////////////////////////////////// #else #error "GNU Scientific library is missing!" #endif odin-1.8.5/odindata/fileio.cpp0000644000175000017500000010175211734622162013147 00000000000000#include "fileio.h" #include "utils.h" #include "complexdata.h" // for unit test #include #include #include #include const char* FileIO::get_compName() {return "FileIO";} LOGGROUNDWORK(FileIO) /////////////////////////////////////////////////////////////////////////////// void FileFormat::register_format() { svector suffs=suffix(); for(unsigned int i=0; i& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("FileFormat","read"); ODINLOG(odinlog,errorLog) << this->description() << "::read not implemented" << STD_endl; return -1; } int FileFormat::read(FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template) { Data data; Protocol prot(protocol_template); int result=this->read(data, filename, opts, prot); if(result<0) return -1; if(result>0) pdmap[prot].reference(data); // Ignore zero-size data, e.g. DICOMDIR return result; } int FileFormat::write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { Log odinlog("FileFormat","write"); ODINLOG(odinlog,errorLog) << this->description() << "::write not implemented" << STD_endl; return -1; } int FileFormat::write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { int result=0; svector fnames=create_unique_filenames(filename, pdmap, opts.fnamepar); int ifile=0; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { int writeresult=this->write(pdit->second, fnames[ifile], opts, pdit->first); if(writeresult<0) return writeresult; result+=writeresult; ifile++; } return result; } STD_string FileFormat::analyze_suffix(const STD_string& filename) { JDXfileName fname(filename); return fname.get_suffix(); } FileFormat* FileFormat::get_format(const STD_string& filename, const STD_string& override_suffix) { STD_string suffix; if(override_suffix==AUTODETECTSTR) { suffix=analyze_suffix(filename); } else { suffix=override_suffix; } if(formats.find(suffix)!=formats.end()) return formats[suffix]; return 0; } svector FileFormat::possible_formats() { svector result; result.resize(formats.size()); int index=0; for(STD_map::const_iterator it=formats.begin(); it!=formats.end(); ++it) { result[index]=it->first; index++; } return result; } STD_string FileFormat::formats_str(const STD_string& indent) { STD_string result; for(STD_map::const_iterator it=formats.begin(); it!=formats.end(); ++it) { result+=indent+(it->first)+" \t ("+it->second->description(); svector dialects=it->second->dialects(); if(dialects.size()) result+=", dialects: "+dialects.printbody(); result+=")\n"; } return result; } void FileFormat::format_error(const STD_string& filename) { Log odinlog("FileFormat","format_error"); ODINLOG(odinlog,errorLog) << "File extension >" << analyze_suffix(filename) << "< of file >" << filename << "< not recognized" << STD_endl; ODINLOG(odinlog,errorLog) << "Recognized file extensions (and formats) are" << STD_endl << formats_str("") << STD_endl; } svector FileFormat::create_unique_filenames(const STD_string& filename, const FileIO::ProtocolDataMap& pdmap, const STD_string& par) { Log odinlog("FileFormat","create_unique_filenames"); unsigned int nnames=pdmap.size(); svector result; result.resize(nnames); if(nnames==1) { result[0]=filename; return result; } STD_string serDesc; int serNum; // Get max series number int maxseries=0; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { pdit->first.study.get_Series(serDesc,serNum); maxseries=STD_max(maxseries,serNum); } svector pars; pars=tokens(par); int npars=pars.size(); // Create vector of strings "S[_]" STD_map namescount; svector unique_names; unique_names.resize(nnames); unsigned int iname=0; for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { pdit->first.study.get_Series(serDesc,serNum); for(unsigned int i=0;ifirst.printval(pars[ipar]), "\n", ""); // truncate after first newline } } if(namescount.find(str)==namescount.end()) namescount[str]=0; else namescount[str]++; unique_names[iname]=str; iname++; } // Make sure filenames are unique by appending enumeration, if neccessary STD_map uniqueindex; // separate count for each non-unique filename for(unsigned int i=0; i0) { if(uniqueindex.find(str)==uniqueindex.end()) uniqueindex[str]=0; else uniqueindex[str]++; unique_names[i]+="_"+itos(uniqueindex[str],ncount); } } // Decompose file name to insert unique name before first known prefix JDXfileName fname(filename); svector fmts=FileIO::autoformats(); JDXfileName bname=fname.get_basename_nosuffix(); STD_string fnamesuff(fname.get_suffix()); STD_string suffixstr; if(fnamesuff!="") suffixstr="."+fname.get_suffix(); ODINLOG(odinlog,normalDebug) << "suffixstr=" << suffixstr << STD_endl; bool known_fmt=true; while(known_fmt) { // split filename from right to left as long as known file extensions are detected STD_string suff=bname.get_suffix(); known_fmt=false; for(unsigned int i=0; i odinlog("FileFormat","voxel_extent"); float result; if(direction==sliceDirection) { if(geometry.get_Mode()==voxel_3d) { result=secureDivision(geometry.get_FOV(direction), size); } else { if(geometry.get_nSlices()>1) result=geometry.get_sliceDistance(); else result=geometry.get_sliceThickness(); } } else { result=secureDivision(geometry.get_FOV(direction), size); } ODINLOG(odinlog,normalDebug) << "result(" << directionLabel[direction] << ")=" << result << STD_endl; return result; } STD_map FileFormat::formats; ////////////////////////////////////////////////////////////////////////// void register_asc_format(); void register_dicom_format(); void register_gzip_format(); void register_hfss_format(); void register_jdx_format(); void register_mhd_format(); void register_mat_format(); void register_nifti_format(); void register_png_format(); void register_raw_format(); void register_Iris3D_format(); void register_vtk_format(); ////////////////////////////////////////////////////////////// struct FileFormatCreator : public StaticHandler { // functions to initialize/delete static members by the StaticHandler template class static void init_static() { register_asc_format(); register_dicom_format(); register_gzip_format(); register_jdx_format(); register_mhd_format(); register_mat_format(); register_nifti_format(); register_png_format(); register_Iris3D_format(); register_raw_format(); register_hfss_format(); register_vtk_format(); } static void destroy_static() {} }; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; ////////////////////////////////////////////////////////////////////////// int FileIO::autoread(ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template,ProgressMeter* progmeter) { Log odinlog("FileIO","autoread"); if(!checkdir(filename.c_str()) && filesize(filename.c_str())<=0) { ODINLOG(odinlog,errorLog) << "File " << filename << " not found or is empty" << STD_endl; return -1; } FileFormatCreator ffc; // for some reason, we needed a named object here instead of a plain constructor // override file suffix if jdx option is given STD_string suffix=opts.format; if(opts.jdx!="") suffix="smp"; int result=-1; if(checkdir(filename.c_str())) { result=read_dir(pdmap, filename, opts, protocol_template,progmeter); if(result<0) return -1; } else { FileFormat* ff=FileFormat::get_format(filename,suffix); if(!ff) { FileFormat::format_error(filename); return -1; } ODINLOG(odinlog,loglevel()) << "Reading format " << ff->description() << STD_endl; result=ff->read(pdmap, filename, opts, protocol_template); if(result<0) { ODINLOG(odinlog,errorLog) << "Cannot read file " << filename << STD_endl; return -1; } } ODINLOG(odinlog,normalDebug) << "slicedist=" << pdmap.begin()->first.geometry.get_sliceDistance() << STD_endl; ProtocolDataMap pdmapin(pdmap); pdmap.clear();unsigned short cnt=0; for(ProtocolDataMap::const_iterator pdit=pdmapin.begin(); pdit!=pdmapin.end(); ++pdit) { if(!pdit->second.size()) { ODINLOG(odinlog,errorLog) << "Zero-size data while reading " << filename << STD_endl; return -1; } TinyVector shape=pdit->second.shape(); Protocol prot(pdit->first); // overwrite extent in protocol prot.seqpars.set_NumOfRepetitions(shape(timeDim)); if(prot.geometry.get_Mode()==slicepack) prot.geometry.set_nSlices(shape(sliceDim)); else prot.seqpars.set_MatrixSize(sliceDirection,shape(sliceDim)); prot.seqpars.set_MatrixSize(phaseDirection,shape(phaseDim)); prot.seqpars.set_MatrixSize(readDirection,shape(readDim)); // Adjust total duration of sequence, only if uninitialized ODINLOG(odinlog,normalDebug) << "ExpDuration=" << prot.seqpars.get_ExpDuration() << STD_endl; prot.seqpars.set_ExpDuration(STD_max(prot.seqpars.get_ExpDuration(), shape(0)*prot.seqpars.get_RepetitionTime()/(60.0*1000.0))); // Set label of protocol to filename STD_string postfix; if(pdmapin.size()>1) postfix=":"+itos(cnt,pdmapin.size()-1); prot.set_label("Protocol of "+filename+postfix); const Data& data=pdit->second; if(!opts.fmap && data.is_filemapped()) { ODINLOG(odinlog,normalDebug) << "filemapped" << STD_endl; pdmap[prot].reference(data.copy()); } else { pdmap[prot].reference(data); } STD_string cntstr; if(pdmapin.size()>1) cntstr="#"+itos(cnt)+" "; ODINLOG(odinlog,loglevel()) << "Read dataset " << cntstr << "from file " << filename << " with dimensions " << shape << STD_endl; cnt++; } ODINLOG(odinlog,normalDebug) << "mem(read): " << Profiler::get_memory_usage() << STD_endl; // Extract only a certain dataset if requested int dset2extract=-1; if(opts.dset!="") { dset2extract=atoi(opts.dset.c_str()); if(dset2extract>=int(pdmap.size()) || dset2extract<0) { ODINLOG(odinlog,errorLog) << "Dataset to extract (" << dset2extract << ") out of range (" << pdmap.size() << ")" << STD_endl; return -1; } } if(dset2extract>=0) { ODINLOG(odinlog,loglevel()) << "Extracting dataset with index " << dset2extract << STD_endl; ProtocolDataMap pdmap_copy(pdmap); pdmap.clear(); int iset=0; for(ProtocolDataMap::const_iterator pdit=pdmap_copy.begin(); pdit!=pdmap_copy.end(); ++pdit) { if(dset2extract==iset) pdmap[pdit->first].reference(pdit->second); iset++; } } // filter on certain parameters in protocol if(opts.filter!="") { svector toks=tokens(opts.filter,'='); if(toks.size()==2) { ODINLOG(odinlog,loglevel()) << "Filtering data where parameter " << toks[0] << " contains " << toks[1] << STD_endl; ProtocolDataMap pdmap_copy(pdmap); pdmap.clear(); for(ProtocolDataMap::const_iterator pdit=pdmap_copy.begin(); pdit!=pdmap_copy.end(); ++pdit) { if(pdit->first.printval(toks[0]).find(toks[1])!=STD_string::npos) pdmap[pdit->first].reference(pdit->second); } } } ODINLOG(odinlog,normalDebug) << "mem(result): " << Profiler::get_memory_usage() << STD_endl; return result; } ////////////////////////////////////////////////////////////////////////// struct ImageKey : public UniqueIndex { double acquisition_time; double slice_loc; STD_string filename; STD_string datatype; ImageKey(double tt, double sl, const STD_string& fn, const STD_string& dt) : acquisition_time(tt), slice_loc(sl), filename(fn), datatype(dt) {} bool operator < (const ImageKey& ik) const { if(slice_loc!=ik.slice_loc) return (slice_loc > KeyImageMap; int FileIO::read_dir(ProtocolDataMap& pdmap, const STD_string& dirname, const FileReadOpts& opts, const Protocol& protocol_template,ProgressMeter* progmeter) { Log odinlog("FileIO","read_dir"); ODINLOG(odinlog,normalDebug) << "mem(start): " << Profiler::get_memory_usage() << STD_endl; Range all=Range::all(); int result=0; svector dirfiles=browse_dir(dirname,false,true); unsigned int nfiles=dirfiles.size(); if(!nfiles) { ODINLOG(odinlog,errorLog) << "No files found in directory " << dirname << STD_endl; return -1; } STD_map oneimagemap; // Use local options to skip some of the global autoread options FileReadOpts opts_copy=opts; opts_copy.dset=""; if(progmeter) progmeter->new_task( nfiles,"FileIO::read_dir"); for(unsigned int i=0; iincrease_counter(dirfilename.c_str())) break;//cancel if the ProgressMeter says so if(readresult<0) { ODINLOG(odinlog,warningLog) << "Ignoring unrecognized file " << dirfiles[i] << " while reading dir" << STD_endl; } else if(readresult>0) { // ignore files unrecognized by the plugin (e.g. DICOMDIR) // Iterate over protocol-data pairs for(ProtocolDataMap::const_iterator pdit=onepdmap.begin(); pdit!=onepdmap.end(); ++pdit) { const Protocol& onefileprot=pdit->first; const Data& onefiledata=pdit->second; KeyImageMap& imgmap=oneimagemap[onefileprot]; // Get/insert key-image map for this protocol // Check x- and y-size KeyImageMap::const_iterator it=imgmap.begin(); if(it!=imgmap.end()) { // only check size if there already is an entry in the key-image map if(it->second.extent(0)!=onefiledata.extent(phaseDim)) { ODINLOG(odinlog,errorLog) << "Files in dir have different ysize" << STD_endl; return -1; } if(it->second.extent(1)!=onefiledata.extent(readDim)) { ODINLOG(odinlog,errorLog) << "Files in dir have different xsize" << STD_endl; return -1; } } STD_string dtype_prot=onefileprot.system.get_data_type(); // Insert repetitions and slices separately into map for(int irep=0; irep& dataref=imgmap[ImageKey(acqstart,sliceloc,dirfilename,dtype_prot)]; dataref.resize(onefiledata.extent(phaseDim),onefiledata.extent(readDim)); dataref=onefiledata(irep,islice,all,all); if(!progmeter) { ODINLOG(odinlog,loglevel()) << "Read slice from file " << dirfiles[i] << " " << onefiledata.shape() << " with acquisition_start/slice_location=" << acqstart << "/" << sliceloc << STD_endl; } } } } // end iterating over protocol-data pairs } } // end iterating over files ODINLOG(odinlog,loglevel()) << "Found " << oneimagemap.size() << " protocol(s) while reading files:" << STD_endl; ODINLOG(odinlog,normalDebug) << "mem(read): " << Profiler::get_memory_usage() << STD_endl; // Iterate over separate protocols to combine data int protindex=0; for(STD_map::iterator it=oneimagemap.begin(); it!=oneimagemap.end(); ++it) { KeyImageMap::const_iterator imgit; Protocol prot(it->first); KeyImageMap& imgmap=it->second; // non-const to be cleared after retrieving data from it TinyVector shape; imgit=imgmap.begin(); if(imgit==imgmap.end()) { ODINLOG(odinlog,errorLog) << "Empty imgmap" << STD_endl; return -1; } shape(readDim)=imgit->second.extent(1); shape(phaseDim)=imgit->second.extent(0); // Get slice offsets and min acq time by iterating over images STD_list slice_offsets; STD_list datatypes; double min_acqstart=imgit->first.acquisition_time; double max_acqstart=imgit->first.acquisition_time; for(imgit=imgmap.begin(); imgit!=imgmap.end(); ++imgit) { slice_offsets.push_back(imgit->first.slice_loc); datatypes.push_back(imgit->first.datatype); min_acqstart=STD_min(min_acqstart,imgit->first.acquisition_time); max_acqstart=STD_max(max_acqstart,imgit->first.acquisition_time); } // Find datatype with highest resolution in final dataset and use it for all datasets datatypes.sort(); datatypes.unique(); STD_string dtype=TypeTraits::type2label((float)0); // default if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((u8bit) 0))!=datatypes.end()) dtype=TypeTraits::type2label((u8bit)0); if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((s8bit) 0))!=datatypes.end()) dtype=TypeTraits::type2label((s8bit)0); if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((u16bit)0))!=datatypes.end()) dtype=TypeTraits::type2label((u16bit)0); if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((s16bit)0))!=datatypes.end()) dtype=TypeTraits::type2label((s16bit)0); if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((u32bit)0))!=datatypes.end()) dtype=TypeTraits::type2label((u32bit)0); if(find(datatypes.begin(),datatypes.end(),TypeTraits::type2label((s32bit)0))!=datatypes.end()) dtype=TypeTraits::type2label((s32bit)0); if(datatypes.size()>1) { ODINLOG(odinlog,loglevel()) << "Using single datatype " << dtype << " for images with datatypes=" << svector(list2vector(datatypes)).printbody() << STD_endl; } prot.system.set_data_type(dtype); slice_offsets.sort(); slice_offsets.unique(); shape(sliceDim)=slice_offsets.size(); int ndatasets=imgmap.size(); shape(timeDim)=ndatasets/shape(sliceDim); // interpret remainder as time dimension ODINLOG(odinlog,loglevel()) << "ndatasets/shape(" << protindex << ")=" << ndatasets << "/" << shape << STD_endl; if(ndatasets!=(shape(timeDim)*shape(sliceDim))) { ODINLOG(odinlog,errorLog) << "Size mismatch, ndatasets(" << ndatasets << ")!=nreps(" << shape(timeDim) << ")*nslices(" << shape(sliceDim) << ")" << STD_endl; return -1; } // Insert slices into data according to their ordering Data data(shape); ODINLOG(odinlog,normalDebug) << "mem(data): " << Profiler::get_memory_usage() << STD_endl; int irep=0; int islice=0; STD_map sliceindexmap; // gets sorted according to temporal index for(imgit=imgmap.begin(); imgit!=imgmap.end(); ++imgit) { if(irep==0) sliceindexmap[imgit->first.acquisition_time]=islice; data(irep,islice,all,all)=imgit->second; result++; irep++; if(irep>=shape(timeDim)) { irep=0; islice++; if(islice>=shape(sliceDim)) islice=0; } } // set new acquisition start and duration prot.seqpars.set_AcquisitionStart(min_acqstart); ODINLOG(odinlog,normalDebug) << "min_acqstart: " << min_acqstart << " max_acqstart: " << max_acqstart << " dur: "<< max_acqstart - min_acqstart+ prot.seqpars.get_RepetitionTime()/1000 << STD_endl; prot.seqpars.set_ExpDuration( (max_acqstart - min_acqstart+ prot.seqpars.get_RepetitionTime()/1000 ) /60.0); // overwrite slice settings in protocol prot.geometry.set_nSlices(shape(sliceDim)); fvector slicevec=list2vector(slice_offsets); ODINLOG(odinlog,normalDebug) << "slicevec=" << slicevec.printbody() << STD_endl; if(slicevec.size()>1) { float slicedist=fabs(slicevec[1]-slicevec[0]); ODINLOG(odinlog,normalDebug) << "slicedist=" << slicedist << STD_endl; prot.geometry.set_sliceDistance(slicedist); } if(slicevec.size()>0) prot.geometry.set_offset(sliceDirection,0.5*(slicevec[0]+slicevec[slicevec.size()-1])); pdmap[prot].reference(data); // Finally, add data to protocol-data map imgmap.clear(); // save memory protindex++; } // end iterating over protocols ODINLOG(odinlog,normalDebug) << "mem(comb): " << Profiler::get_memory_usage() << STD_endl; return result; } ////////////////////////////////////////////////////////////////////////// int FileIO::autowrite(const ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { Log odinlog("FileIO","autowrite"); Range all=Range::all(); if(filename=="") { ODINLOG(odinlog,errorLog) << "Empty file name" << STD_endl; return -1; } FileFormatCreator ffc; FileFormat* ff=FileFormat::get_format(filename,opts.format); if(!ff) { FileFormat::format_error(filename); return -1; } if(opts.wprot!="") { svector protfnames=FileFormat::create_unique_filenames(opts.wprot, pdmap, opts.fnamepar); unsigned int ifile=0; for(ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { ODINLOG(odinlog,loglevel()) << "Storing protocol in file " << protfnames[ifile] << STD_endl; pdit->first.write(protfnames[ifile]); ifile++; } } // local copy to avoid recursion FileWriteOpts opts_copy(opts); opts_copy.split=false; ODINLOG(odinlog,loglevel()) << "Writing format " << ff->description() << STD_endl; int result=0; if(opts.split) { svector splitfnames=FileFormat::create_unique_filenames(filename, pdmap, opts.fnamepar); unsigned int ifile=0; for(ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { STD_string onefilename=splitfnames[ifile]; ODINLOG(odinlog,normalDebug) << "onefilename=" << onefilename << STD_endl; ProtocolDataMap mDummy; mDummy[pdit->first].reference(pdit->second); int writeresult=ff->write(mDummy, onefilename, opts_copy); if(writeresult<0) return -1; result+=writeresult; ODINLOG(odinlog,loglevel()) << "Wrote dataset to file " << onefilename << STD_endl; ifile++; } } else { result=ff->write(pdmap, filename, opts_copy); if(result<0) return -1; ODINLOG(odinlog,loglevel()) << "Wrote " << pdmap.size() << " dataset(s) to file " << filename << STD_endl; } return result; } ////////////////////////////////////////////////////////////// svector FileIO::autoformats() { Log odinlog("FileIO","autoread"); FileFormatCreator ffc; // for some reason, we needed a named object here instead of a plain constructor return FileFormat::possible_formats(); } ////////////////////////////////////////////////////////////// STD_string FileIO::autoformats_str(const STD_string& indent) { FileFormatCreator ffc; // for some reason, we needed a named object here instead of a plain constructor return FileFormat::formats_str(indent); } ////////////////////////////////////////////////////////////// bool FileIO::do_trace=true; STD_string FileFormat::selectDataType(const Protocol &prot,const FileWriteOpts& opts){ if(opts.datatype != AUTOTDATAYPESTR) return opts.datatype; else return prot.system.get_data_type(); } /////////////////////////////////////////////////////////////////////////////// // Unit Test #ifndef NO_UNIT_TEST ////////// General tests /////////////////////////////// class FileIOTest : public UnitTest { public: FileIOTest() : UnitTest("FileIO") {} private: bool check() const { Log odinlog(this,"check"); Range all=Range::all(); FileIO::set_trace_status(false); // disable logging to console // Testing whether files are sorted alphabetically according to their file name STD_string tmpdir(tempfile()); if(createdir(tmpdir.c_str())) return false; int testsize=16; Data testslice(1,1,testsize,testsize); int nfiles=22; for(int i=0; i testdirarr; if(testdirarr.autoread(tmpdir)<0) return false; TinyVector expected_shape(nfiles,1,testsize,testsize); if(testdirarr.shape()!=expected_shape) { ODINLOG(odinlog,errorLog) << "testdirarr.shape()=" << testdirarr.shape() << ", but expected " << expected_shape << STD_endl; return false; } for(int i=0; i1.0e-3) { ODINLOG(odinlog,errorLog) << "meanval(" << i << ")=" << meanval << ", but expected " << float(i) << STD_endl; return false; } } // Testing reading of complex data STD_string tmpfile(tempfile()+".float"); ComplexData<1> cdata(testsize); cdata=STD_complex(0.0,1.0); if(cdata.write(tmpfile)<0) return false; FileReadOpts opts; Data fdata; STD_map expected; expected["abs"]=1.0; expected["pha"]=0.5*PII; expected["real"]=0.0; expected["imag"]=1.0; for(STD_map::const_iterator it=expected.begin(); it!=expected.end(); ++it) { opts.cplx=it->first; if(fdata.autoread(tmpfile, opts)<0) return false; if(fdata.size()!=testsize) { ODINLOG(odinlog,errorLog) << "reading complex raw: size mismatch" << STD_endl; return false; } float meanval=mean(fdata); float expected=it->second; if(fabs(meanval-expected)>1.0e-3) { ODINLOG(odinlog,errorLog) << "reading complex raw: mean(" << opts.cplx.operator STD_string() << ")=" << meanval << ", but expected " << expected << STD_endl; return false; } } return true; } }; ////////// Format-specific tests /////////////////////////////// void create_fileio_testarr(Data& testarr, const TinyVector& shape) { testarr.resize(shape); testarr=0.0; for(int i=0; i indexvec=testarr.create_index(i); for(int j=0; j class FileIOFormatTest : public UnitTest { public: FileIOFormatTest(const STD_string& suff) : UnitTest(("FileIO "+suff).c_str()), suffix(suff) {} private: STD_string suffix; bool compare_arrays(const STD_string& test, const Data& a1, const Data& a2) const { Log odinlog(this,"compare_arrays"); if(a1.shape()!=a2.shape()) { ODINLOG(odinlog,errorLog) << test << " failed, shape mismatch:" << STD_endl; ODINLOG(odinlog,errorLog) << a1.shape() << " != " << a2.shape() << STD_endl; return false; } Data a1copy; a1.convert_to(a1copy); for(int i=0; i indexvec=a1.create_index(i); if(a1copy(indexvec)!=a2(indexvec)) { ODINLOG(odinlog,errorLog) << test << " failed, value mismatch at index " << indexvec << STD_endl; ODINLOG(odinlog,errorLog) << a1copy(indexvec) << " != " << a2(indexvec) << STD_endl; return false; } } return true; } bool check() const { Log odinlog(this,"check"); FileIO::set_trace_status(false); // disable logging to console STD_list > shapelst; shapelst.push_back(TinyVector(1,1,YSize,XSize)); if(!OnlyBitmap) { shapelst.push_back(TinyVector(3,4,YSize,XSize)); shapelst.push_back(TinyVector(1,4,YSize,XSize)); shapelst.push_back(TinyVector(3,1,YSize,XSize)); } for(STD_list >::const_iterator it=shapelst.begin(); it!=shapelst.end(); ++it) { FileReadOpts readopts; STD_string prefix(tempfile()); // separate name for each shape STD_string writefname=prefix+"."+suffix; STD_string readfname=writefname; if(ReadDir) { readfname=prefix+"_"+suffix; readopts.format=suffix; } Data testarr; create_fileio_testarr(testarr,*it); Data readdata; // simple write/read if(testarr.autowrite(writefname)<0) return false; if(readdata.autoread(readfname, readopts)<0) return false; if(!compare_arrays("autowrite/autoread("+readfname+")", testarr, readdata)) return false; // Testing whether geometry info is preserved if(!OnlyBitmap) { Protocol prot; Geometry& geo=prot.geometry; if(HasOrientation) { geo.set_orientation(-66.7, 78.2, -124.7); geo.set_offset(readDirection,22.7); geo.set_offset(phaseDirection,-5.9); geo.set_offset(sliceDirection,99.9); } geo.set_FOV(readDirection,192.6); geo.set_FOV(phaseDirection,200.2); geo.set_nSlices(testarr.extent(1)); geo.set_sliceDistance(6.1); if(HasSliceThick) { geo.set_sliceThickness(3.2); } else { geo.set_sliceThickness(6.1); // the same as slice distance } if(testarr.autowrite(writefname, FileWriteOpts(), &prot)<0) return false; Protocol readprot; if(readdata.autoread(readfname, readopts, &readprot)<0) return false; if(!compare_arrays("autowrite/autoread+geo("+readfname+")", testarr, readdata)) return false; Protocol protcopy(prot); // Create copy of protocol to use limited accuracy comparison of Protocol protcopy.geometry=readprot.geometry; // only geometry may differ if(!(prot==protcopy)) { // use limited accuracy comparison of Protocol ODINLOG(odinlog,errorLog) << "autowrite/autoread(geo)" << (*it) << " failed: prot.geometry=" << prot.geometry << "protcopy.geometry=" << protcopy.geometry << STD_endl; return false; } } } return true; } }; /////////////////////////////////////////////////////////////////////// void alloc_FileIOTest() { // create test instances new FileIOTest; new FileIOFormatTest<7, 13, double, false,false,true,true>("jdx"); #ifdef PNGSUPPORT new FileIOFormatTest<7, 13, u8bit, true,false,false,false>("png"); #endif #ifdef HAVE_LIBZ #ifndef STREAM_REPLACEMENT new FileIOFormatTest<7, 13, double, false,false,true,true>("jdx.gz"); #endif #endif #ifdef DICOMSUPPORT new FileIOFormatTest<16, 16, u16bit, false,true,true,true>("dcm"); // needs square matrix size #endif #ifdef NIFTISUPPORT new FileIOFormatTest<7, 13, double, false,false,true,false>("nii"); new FileIOFormatTest<7, 13, double, false,false,false,false>("hdr"); #ifdef HAVE_LIBZ #ifndef STREAM_REPLACEMENT new FileIOFormatTest<7, 13, double, false,false,true,false>("nii.gz"); #endif #endif #endif } #endif odin-1.8.5/odindata/filter_align.h0000644000175000017500000000271711322062337014000 00000000000000/*************************************************************************** filter_align.h - description ------------------- begin : Fri Jan 16 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_ALIGN_H #define FILTER_ALIGN_H #include class FilterAlign : public FilterStep { JDXfileName fname; JDXint blowup; STD_string label() const {return "align";} STD_string description() const {return "Align data to the geometry (voxel locations) of an external file";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterAlign();} void init(); }; #endif odin-1.8.5/odindata/filter_resize.cpp0000644000175000017500000000655711734622162014555 00000000000000#include "filter_resize.h" #include void FilterResize::init() { for(int i=0; i<3; i++) { newsize[i].set_description(STD_string(dataDimLabel[1+i])+"-size"); append_arg(newsize[i],"newsize"+itos(i)); } } bool FilterResize::process(Data& data, Protocol& prot) const { TinyVector oldshape(data.shape()); TinyVector newshape(data.shape()); for(int i=0; i<3; i++) newshape(1+i)=newsize[i]; data.congrid(newshape); // update stuff in the protocol after regridding prot.seqpars.set_MatrixSize(phaseDirection,newshape(phaseDim)); prot.seqpars.set_MatrixSize(readDirection,newshape(readDim)); if(prot.geometry.get_Mode()==slicepack) { prot.geometry.set_nSlices(newshape(sliceDim)); float distfactor=secureDivision(oldshape(sliceDim), newshape(sliceDim)); prot.geometry.set_sliceDistance(distfactor*prot.geometry.get_sliceDistance()); } else { prot.seqpars.set_MatrixSize(sliceDirection,newshape(sliceDim)); } return true; } //////////////////////////////////////////////////////////////////////////////// void FilterResample::init() { newsize.set_description("new size"); append_arg(newsize,"newsize"); } bool FilterResample::process(Data& data, Protocol& prot) const { TinyVector newshape(data.shape()); newshape(0)=newsize; data.congrid(newshape); // update stuff in the protocol after regridding prot.seqpars.set_NumOfRepetitions(newsize); return true; } //////////////////////////////////////////////////////////////////////////////// void FilterIsotrop::init() { size=0; size.set_description("voxelsize"); append_arg(size,"voxelsize"); } bool FilterIsotrop::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Geometry &geo=prot.geometry; TinyVector shape(data.shape()),newshape=shape; TinyVector vox_mult; TinyVector vox_size( FileFormat::voxel_extent(geo,sliceDirection, shape(sliceDim)), FileFormat::voxel_extent(geo,phaseDirection, shape(phaseDim)), FileFormat::voxel_extent(geo,readDirection, shape(readDim)) ); float m; if(size!=0)m=size; else m=min(vox_size); vox_mult=vox_size/m; ODINLOG(odinlog,normalDebug) << "current voxel_size: " << vox_size << STD_endl; ODINLOG(odinlog,normalDebug) << "shape scaling vector: " << vox_mult << STD_endl; for(dataDim d=readDim;d>timeDim;d=dataDim(d-1)) newshape(d)=(int)(vox_mult(d-1)*shape(d)); ODINLOG(odinlog,normalDebug) << "new shape: " << newshape << STD_endl; data.congrid(newshape); //prevent update (called by set_nSlices) from overriding FOVslice switch(geo.get_Mode()){ case slicepack: geo.set_sliceThickness(m); geo.set_sliceDistance(m); break; case voxel_3d: geo.set_FOV(sliceDirection,m*newshape(sliceDim)); } // update stuff in the protocol after regridding geo.set_nSlices(newshape(sliceDim)); prot.seqpars.set_MatrixSize(phaseDirection,newshape(phaseDim)); prot.seqpars.set_MatrixSize(readDirection,newshape(readDim)); ODINLOG(odinlog,normalDebug) << "new voxel_size: " << TinyVector( FileFormat::voxel_extent(geo,sliceDirection, data.shape()(sliceDim)), FileFormat::voxel_extent(geo,phaseDirection, data.shape()(phaseDim)), FileFormat::voxel_extent(geo,readDirection, data.shape()(readDim))) << STD_endl; return true; } odin-1.8.5/odindata/data.h0000644000175000017500000010144011734622163012251 00000000000000/*************************************************************************** data.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen & Michael von Mengershausen email : jochimse@cns.mpg.de mengers@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef DATA_H #define DATA_H #ifndef TJUTILS_CONFIG_H #define TJUTILS_CONFIG_H #include #endif #include #ifdef ODIN_DEBUG #define BZ_DEBUG #endif #include // include 1st to overwrite mutex defines // undef mutex defines #ifdef BZ_MUTEX_DECLARE #undef BZ_MUTEX_DECLARE #endif #ifdef BZ_MUTEX_INIT #undef BZ_MUTEX_INIT #endif #ifdef BZ_MUTEX_LOCK #undef BZ_MUTEX_LOCK #endif #ifdef BZ_MUTEX_UNLOCK #undef BZ_MUTEX_UNLOCK #endif #ifdef BZ_MUTEX_DESTROY #undef BZ_MUTEX_DESTROY #endif // do not use mutex in Blitz, even if pthread is available // to get consistent behaviour across all platforms #define BZ_MUTEX_DECLARE(name) #define BZ_MUTEX_INIT(name) #define BZ_MUTEX_LOCK(name) #define BZ_MUTEX_UNLOCK(name) #define BZ_MUTEX_DESTROY(name) #include #include // to use arithmetics of TinyVectors using namespace blitz; #include #include #include #include #include // some additional macros for complex numbers BZ_DECLARE_FUNCTION_RET (float2real, STD_complex); BZ_DECLARE_FUNCTION_RET (float2imag, STD_complex); BZ_DECLARE_FUNCTION_RET (creal, float) BZ_DECLARE_FUNCTION_RET (cimag, float) BZ_DECLARE_FUNCTION_RET (cabs, float) BZ_DECLARE_FUNCTION_RET (phase, float) BZ_DECLARE_FUNCTION (logc) BZ_DECLARE_FUNCTION (expc) BZ_DECLARE_FUNCTION (conjc) // Other useful macros BZ_DECLARE_FUNCTION2(secureDivision) BZ_DECLARE_FUNCTION (secureInv) #ifdef STL_REPLACEMENT BZ_DECLARE_ARRAY_ET_SCALAR_OPS(tjstd_complex) #endif /** * @addtogroup odindata * @{ */ /////////////////////////////////////////////////////// struct FileMapHandle { FileMapHandle() : fd(-1), offset(0), refcount(1) {} int fd; LONGEST_INT offset; // in bytes int refcount; Mutex mutex; // protect refcount }; /////////////////////////////////////////////////////// /** * This template class holds multidimensional data. In addition to functionality * provided by the Blitz Array class, it offers methods to read/write raw data * and and other file formats (nifti, vtk, ...) to/from a file. * In addition, uing a special constructor, the array can be associated with a block * of data on disk using the UNIX mmap functionality. In this case, any changes made * to the array will be automatically tranfered to the file. Please note that any * attempt to resize such an array will most likely cause a segmentation fault. * */ template class Data : public Array { public: /** * Constructs an array with the given dimensionality and initial value */ Data(const TinyVector& dimvec, const T& val=0) : Array(dimvec), fmap(0) {(*this)=val;} // Variable extent constructors Data() : fmap(0) {} Data(int extent1) : Array(extent1), fmap(0) {} Data(int extent1, int extent2) : Array(extent1,extent2), fmap(0) {} Data(int extent1, int extent2,int extent3) : Array(extent1,extent2,extent3), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4) : Array(extent1,extent2,extent3,extent4), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4,int extent5) : Array(extent1,extent2,extent3,extent4,extent5), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6) : Array(extent1,extent2,extent3,extent4,extent5,extent6), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7) : Array(extent1,extent2,extent3,extent4,extent5,extent6,extent7), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8) : Array(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8), fmap(0) {} Data(int extent1, int extent2,int extent3,int extent4,int extent5,int extent6,int extent7,int extent8,int extent9) : Array(extent1,extent2,extent3,extent4,extent5,extent6,extent7,extent8,extent9), fmap(0) {} /** * Maps the given file 'filename' into the newly created array via the the mmap function, * see the mmap man page for details. The mapping is abolish when the * array is destroyed (destructor). Other parameters: * - readonly : If true, file can only be read. If false, the file will be created if it does not exist * - shape : The extent in each dimension * - offset : Skip first 'offset' bytes */ Data(const STD_string& filename, bool readonly, const TinyVector& shape, LONGEST_INT offset=0 ); /** * Copy constructor */ Data(const Data& d) : fmap(0) {Data::reference(d);} /** * Copy constructor from Blitz::Array */ Data(const Array& a) : Array(a), fmap(0) {} /** * Constructor from an equivalent tjarray (\ref arrays). If rank of 'a' is smaller, extent will pe padded with 1 at front. */ Data(const tjarray,T>& a) : fmap(0) { (*this)=a;} /** * Constructor from expression template */ template Data(BZ_ETPARM(_bz_ArrayExpr) expr) : Array(expr), fmap(0) {} /** * Destructor */ ~Data(); /** * Assignment operator */ Data& operator = (const Data& d) {Array::operator=(d); return *this;} /** * Assignment operator from Blitz::Array */ Data& operator = (const Array& a) {Array::operator=(a); return *this;} /** * Fills all elements with 'val' */ Data& operator = (const T& val) {Array::operator=(val); return *this;} /** * Assignment operator for expression templates */ template inline Data& operator = (BZ_ETPARM(_bz_ArrayExpr) expr) { typedef _bz_typename T_expr::T_numtype T_numtype; evaluate(expr, _bz_update()); return *this; } /** * Assignment from an equivalent tjarray (\ref arrays). If rank of 'a' is smaller, extent will pe padded with 1 at front. */ Data& operator = (const tjarray,T>& a); // resolve ambiguities Array operator + (const Data& b) const {return Array(Array(*this)+Array(b));} Array operator - (const Data& b) const {return Array(Array(*this)-Array(b));} Array operator * (const Data& b) const {return Array(Array(*this)*Array(b));} Array operator / (const Data& b) const {return Array(Array(*this)/Array(b));} // resolve ambiguities Array operator + (const T& v) const {return Array(Array(*this)+v);} Array operator - (const T& v) const {return Array(Array(*this)-v);} Array operator * (const T& v) const {return Array(Array(*this)*v);} Array operator / (const T& v) const {return Array(Array(*this)/v);} /** * Reads the array from a raw data file 'filename' of type 'format' which can be one of * 's8bit, u8bit, s16bit, u16bit, s32bit, u32bit, float or double'. * No resizing is performed prior to reading. Skip the first 'offset' bytes. * - Return value: 0 if succesful, otherwise -1 */ int read(const STD_string& format,const STD_string& filename, LONGEST_INT offset=0); /** * Reads the array from a raw data file 'filename' of type 'T2'. * No resizing is performed prior to reading. Skip the first 'offset' bytes. * - Return value: 0 if succesful, otherwise -1 */ template int read(const STD_string& filename, LONGEST_INT offset=0); /** * Writes the array to a raw data file 'filename' of type 'format' which can be one of * 's8bit, u8bit, s16bit, u16bit, s32bit, u32bit, float or double'. * - Return value: 0 if succesful, otherwise -1 */ int write(const STD_string& format,const STD_string& filename, autoscaleOption scaleopt=autoscale) const; /** * Writes the array to a raw data file 'filename' of type 'T2'. * - Return value: 0 if succesful, otherwise -1 */ template int write(const STD_string& filename, autoscaleOption scaleopt=autoscale) const; /** * Writes the array to a raw data file 'filename' of type the same type as the array is. *The mode specifies whether an already existing file is overwritten, or the data is appended. * - Return value: 0 if succesful, otherwise -1 */ int write(const STD_string& filename, fopenMode mode=overwriteMode) const; /** * Writes the array as a formatted ASCII file to * 'filename', one value per line. If 'pre' is * of the same size as this, its values are * inserted before the value on each line, * and the values of 'post' are inserted after * the values of this array on each line. * Return value is -1 if an error occurs. */ int write_asc_file(const STD_string& filename, const Array& pre=defaultArray, const Array& post=defaultArray) const; /** * reads in white-space separated data from ASCII file, no resizing is performed prior to reading * Return value is -1 if an error occurs. */ int read_asc_file(const STD_string& filename); /** * Writes data set to file 'filename' in the format automatically detected by the given file extension. * Extra options can be given by 'opts' and protocol settings can be overwritten by 'prot'. * Returns number of slices, or -1 if it fails. */ int autowrite(const STD_string& filename, const FileWriteOpts& opts=FileWriteOpts(), const Protocol* prot=0) const; /** * Reads data set from file 'filename' assuming the format automatically detected by the given file extension. * Extra options can be given by 'opts' and protocol settings will be stored in 'prot'. * The progress meter 'progmeter' can be optionally specified to monitor the progress of the operation. * Returns number of slices sucessfully read, or -1 if it fails. */ int autoread(const STD_string& filename, const FileReadOpts& opts=FileReadOpts(), Protocol* prot=0, ProgressMeter* progmeter=0); /** * Returns true if the array is associated with a file on disk */ bool is_filemapped() const {return fmap;} /** * Exports this array into an equivalent tjarray (\ref arrays) */ operator tjarray,T> () const; /** * Creates an index vector according to a linear index for the whole array * by taking the shape into account. */ TinyVector create_index(unsigned long index) const; /** * Creates a linear index from an index vector */ unsigned long create_linear_index(const TinyVector& indexvec) const; /** * Shift the data by 'shift' pixels in dimension 'shift_dim'. The * data is shifted cyclically, i.e. the values which are shifted * out at one edge of the array will be shifted in on the other edge. */ void shift(unsigned int shift_dim, int shift); /** * Interpolate (or extrapolate) the data in the array to the new shape. * The interpolation is performed dimension-by-dimension using the GSL spline interpolation * routines. * Add extra shift 'subpixel_shift' in units of pixels on the destination grid if 'subpixel_shift' is non-null. * if 'left_to_right' is set to true, interpolation starts at the most left * dimension, i.e. at those with the highest index, down to the lowest index. * If set to false, interpolation is performed vice versa. */ void congrid(const TinyVector& newshape, const TinyVector* subpixel_shift=0, bool left_to_right=false); /** * Converts the array to type 'T2', with dimensionality 'N_rank2' and stores the result in 'dst'. * The scaling strategy can be specified by 'scaleopt'. * 'dst' will be unique, i.e. no other references to the array exist. * In addition to changing 'dst', a reference to the same array is returned for convenience. */ template Data& convert_to(Data& dst, autoscaleOption scaleopt=autoscale) const; // specialization which uses reference if type/rank are same and scale/offset==0.0 to reduce memory usage Data& convert_to(Data& dst, autoscaleOption scaleopt=autoscale) const; /** * Makes array unique and continuous and returns pointer to data */ T* c_array(); // Reimplemented Blitz::Array functions void reference(const Data& d); // dummy objects used for default arguments static Array defaultArray; private: void interpolate1dim(unsigned int dim, int newsize, float subpixel_shift); void detach_fmap(); FileMapHandle* fmap; }; template Array Data::defaultArray; /** @} */ /////////////////////////////////////////////////////////////////////////////// #ifdef STREAM_REPLACEMENT template inline STD_ostream& operator << (STD_ostream& s,const Array&) {return s;} template inline STD_ostream& operator << (STD_ostream& s,const TinyVector&) { return s;} inline STD_ostream& operator << (STD_ostream& s,const Range&) { return s;} #endif /////////////////////////////////////////////////////////////////////////////// /* * Create n-dim index from linear 'index' for a given 'shape' */ template TinyVector index2extent(const TinyVector& shape, unsigned int index) { TinyVector result; unsigned int temp=index; for(int i=N_rank-1;i>=0;i--){ result(i)=temp%shape(i); temp=temp/shape(i); } return result; } /////////////////////////////////////////////////////////////////////////////// // leave this function outside of class Data, otherwise it screws up // when using optimization template void convert_from_ptr(Data& dst, const T2* src, const TinyVector& shape, autoscaleOption scaleopt=autoscale) { Log odinlog("Data","convert_from_ptr"); int dstsize=product(shape); int srcsize=dstsize*Converter::get_elements((T)0)/Converter::get_elements((T2)0); ODINLOG(odinlog,normalDebug) << "dstsize/srcsize=" << dstsize << "/" << srcsize << STD_endl; dst.resize(shape); Converter::convert_array(src, dst.c_array(), srcsize, dstsize, scaleopt); } // specialization in case the type is the same template void convert_from_ptr(Data& dst, const T* src, const TinyVector& shape) { dst.reference(Array((T*)src, shape, duplicateData)); } //////////////////////////////////////////////////////////////////////////// template Data::Data(const STD_string& filename, bool readonly, const TinyVector& shape, LONGEST_INT offset ) : fmap(new FileMapHandle) { T* ptr=(T*)filemap(filename, (LONGEST_INT)product(shape)*sizeof(T), offset, readonly, fmap->fd); if(ptr && (fmap->fd)>=0) { // only negative file descriptor indicates filemap failure Array::reference(Array(ptr, shape, neverDeleteData)); fmap->offset=offset; } else { delete fmap; fmap=0; } } //////////////////////////////////////////////////////////////////////////// template void Data::detach_fmap() { Log odinlog("Data","detach_fmap"); if(fmap) { fmap->mutex.lock(); (fmap->refcount)--; ODINLOG(odinlog,normalDebug) << "fd/offset/refcount=" << fmap->fd << "/" << fmap->offset << "/" << fmap->refcount << STD_endl; if(!(fmap->refcount)) { fileunmap(fmap->fd, Array::data(), (LONGEST_INT)Array::size()*sizeof(T), fmap->offset); fmap->mutex.unlock(); delete fmap; fmap=0; } if(fmap) fmap->mutex.unlock(); } } //////////////////////////////////////////////////////////////////////////// template Data::~Data() { detach_fmap(); } //////////////////////////////////////////////////////////////////////////// template void Data::reference(const Data& d) { Log odinlog("Data","reference"); detach_fmap(); fmap=d.fmap; if(fmap) { MutexLock lock(fmap->mutex); (fmap->refcount)++; ODINLOG(odinlog,normalDebug) << "fmap->refcount=" << fmap->refcount << STD_endl; } Array::reference(d); } //////////////////////////////////////////////////////////////////////////// template Data& Data::operator = (const tjarray,T>& a) { Log odinlog("Data","="); if( a.dim() <= N_rank ) { ndim nn=a.get_extent(); int npad=N_rank-nn.dim(); ODINLOG(odinlog,normalDebug) << "npad=" << npad << STD_endl; for(int ipad=0; ipad tv; for(unsigned int i=0; i (filename); if(format==TypeTraits::type2label((s8bit)0)) return read (filename); if(format==TypeTraits::type2label((u16bit)0)) return read(filename); if(format==TypeTraits::type2label((s16bit)0)) return read(filename); if(format==TypeTraits::type2label((u32bit)0)) return read(filename); if(format==TypeTraits::type2label((s32bit)0)) return read(filename); if(format==TypeTraits::type2label((float)0)) return read (filename); if(format==TypeTraits::type2label((double)0)) return read(filename); ODINLOG(odinlog,errorLog) << "Unable to read file " << filename << " with data type " << format << STD_endl; return -1; } //////////////////////////////////////////////////////////////////////////// template template int Data::read(const STD_string& filename, LONGEST_INT offset) { Log odinlog("Data","read"); LONGEST_INT fsize=filesize(filename.c_str())-offset; LONGEST_INT nelements_file=fsize/sizeof(T2); LONGEST_INT length=product(Array::shape()); ODINLOG(odinlog,normalDebug) << "fsize / nelements_file / length = " << fsize << " / " << nelements_file << " / " << length << STD_endl; if(!length) return 0; if(nelements_file fileshape(Array::shape()); fileshape(N_rank-1) *= (Converter::get_elements((T)0)/Converter::get_elements((T2)0)); // Adjust extent of last dim for copmlex data Data filedata(filename, true, fileshape, offset); filedata.convert_to(*this); return 0; } //////////////////////////////////////////////////////////////////////////// template int Data::write(const STD_string& format, const STD_string& filename, autoscaleOption scaleopt) const { Log odinlog("Data","write"); if(format==TypeTraits::type2label((u8bit)0)) return write (filename,scaleopt); if(format==TypeTraits::type2label((s8bit)0)) return write (filename,scaleopt); if(format==TypeTraits::type2label((u16bit)0)) return write(filename,scaleopt); if(format==TypeTraits::type2label((s16bit)0)) return write(filename,scaleopt); if(format==TypeTraits::type2label((u32bit)0)) return write(filename,scaleopt); if(format==TypeTraits::type2label((s32bit)0)) return write(filename,scaleopt); if(format==TypeTraits::type2label((float)0)) return write (filename,scaleopt); if(format==TypeTraits::type2label((double)0)) return write(filename,scaleopt); ODINLOG(odinlog,errorLog) << "Unable to write file " << filename << " with data type " << format << STD_endl; return -1; } //////////////////////////////////////////////////////////////////////////// template int Data::write(const STD_string& filename, fopenMode mode) const { Log odinlog("Data","write"); if(filename=="") return 0; FILE* file_ptr=FOPEN(filename.c_str(),modestring(mode)); if(file_ptr==NULL) { ODINLOG(odinlog,errorLog) << "unable to create/open file >" << filename << "< - " << lasterr() << STD_endl; return -1; } Data data_copy(*this); // for contig memory LONGEST_INT nmemb=Array::numElements(); LONGEST_INT count=fwrite(data_copy.c_array(),sizeof(T),nmemb,file_ptr); if(count!=nmemb) { ODINLOG(odinlog,errorLog) << "unable to fwrite to file >" << filename << "< - " << lasterr() << STD_endl; return -1; } if(file_ptr!=NULL) fclose(file_ptr); return 0; } //////////////////////////////////////////////////////////////////////////// template template int Data::write(const STD_string& filename, autoscaleOption scaleopt) const { Log odinlog("Data","write"); rmfile(filename.c_str()); // remove old file to get new file size with mmap ODINLOG(odinlog,normalDebug) << "mem(pre): " << Profiler::get_memory_usage() << STD_endl; Data converted_data; convert_to(converted_data,scaleopt); ODINLOG(odinlog,normalDebug) << "mem(cnv): " << Profiler::get_memory_usage() << STD_endl; Data filedata(filename,false,converted_data.shape()); ODINLOG(odinlog,normalDebug) << "mem(map): " << Profiler::get_memory_usage() << STD_endl; filedata=converted_data; return 0; } //////////////////////////////////////////////////////////////////////////// template int Data::write_asc_file(const STD_string& filename, const Array& pre, const Array& post) const { bool have_pre=false; bool have_post=false; Data pre_data(pre); Data post_data(post); int n=Array::numElements(); if(pre_data.numElements()==n) have_pre=true; if(post_data.numElements()==n) have_post=true; STD_ofstream ofs(filename.c_str()); if(ofs.bad()) return -1; T val; for(int i=0; i int Data::read_asc_file(const STD_string& filename) { STD_ifstream ifs(filename.c_str()); if(ifs.bad()) return -1; STD_string valstr; for(int i=0; i::numElements(); i++) { if(ifs.bad()) return -1; ifs >> valstr; TypeTraits::string2type(valstr,(*this)(create_index(i))); } ifs.close(); return 0; } //////////////////////////////////////////////////////////////////////////// // Interface to FileIO functionality int fileio_autowrite(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol* prot); int fileio_autoread(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol* prot, ProgressMeter* progmeter); template int Data::autowrite(const STD_string& filename, const FileWriteOpts& opts, const Protocol* prot) const { Data filedata; convert_to(filedata); return fileio_autowrite(filedata, filename, opts, prot); } template int Data::autoread(const STD_string& filename, const FileReadOpts& opts, Protocol* prot, ProgressMeter* progmeter) { Data filedata; int result=fileio_autoread(filedata, filename, opts, prot, progmeter); if(result>0) filedata.convert_to(*this); return result; } //////////////////////////////////////////////////////////////////////////// template Data::operator tjarray,T> () const { tjarray,T> a; ndim nn(N_rank); for(unsigned int i=0; i::extent(i); a.redim(nn); for(unsigned int i=0;i template Data& Data::convert_to(Data& dst, autoscaleOption scaleopt) const { Log odinlog("Data","convert_to"); TinyVector newshape; newshape=1; for(int i=0; i<(N_rank-N_rank2+1); i++) { // collapse extra dims into first dim of new shape, including first dim int srcindex=i; if(srcindex>=0 && srcindex::extent(srcindex); } for(int i=0; i<(N_rank2-1); i++) { // Fill new shape with extents of original dim, except for the first dim int srcindex=N_rank-N_rank2+1+i; if(srcindex>=0 && srcindex::extent(srcindex); } // modify last dimension to account for different element sizes newshape(N_rank2-1)=newshape(N_rank2-1)*Converter::get_elements((T)0)/Converter::get_elements((T2)0); dst.resize(newshape); // dst will be unique now Data src_copy(*this); // make read/write copy of this Converter::convert_array(src_copy.c_array(), dst.c_array(), src_copy.numElements(), dst.numElements(), scaleopt); return dst; } // specialization which uses reference if type/rank are same and no scaling is necessary to reduce memory usage template Data& Data::convert_to(Data& dst, autoscaleOption scaleopt) const { Log odinlog("Data","convert_to"); if(scaleopt==noscale || !std::numeric_limits::is_integer) { ODINLOG(odinlog,normalDebug) << "Using reference" << STD_endl; dst.reference(*this); } else { Data src_copy(*this); // make read/write copy of this dst.resize(src_copy.shape()); // dst will be unique now Converter::convert_array(src_copy.c_array(), dst.c_array(), src_copy.numElements(), dst.numElements(), scaleopt); } return dst; } //////////////////////////////////////////////////////////////////////////// template TinyVector Data::create_index(unsigned long index) const { return index2extent(Array::shape(), index); } //////////////////////////////////////////////////////////////////////////// template unsigned long Data::create_linear_index(const TinyVector& indexvec) const { unsigned long totalIndex=0,subsize; TinyVector nn(Array::extent()); for(unsigned long i=0;i void Data::shift(unsigned int shift_dim, int shift) { Log odinlog("Data","shift"); if(!shift) return; if( shift_dim >= N_rank ){ ODINLOG(odinlog,errorLog) << "shift dimension(" << shift_dim << ") >= rank of data (" << N_rank << ") !\n"; return; } int shift_extent=Array::extent(shift_dim); int abs_shift=abs(shift); if(shift_extent < abs_shift){ ODINLOG(odinlog,errorLog) << "extent(" << shift_extent << ") less than shift(" << abs_shift << ") !\n"; return; } Data data_copy(Array::copy()); TinyVector index; for(int i=0; i::numElements(); i++) { index=create_index(i); T val=data_copy(index); int shiftindex=index(shift_dim)+shift; if(shiftindex>=shift_extent) shiftindex-=shift_extent; if(shiftindex<0) shiftindex+=shift_extent; index(shift_dim)=shiftindex; (*this)(index)=val; } } //////////////////////////////////////////////////////////////////////////// template void Data::congrid(const TinyVector& newshape, const TinyVector* subpixel_shift, bool left_to_right) { Log odinlog("Data","congrid"); for(int i=0;i::shape()(dim) && subpixel_shift==0.0) { ODINLOG(odinlog,normalDebug) << "interpolation not required" << STD_endl; return; } if(dim>=N_rank) { ODINLOG(odinlog,errorLog) << "dim is larger than N_rank" << STD_endl; return; } if(newsize<0) { ODINLOG(odinlog,errorLog) << "newsize is negative" << STD_endl; return; } Array olddata(*this); olddata.makeUnique(); TinyVector oldshape(olddata.shape()); int oldsize=oldshape(dim); TinyVector newshape(oldshape); newshape(dim)=newsize; resize(newshape); // This holds the the shape of the subspace which is orthogonal to direction 'dim' TinyVector ortho_shape(oldshape); ortho_shape(dim)=1; // The total number of elements in the orthogonal subspace unsigned long n_ortho=product(ortho_shape); ODINLOG(odinlog,normalDebug) << "n_ortho=" << n_ortho << STD_endl; TinyVector indexvec; T* oldoneline=new T[oldsize]; for(unsigned long iortho=0; iortho(ortho_shape,iortho); for(int j=0; j T* Data::c_array() { Log odinlog("Data","c_array"); bool need_copying=false; // check storage order TinyVectorord=Array::ordering(); for(int i=0; i::isRankStoredAscending(i)) need_copying=true; } // check for slicing if(!Array::isStorageContiguous()) need_copying=true; if(need_copying) { ODINLOG(odinlog,normalDebug) << "need_copying" << STD_endl; Data tmp(Array::shape()); tmp=(*this); // reference(copy()) would not be enough since it would preserve ordering reference(tmp); } return Array::data(); } #endif odin-1.8.5/odindata/fileio_gzip.cpp0000644000175000017500000001460411322062337014172 00000000000000#include "fileio.h" /* this based on the minigz-example by Jean-loup Gailly of the zlib distribution so hail him :-) (and see below for copyright notice) */ /* zlib.h -- interface of the 'zlib' general purpose compression library version 1.2.3, July 18th, 2005 Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. Jean-loup Gailly Mark Adler jloup@gzip.org madler@alumni.caltech.edu The data format used by the zlib library is described by RFCs (Request for Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ #ifdef HAVE_LIBZ #ifndef STREAM_REPLACEMENT #include #include struct GzipFormat : public FileFormat { STD_string description() const {return "GNU-Zip container for other formats";} svector suffix() const { svector result; result.resize(1); result[0]="gz"; return result; } svector dialects() const {return svector();} bool gz_compress(STD_ifstream &in, gzFile out) { Log odinlog("GzipFormat","gz_compress"); char *buf = new char[2048*1024]; int len; int err; bool ret=true; try { for ( in.read(buf, 2048*1024); (len = in.gcount()); in.read(buf, 2048*1024) ) { if (gzwrite(out, buf, len) != len) { ODINLOG(odinlog,errorLog) << gzerror(out, &err) << STD_endl; return false; } } if (in.bad()) { ODINLOG(odinlog,errorLog) <<"file read" << STD_endl;return false; } } catch(...) { delete[] buf; throw; } delete buf; return ret; } bool file_compress(STD_string infile, STD_string outfile) { Log odinlog("GzipFormat","file_compress"); STD_ifstream in(infile.c_str(), ios::binary); if (in == NULL) { ODINLOG(odinlog,errorLog) << infile.c_str() << STD_endl; return false; } gzFile out = gzopen(outfile.c_str(), "wb"); if (out == NULL) { ODINLOG(odinlog,errorLog) << "gzopen " << outfile << " failed" << STD_endl; return false; } bool ret=gz_compress(in, out); if (gzclose(out) != Z_OK) { ODINLOG(odinlog,errorLog) << "gzclose " << outfile << " failed" << STD_endl; return false; } else return ret; } bool gz_uncompress(gzFile in, STD_ofstream &out) { Log odinlog("GzipFormat","gz_uncompress"); char *buf=new char[2048*1024]; int len; int err; try { for ( len = gzread(in, buf, 2048*1024); len; len = gzread(in, buf, 2048*1024) ) { if (len < 0){ODINLOG(odinlog,errorLog) << gzerror(in, &err) << STD_endl;return false;} else { out.write(buf,len); if (out.bad()) {ODINLOG(odinlog,errorLog) << "file write" << STD_endl;return false;} } } } catch(...) { delete[] buf; throw; } delete[] buf; return true; } bool file_uncompress(STD_string infile,STD_string outfile) { Log odinlog("GzipFormat","file_uncompress"); gzFile in = gzopen(infile.c_str(), "rb"); if (in == NULL) { ODINLOG(odinlog,errorLog) << "gzopen " << infile << " failed" << STD_endl; return false; } STD_ofstream out(outfile.c_str(), ios::binary); if (out.bad()) { ODINLOG(odinlog,errorLog) << infile.c_str() << STD_endl; return false; } bool ret=gz_uncompress(in, out); if (gzclose(in) != Z_OK) { ODINLOG(odinlog,errorLog) << "gclose " << outfile << " failed" << STD_endl; return false; } return ret; } static STD_string tempfilename(STD_string filename) { const STD_string unzipped_suffix=JDXfileName(JDXfileName(filename).get_basename_nosuffix()).get_suffix(); return tempfile()+"."+unzipped_suffix; } int read(FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template) { Log odinlog("GzipFormat","read"); const STD_string tmpfile=tempfilename(filename); ODINLOG(odinlog,normalDebug) << "tmpfile=" << tmpfile << STD_endl; if(file_uncompress(filename,tmpfile)) { bool tracestat_cache=FileIO::get_trace_status(); FileIO::set_trace_status(false); // disable temporarily int result=FileIO::autoread(pdmap, tmpfile, opts, protocol_template); FileIO::set_trace_status(tracestat_cache); rmfile(tmpfile.c_str()); return result; } else { return -1; } } int write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { Log odinlog("GzipFormat","write"); const STD_string tmpfile=tempfilename(filename); ODINLOG(odinlog,normalDebug) << "tmpfile=" << tmpfile << STD_endl; bool tracestat_cache=FileIO::get_trace_status(); FileIO::set_trace_status(false); // disable temporarily int result=FileIO::autowrite(pdmap, tmpfile, opts); FileIO::set_trace_status(tracestat_cache); if(result>=0) { if(file_compress(tmpfile,filename)) { rmfile(tmpfile.c_str()); } else { const JDXfileName fname(filename); STD_string realname = fname.get_dirname() + SEPARATOR_STR +fname.get_basename_nosuffix(); ODINLOG(odinlog,infoLog) << " saving " << realname << STD_endl; movefile(tmpfile.c_str(), realname.c_str()); } } return result; } }; #endif #endif ////////////////////////////////////////////////////////////// void register_gzip_format() { #ifdef HAVE_LIBZ #ifndef STREAM_REPLACEMENT static GzipFormat gf; gf.register_format(); #endif #endif } odin-1.8.5/odindata/filter_splice.cpp0000644000175000017500000000556311725203122014516 00000000000000#include "filter_splice.h" #include "filter.h" void FilterSplice::init() { for(int i=0; i odinlog(c_label(),"process"); if(dir=="none") { ODINLOG(odinlog,errorLog) << "no dimension given for splice" << STD_endl; return false; } FileIO::ProtocolDataMap spliced_pdmap; for(FileIO::ProtocolDataMap::const_iterator it=pdmap.begin();it!=pdmap.end();it++) { const Protocol& prot=it->first; const Data& data=it->second; STD_string serDesc; int serNum; prot.study.get_Series(serDesc,serNum); if(serDesc!="") serDesc+="_"; TinyVector shape(data.shape()); int nsplice = shape(dir); TinyVector newshape(shape); newshape(dir)=1; direction protdir=direction(3-dir); dvector offsetvec; if(dir==sliceDim && prot.geometry.get_Mode()==slicepack) offsetvec=prot.geometry.get_sliceOffsetVector(); // better accuracy in slicepack mode float origoffset=0.0; float voxelsize=0.0; if(dir!=timeDim) { origoffset=prot.geometry.get_offset(protdir); voxelsize=FileFormat::voxel_extent(prot.geometry, protdir, nsplice); ODINLOG(odinlog,normalDebug) << "origoffset/voxelsize=" << origoffset << "/" << voxelsize << STD_endl; } for(int isplice=0; isplice spliced(newshape); TinyVector lowerBounds; TinyVector upperBounds; for(int i=0; i<4; i++) { lowerBounds(i)=0; upperBounds(i)=shape(i)-1; } lowerBounds(dir)=upperBounds(dir)=isplice; spliced=data(RectDomain<4>(lowerBounds, upperBounds)); // Adjust series description protcopy.study.set_Series(serDesc+dataDimLabel[dir]+itos(isplice,nsplice-1),serNum); // Adjusting protocol if(dir==timeDim) { protcopy.seqpars.set_NumOfRepetitions(1); protcopy.seqpars.set_AcquisitionStart(prot.seqpars.get_AcquisitionStart()+isplice*prot.seqpars.get_RepetitionTime()); } else { if(dir==sliceDim) protcopy.geometry.set_nSlices(1); protcopy.seqpars.set_MatrixSize(protdir,1); protcopy.geometry.set_FOV(protdir,voxelsize); if(offsetvec.size()) { protcopy.geometry.set_offset(protdir, offsetvec[isplice]); } else { float ioffset=float(isplice)-0.5*float(nsplice-1); protcopy.geometry.set_offset(protdir, origoffset+ioffset*voxelsize); } } spliced_pdmap[protcopy].reference(spliced); } } pdmap=spliced_pdmap; return true; } odin-1.8.5/odindata/fileio_nifti.cpp0000644000175000017500000003624011322062337014332 00000000000000#include "fileio.h" #include "filter.h" #ifdef NIFTISUPPORT #include ///////////////////////////////////////////////////////////// struct NiftiFormat : public FileFormat{ STD_string description() const {return "NIFTI/ANALYZE";} svector suffix() const{ svector result; result.resize(2); result[0]="nii"; result[1]="hdr"; return result; } svector dialects() const{ svector result; result.resize(1); result[0]="fsl"; return result; } float read_orientation(const nifti_image &ni,Geometry &geometry, const FileReadOpts& opts) { Log odinlog("NiftiFormat","read_orientation"); float spatscale=1.0; if(ni.xyz_units==NIFTI_UNITS_METER) spatscale=1.0e3; if(ni.xyz_units==NIFTI_UNITS_MICRON) spatscale=1.0e-3; //@todo check me geometry.set_FOV(readDirection,ni.dx*spatscale*ni.dim[1]); geometry.set_FOV(phaseDirection,ni.dy*spatscale*ni.dim[2]); geometry.set_sliceThickness(ni.dz*spatscale); geometry.set_sliceDistance(ni.dz*spatscale); //no interslice distance in nifti - so use thickness geometry.set_nSlices(ni.dim[3]); if(ni.nifti_type>0) { // only for non-ANALYZE dvector readvec(3),phasevec(3),slicevec(3),centervec(3); // RotMatrix scaleMat;//method 2 if(ni.qform_code>0) {// just tranform to the nominal space of the scanner ODINLOG(odinlog,normalDebug) << "Reading orientation from qform" << STD_endl; for(unsigned short i=0;i<3;i++) { readvec[i] =ni.qto_xyz.m[i][0]/ni.dx; phasevec[i] =ni.qto_xyz.m[i][1]/ni.dy; slicevec[i] =ni.qto_xyz.m[i][2]/ni.dz; centervec[i]=ni.qto_xyz.m[i][3]*spatscale; } } else if(ni.sform_code>0) { // method 3 ODINLOG(odinlog,normalDebug) << "Reading orientation from sform" << STD_endl; for(unsigned short i=0;i<3;i++) { readvec[i] =ni.sto_xyz.m[i][0]/ni.dx; phasevec[i] =ni.sto_xyz.m[i][1]/ni.dy; slicevec[i] =ni.sto_xyz.m[i][2]/ni.dz; centervec[i]=ni.sto_xyz.m[i][3]*spatscale; } } else { ODINLOG(odinlog,infoLog) << "can't read Orientation"<< STD_endl; } const dvector ivector =//diagonale trougth the image in "normal" space (geometry.get_FOV(readDirection)-ni.dx)*readvec+ (geometry.get_FOV(phaseDirection)-ni.dy)*phasevec+ (geometry.get_FOV(sliceDirection)-ni.dz)*slicevec; centervec+=ivector/2; ODINLOG(odinlog,normalDebug) << "FOV read/phase/slice:"<< geometry.get_FOV(readDirection) << "/" << geometry.get_FOV(phaseDirection) << "/" << geometry.get_FOV(sliceDirection) << STD_endl; ODINLOG(odinlog,normalDebug) << "readvec:" << readvec.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "phasevec:"<< phasevec.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "slicevec:"<< slicevec.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "image diagonale "<< ivector.printbody() <<"/" << sqrt(ivector[0]*ivector[0]+ivector[1]*ivector[1]+ivector[2]*ivector[2])<< STD_endl; ODINLOG(odinlog,normalDebug) << "center " << centervec.printbody() << STD_endl; // @todo should be set here // for(unsigned short i=0;i<3;i++) // scaleMat[i][i]=1/ni.pixdim[i+1]; geometry.set_orientation_and_offset(readvec,phasevec,slicevec,centervec); ODINLOG(odinlog,normalDebug) << "set up gradrot matrix " << geometry.get_gradrotmatrix().print() << STD_endl; ODINLOG(odinlog,normalDebug) << "set up center (offset) " << geometry.get_center().printbody() << STD_endl; return ni.scl_slope?:1; } return 1; } template void copy_from(const T* src,Data &dst, const FileReadOpts& opts) { convert_from_ptr(dst, src, dst.shape()); } int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("NiftiFormat","read"); nifti_image* ni=nifti_image_read(filename.c_str(), true); float scale=read_orientation(*ni,prot.geometry,opts); data.resize( ni->ndim>=4 ? ni->dim[4]:1, ni->ndim>=3 ? ni->dim[3]:1, ni->ndim>=2 ? ni->dim[2]:1, ni->dim[1] ); const TinyVector shape(data.shape()); ODINLOG(odinlog,normalDebug) << "shape/ndim=" << shape << "/" << ni->ndim << STD_endl; if(ni->nvox!=product(shape)) ODINLOG(odinlog,errorLog) << "ni->nvox=" << ni->nvox << " != product(shape)=" << product(shape) << STD_endl; STD_string type; //copy ni->data to data switch(ni->datatype) { case DT_UINT8: type=TypeTraits::type2label((u8bit)0); copy_from((u8bit*)ni->data, data,opts); break; case DT_INT8: type=TypeTraits::type2label((s8bit)0); copy_from((s8bit*)ni->data, data,opts); break; case DT_UINT16: type=TypeTraits::type2label((u16bit)0); copy_from((u16bit*)ni->data, data,opts); break; case DT_INT16: type=TypeTraits::type2label((s16bit)0); copy_from((s16bit*)ni->data, data,opts); break; case DT_UINT32: type=TypeTraits::type2label((u32bit)0); copy_from((u32bit*)ni->data, data,opts); break; case DT_INT32: type=TypeTraits::type2label((s32bit)0); copy_from((s32bit*)ni->data, data,opts); break; case DT_FLOAT32: type=TypeTraits::type2label((float)0); copy_from((float*)ni->data, data,opts); break; case DT_FLOAT64: type=TypeTraits::type2label((double)0); copy_from((double*)ni->data, data,opts); break; default: ODINLOG(odinlog,errorLog) << "Unsupported datatype " << ni->datatype << STD_endl; return -1; break; } ODINLOG(odinlog,normalDebug) << "type=" << type << STD_endl; if(type=="")return -1; //scale data data*=scale; //set some metadata prot.system.set_data_type(type); prot.seqpars.set_NumOfRepetitions(ni->dim[4]); float timescale=1.0; if(ni->time_units==NIFTI_UNITS_SEC) timescale=1.0e3; if(ni->time_units==NIFTI_UNITS_USEC) timescale=1.0e-3; prot.seqpars.set_RepetitionTime(timescale*ni->dt); nifti_image_free(ni); return shape(0)*shape(1); } void store_orientation(nifti_image &ni,const Data& data,const Geometry &geometry, const FileWriteOpts& opts) { Log odinlog("NiftiFormat","store_orientation"); ni.sform_code=ni.qform_code=NIFTI_XFORM_SCANNER_ANAT; //set scanner aligned space const RotMatrix rot(geometry.get_gradrotmatrix());//orientation of the image in "normal" space const TinyVector shape(data.shape());//size of the image in voxels const dvector center(geometry.get_center());//position of the image in "normal" space ni.dx=ni.pixdim[1]=voxel_extent(geometry,readDirection, shape(3)); ni.dy=ni.pixdim[2]=voxel_extent(geometry,phaseDirection, shape(2)); ni.dz=ni.pixdim[3]=voxel_extent(geometry,sliceDirection, shape(1)); const dvector ivector =//diagonale trougth the image (from first voxel, to the last) in "normal" space (geometry.get_FOV(readDirection)-ni.dx)*geometry.get_readVector()+ (geometry.get_FOV(phaseDirection)-ni.dy)*geometry.get_phaseVector()+ (geometry.get_FOV(sliceDirection)-ni.dz)*geometry.get_sliceVector(); // double heightAng,azimutAng,inplaneAng; // geometry.get_orientation(heightAng,azimutAng,inplaneAng); ODINLOG(odinlog,normalDebug) << "get_gradrotmatrix "<< rot.print() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_readVector "<< geometry.get_readVector().printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_phaseVector "<< geometry.get_phaseVector().printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_sliceVector "<< geometry.get_sliceVector().printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "get_center "<< center.printbody() << STD_endl; ODINLOG(odinlog,normalDebug) << "FOV read/phase/slice "<< geometry.get_FOV(readDirection) << "/" << geometry.get_FOV(phaseDirection) << "/" << geometry.get_FOV(sliceDirection) << STD_endl; ODINLOG(odinlog,normalDebug) << "image diagonale "<< ivector.printbody() <<"/" << sqrt(ivector[0]*ivector[0]+ivector[1]*ivector[1]+ivector[2]*ivector[2])<< STD_endl; // ODINLOG(odinlog,normalDebug) << "heightAng,azimutAng,inplaneAng " << heightAng << "," << azimutAng << "," << inplaneAng << STD_endl; //create space tranformation matrices - transforms the space when reading _NOT_ the data //@todo maybe we can get the quaternions directly from the given rotation angles for(int y =0;y<3;y++) { ni.qto_xyz.m[0][y]=rot[0][y]; ni.qto_xyz.m[1][y]=rot[1][y]; ni.qto_xyz.m[2][y]=rot[2][y]; ni.qto_xyz.m[y][3]=center[y]-ivector[y]/2; } memcpy(ni.sto_xyz.m,ni.qto_xyz.m,sizeof(ni.sto_xyz.m)); //add scaling to the sform for(int y =0;y<3;y++){ ni.sto_xyz.m[0][y]*=ni.pixdim[1+y]; ni.sto_xyz.m[1][y]*=ni.pixdim[1+y]; ni.sto_xyz.m[2][y]*=ni.pixdim[1+y]; } ni.dx=ni.pixdim[1]; ni.dy=ni.pixdim[2]; ni.dz=ni.pixdim[3]; //generate matching quaternions nifti_mat44_to_quatern( ni.qto_xyz, &ni.quatern_b,&ni.quatern_c,&ni.quatern_d, &ni.qoffset_x,&ni.qoffset_y,&ni.qoffset_z, NULL,NULL,NULL, &ni.qfac); } template void* copy_to(Data &src,Data &dst,nifti_image &ni, Geometry& geo,const FileWriteOpts& opts) { Log odinlog("NiftiFormat","copy_to"); src.convert_to(dst,noupscale); const TinyVector shape(src.shape()); ni.ndim=ni.dim[0]=shape(0)>1 ? 4:3; ni.nx=ni.dim[1]=shape(3); ni.ny=ni.dim[2]=shape(2); ni.nz=ni.dim[3]=shape(1); ni.nt=ni.dim[4]=shape(0); //@todo - is already done in autoscaled conversion - waste of time ni.cal_max = max(dst); ni.cal_min = min(dst); ni.nvox=product(shape); //and return pointer to the converted data return dst.c_array(); } int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { Log odinlog("NiftiFormat","write"); STD_string type=selectDataType(prot,opts); JDXfileName fname(filename); Protocol protcopy(prot); Geometry& geo=protcopy.geometry; Data src(data); nifti_image ni; memset(&ni,0, sizeof(nifti_image)); //set everything to zero - default value for "not used" ni.nu=ni.nv=ni.nw=1; if(tolowerstr(opts.dialect)=="fsl") { bool do_transform=false; STD_string sppart="s,p"; if(geo.get_orientation()==sagittal || geo.get_orientation()==coronal) { ODINLOG(odinlog,infoLog) << "Rotating around read axis for fsl dialect" << STD_endl; sppart="p-,s"; do_transform=true; } STD_string rsign; double heightAng, azimutAng, inplaneAng; bool revSlice; geo.get_orientation(heightAng, azimutAng, inplaneAng, revSlice); if(!revSlice) { // FSL needs 'radiological' handness ODINLOG(odinlog,infoLog) << "Reversing handness for fsl dialect" << STD_endl; rsign="-"; do_transform=true; } if(do_transform) FilterChain("-swapdim "+sppart+",r"+rsign+"").apply(protcopy,src); } // Compatabilty with FSL STD_string newtype; if(IS_TYPE(s8bit,type)) newtype=TypeTraits::type2label((u8bit)0); else if(IS_TYPE(u16bit,type)) newtype=TypeTraits::type2label((s16bit)0); else if(IS_TYPE(u32bit,type)) newtype=TypeTraits::type2label((s32bit)0); if(newtype!="") { if(tolowerstr(opts.dialect)=="fsl" || fname.get_suffix()=="hdr") { ODINLOG(odinlog,infoLog) << "data type " << type << " is not supported, falling back to " << newtype << STD_endl; type=newtype; } else { ODINLOG(odinlog,warningLog) << "data type " << type << " is not supported in FSL, use '-wdialect fsl' to correct this" << STD_endl; } } store_orientation(ni,src,geo,opts); //dummies to keep the data ni.data points to Data< u8bit,4> u8bit_data; Data< s8bit,4> s8bit_data; Data u16bit_data; Data s16bit_data; Data u32bit_data; Data s32bit_data; Data< float,4> float_data; Data double_data; ni.datatype=DT_UNKNOWN; if( IS_TYPE( u8bit,type)) {ni.datatype=DT_UINT8; ni.data=copy_to(src, u8bit_data,ni,geo,opts);} else if(IS_TYPE( s8bit,type)) {ni.datatype=DT_INT8; ni.data=copy_to(src, s8bit_data,ni,geo,opts);} else if(IS_TYPE(u16bit,type)) {ni.datatype=DT_UINT16; ni.data=copy_to(src,u16bit_data,ni,geo,opts);} else if(IS_TYPE(s16bit,type)) {ni.datatype=DT_INT16; ni.data=copy_to(src,s16bit_data,ni,geo,opts);} else if(IS_TYPE(u32bit,type)) {ni.datatype=DT_UINT32; ni.data=copy_to(src,u32bit_data,ni,geo,opts);} else if(IS_TYPE(s32bit,type)) {ni.datatype=DT_INT32; ni.data=copy_to(src,s32bit_data,ni,geo,opts);} else if(IS_TYPE(float,type)) {ni.datatype=DT_FLOAT32;ni.data=copy_to(src, float_data,ni,geo,opts);} else if(IS_TYPE(double,type)) {ni.datatype=DT_FLOAT64;ni.data=copy_to(src,double_data,ni,geo,opts);} ni.nbyper=TypeTraits::typesize(type); ODINLOG(odinlog,normalDebug) << "nbyper/datatype=" << ni.nbyper << "/" << ni.datatype << STD_endl; ODINLOG(odinlog,normalDebug) << "ni.pixdim[1/2/3]=" << ni.pixdim[1] << "/" << ni.pixdim[2] << "/" << ni.pixdim[3] << STD_endl; if(src.extent(0)) ni.dt=ni.pixdim[4] = prot.seqpars.get_RepetitionTime(); //@todo we could save scale and offset here - intead of autoscale ni.scl_slope=1; ni.scl_inter=0.0;// http://209.85.135.104/search?q=cache:AxBp5gn9GzoJ:nifti.nimh.nih.gov/board/read.php%3Ff%3D1%26i%3D57%26t%3D57+nifti-1+scl_slope&hl=en&ct=clnk&cd=1&client=iceweasel-a ni.freq_dim=1; ni.phase_dim=2; ni.slice_dim=3; ni.xyz_units=NIFTI_UNITS_MM; ni.time_units=NIFTI_UNITS_MSEC; ni.fname=(char*)filename.c_str(); STD_string imgfile; // Keep in scope for valid char* pointer if(fname.get_suffix()=="hdr") { ni.nifti_type=0; // ANALYZE imgfile=fname.get_dirname()+SEPARATOR_STR+fname.get_basename_nosuffix()+".img"; ODINLOG(odinlog,normalDebug) << "imgfile=" << imgfile << STD_endl; ni.iname=(char*)imgfile.c_str(); } else { ni.nifti_type=1; // NIFTI ni.iname=(char*)filename.c_str(); } STD_string studydescr; STD_string physician; prot.study.get_Context(studydescr, physician); snprintf(ni.descrip, 80, "%s", studydescr.c_str()); STD_string seriesdescr; int seriesnr; prot.study.get_Series(seriesdescr, seriesnr); snprintf(ni.intent_name, 16, "%s", seriesdescr.c_str()); errno=0; //reset errno nifti_image_write(&ni); //write the image - in case of a failure errno should be set if(errno) { //if so, tell the user, clean up and return -1 ODINLOG(odinlog,errorLog) << "Could not write to "<< filename << "(" <, (C) 2008 // // Copyright: See COPYING file that comes with this distribution // // #ifndef FILTER_RESLICE_H #define FILTER_RESLICE_H #include class FilterReSlice : public FilterStep { JDXenum orient; STD_string label() const {return "reslice";} STD_string description() const {return "reslices the image to a given orientation";} bool process(Data& data, Protocol& prot)const; FilterStep* allocate() const {return new FilterReSlice();} void init(); }; ///////////////////////////////////////////////////////////////////////////// class FilterSwapdim : public FilterStep { JDXstring newread,newphase,newslice; STD_string label() const {return "swapdim";} STD_string description() const {return "swap/reflect dimensions by specifying a direction triple with optional reflection sign appended";} bool process(Data& data, Protocol& prot)const; FilterStep* allocate() const {return new FilterSwapdim();} static bool selChannel(STD_string name, direction &dir, int& sign); void init(); }; #endif odin-1.8.5/odindata/filter_reduction.h0000644000175000017500000000613211725203122014671 00000000000000/*************************************************************************** filter_reduction.h - description ------------------- begin : Fri Feb 26 2010 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_REDUCTION_H #define FILTER_REDUCTION_H enum reductionOp { minip=0, maxip, proj }; static const char* reductionOpLabel[]={"minip", "maxip", "proj"}; #include template class FilterReduction : public FilterStep { JDXenum dir; STD_string label() const {return reductionOpLabel[Op];} STD_string description() const { STD_string opstr; if(Op==minip) opstr="minimum intensity "; if(Op==maxip) opstr="maximum intensity "; return "Perform "+opstr+"projection over given direction"; } void init() { for(int i=0; i& data, Protocol& prot) const { Log odinlog(c_label(),"process"); if(dir=="none"){ ODINLOG(odinlog,errorLog) << "no valid dimension given" << STD_endl; return false; } TinyVector inshape=data.shape(); TinyVector outshape=data.shape(); outshape(dir)=1; Data outdata(outshape); for(int i=0; i index=outdata.create_index(i); TinyVector lowerBounds=index; TinyVector upperBounds=index; upperBounds(dir)=inshape(dir)-1; if(Op==minip) outdata(index)=min(data(RectDomain<4>(lowerBounds, upperBounds))); if(Op==maxip) outdata(index)=max(data(RectDomain<4>(lowerBounds, upperBounds))); if(Op==proj) outdata(index)=sum(data(RectDomain<4>(lowerBounds, upperBounds))); } data.reference(outdata); // Adjusting protocol, center of slicepack and FOV remains the same if(dir==timeDim) { prot.seqpars.set_NumOfRepetitions(1); } else { if(dir==sliceDim) prot.geometry.set_nSlices(1); prot.seqpars.set_MatrixSize(direction(3-dir),1); } return true; } FilterStep* allocate() const {return new FilterReduction();} }; #endif odin-1.8.5/odindata/integration.h0000644000175000017500000000512611322062337013661 00000000000000/*************************************************************************** integration.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef INTEGRATION_H #define INTEGRATION_H #include /** * @addtogroup odindata * @{ */ /** * Base class of all function classes which should be integrated. * To use this class, derive from it and overload the virtual * function 'evaluate'. */ class Integrand { public: /** * Returns the function value at position 'x'. */ virtual double evaluate(double x) const = 0; /** * Returns the integral from 'xmin' to 'xmax'. * Integration is performed with 'max_subintervals' at which the function * will be calculated and the specified relative 'error_limit'. */ double get_integral(double xmin, double xmax, unsigned int max_subintervals=1000, double error_limit=1e-7) const; protected: Integrand() {} virtual ~Integrand() {} }; //////////////////////////////////////////////////////////// class GslData4Integr; // forward declaration /** * Class which is used for integration of functions. */ class FunctionIntegral { public: /** * Prepare an integration of function 'func' * with 'max_subintervals' at which the function * will be calculated and the specified relative 'error_limit'. */ FunctionIntegral(const Integrand& func, unsigned int max_subintervals=1000, double error_limit=1e-7); /** * Destructor */ ~FunctionIntegral(); /** * Returns the integral from 'xmin' to 'xmax'. */ double get_integral(double xmin, double xmax) const; private: static double integrand(double x, void *params); const Integrand& f; unsigned int n_intervals; double errlimit; GslData4Integr* gsldata; }; /** @} */ #endif odin-1.8.5/odindata/image.cpp0000644000175000017500000001553111363773554012773 00000000000000#include "image.h" #include "data.h" #include Image::Image(const STD_string& label) : JcampDxBlock(label) { magnitude.set_label("magnitude"); magnitude.set_filemode(compressed); append_all_members(); } Image& Image::operator = (const Image& i) { JcampDxBlock::operator = (i); geo=i.geo; magnitude=i.magnitude; append_all_members(); return *this; } unsigned int Image::size(axis ax) const { ndim nn=get_magnitude().get_extent(); int index=nn.size()-1-ax; if(index>=0) return nn[index]; return 1; } Image& Image::transpose_inplane(bool reverse_read, bool reverse_phase) { unsigned int d=magnitude.dim(); if(d<2) return *this; geo.transpose_inplane(reverse_read,reverse_phase); // transpose image data farray magnitude_copy(magnitude); ndim shape=magnitude.get_extent(); STD_swap(shape[d-1],shape[d-2]); magnitude.redim(shape); for(unsigned int i=0; i odinlog(this,"ImageSet(Sample)"); float min_fov=100.0; int min_size=64; farray sddata(smp.get_spinDensity()); STD_string maplabel="Spin Density"; sddata.normalize(); ODINLOG(odinlog,normalDebug) << "sddata.get_extent()=" << sddata.get_extent() << STD_endl; float xFOV=smp.get_FOV(xAxis); float yFOV=smp.get_FOV(yAxis); float zFOV=smp.get_FOV(zAxis); float maxFOV=maxof3(xFOV,yFOV,zFOV); if(maxFOV odinlog(this,"append_image"); bool rename=false; if(img.get_label()=="" || JcampDxBlock::parameter_exists(img.get_label())) rename=true; images.push_back(img); STD_list::iterator it=images.end(); --it; if(rename) it->set_label("Image"+itos(images.size()-1)); JcampDxBlock::append(*it); unsigned int nimages=images.size(); ODINLOG(odinlog,normalDebug) << "nimages=" << nimages << STD_endl; Content.resize(nimages); int index=0; for(it=images.begin(); it!=images.end(); ++it) { ODINLOG(odinlog,normalDebug) << "index/label=" << index << "/" << it->get_label() << STD_endl; Content[index]=it->get_label(); index++; } return *this; } ImageSet& ImageSet::clear_images() { images.clear(); Content.resize(0); return *this; } Image& ImageSet::get_image(unsigned int index) { Log odinlog(this,"get_image"); unsigned int nimages=images.size(); ODINLOG(odinlog,normalDebug) << "index/nimages=" << index << "/" << nimages << STD_endl; if(index>=nimages) return dummy; STD_list::iterator it=images.begin(); for(unsigned int i=0; i odinlog(this,"load"); clear_images(); // check whether we have a whole set of images and determine the total num of images first int noiresult=Content.load(filename); svector contcopy=Content; // create copy because append_image will modify Content unsigned int nimages=contcopy.size(); ODINLOG(odinlog,normalDebug) << "noiresult/nimages/Content=" << noiresult << "/" << nimages << "/" << contcopy.printbody() << STD_endl; int result=0; if(noiresult>0) { // create placeholders Image img; for(unsigned int i=0; i0) { clear_images(); append_image(img); } } return result; } void ImageSet::append_all_members() { JcampDxBlock::clear(); append_member(Content); } odin-1.8.5/odindata/filter_mask.cpp0000644000175000017500000001065011725203122014163 00000000000000#include "filter_mask.h" #include "utils.h" // for TinyVector comparison void FilterGenMask::init(){ min.set_description("lower threshold"); append_arg(min,"min"); max.set_description("upper threshold"); append_arg(max,"max"); } bool FilterGenMask::process(Data& data, Protocol& prot) const { /* TinyVector datashape=data.shape(); TinyVector maskshape=data.shape(); maskshape(timeDim)=1; Data mask(maskshape); mask=1.0; TinyVector maskindex; TinyVector dataindex; for(int i=0; imax) mask(maskindex)=0.0; } } data.reference(mask); */ data=where(Array(data)>=min && Array(data)<=max, float(1.0), float(0.0)); return true; } /////////////////////////////////////////////////////////////////////////// bool FilterAutoMask::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); int nslots=100; float step=secureDivision(max(data),nslots); ODINLOG(odinlog,normalDebug) << "nslots/step=" << nslots << "/" << step << STD_endl; Data hist(nslots); hist=0.0; // create histogram for(int i=0; i=0 && slothist(islot)) { thresh=islot*step; break; } } ODINLOG(odinlog,normalDebug) << "thresh=" << thresh << STD_endl; data=where(Array(data)>thresh, float(1.0), float(0.0)); return true; } /////////////////////////////////////////////////////////////////////////// typedef STD_list > QuantilIndexList; typedef STD_map QuantilIndexMap; void FilterQuantilMask::init(){ fraction.set_minmaxval(0.0,1.0).set_description("quantil"); append_arg(fraction,"fraction"); } bool FilterQuantilMask::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); int ntotal=data.size(); float frac=fraction; check_range(frac,0.0,1.0); int nmask=int((1.0-frac)*ntotal+0.5); ODINLOG(odinlog,normalDebug) << "ntotal/nmask=" << ntotal << "/" << nmask << STD_endl; Data mask(data.shape()); mask=0.0; QuantilIndexMap indexmap; for(int i=0; i index=data.create_index(i); indexmap[data(index)].push_back(index); } int nmap=indexmap.size(); ODINLOG(odinlog,normalDebug) << "ntotal/nmap=" << ntotal << "/" << nmap << STD_endl; QuantilIndexMap::const_iterator mapiter=indexmap.end(); int j=0; while(jsecond; ODINLOG(odinlog,normalDebug) << "indexmap(" << mapiter->first << ")=" << indexlist.size() << STD_endl; for(QuantilIndexList::const_iterator listiter=indexlist.begin(); listiter!=indexlist.end(); ++listiter) { mask(*listiter)=1.0; j++; } } data.reference(mask); return true; } /////////////////////////////////////////////////////////////////////////// void FilterUseMask::init() { fname.set_description("filename"); append_arg(fname,"fname"); } bool FilterUseMask::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); // Load external file Data maskdata; if(maskdata.autoread(fname)<0) return false; TinyVector maskshape=maskdata.shape(); TinyVector datashape=data.shape(); maskshape(timeDim)=datashape(timeDim)=1; if(maskshape!=datashape) { ODINLOG(odinlog,errorLog) << "shape mismatch: " << maskshape << "!=" << datashape << STD_endl; return false; } fvector vals; for(int i=0; i index=data.create_index(i); float val=data(index); index(timeDim)=0; if(maskdata(index)) vals.push_back(val); } data.resize(1,vals.size(),1,1); data(0,Range::all(),0,0)=Data(vals); return true; } odin-1.8.5/odindata/linalg.cpp0000644000175000017500000004032411322062337013136 00000000000000#include "linalg.h" #include "utils.h" #include #include #ifdef HAVE_LIBGSL #include #include #include #endif #ifdef HAVE_LAPACK // The lapack functions extern "C" void cgelss_( int* M, int* N, int* NRHS, STD_complex* A, int* LDA, STD_complex* B, int* LDB, float* S, float* RCOND, int* RANK, STD_complex* WORK, int* LWORK, float* RWORK, int* INFO ); extern "C" void sgelss_( int* M, int* N, int* NRHS, float* A, int* LDA, float* B, int* LDB, float* S, float* RCOND, int* RANK, float* WORK, int* LWORK, int* INFO ); //extern "C" void cgesvd_( char* JOBU, char* JOBVT, int* M, int* N, STD_complex* A, int* LDA, float* S, STD_complex* U, int* LDU, STD_complex* VT, int* LDVT, STD_complex* WORK, int* LWORK, float* RWORK, int* INFO ); //extern "C" void sgesvd_( char* JOBU, char* JOBVT, int* M, int* N, float* A, int* LDA, float* S, float* U, int* LDU, float* VT, int* LDVT, float* WORK, int* LWORK, int* INFO ); extern "C" void ssyev_( char* JOBZ, char* UPLO, int* N, float* A, int* LDA, float* W, float* WORK, int* LWORK, int* INFO); // Chose appropriate LAPACK function by function overloading int gelss( int* M, int* N, int* NRHS, STD_complex* A, int* LDA, STD_complex* B, int* LDB, float* S, float* RCOND, int* RANK, STD_complex* WORK, int* LWORK, float* RWORK, int* INFO ) { cgelss_( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, RWORK, INFO ); return int(WORK[0].real()); } int gelss( int* M, int* N, int* NRHS, float* A, int* LDA, float* B, int* LDB, float* S, float* RCOND, int* RANK, float* WORK, int* LWORK, float* RWORK, int* INFO ) { sgelss_( M, N, NRHS, A, LDA, B, LDB, S, RCOND, RANK, WORK, LWORK, INFO ); return int(WORK[0]); } /* int gesvd( char* JOBU, char* JOBVT, int* M, int* N, STD_complex* A, int* LDA, float* S, STD_complex* U, int* LDU, STD_complex* VT, int* LDVT, STD_complex* WORK, int* LWORK, float* RWORK, int* INFO) { cgesvd_( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, RWORK, INFO ); return int(WORK[0].real()); } int gesvd( char* JOBU, char* JOBVT, int* M, int* N, float* A, int* LDA, float* S, float* U, int* LDU, float* VT, int* LDVT, float* WORK, int* LWORK, float* RWORK, int* INFO) { sgesvd_( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK, LWORK, INFO ); return int(WORK[0]); } */ //////////////////////////////////// bool report_error(int INFO, const char* caller) { Log odinlog("",caller); if(INFO<0) { ODINLOG(odinlog,errorLog) << "the " << -INFO << "-th argument had an illegal value." << STD_endl; return true; } if(INFO>0) { ODINLOG(odinlog,errorLog) << "the algorithm failed to converge." << STD_endl; return true; } return false; } //////////////////////////////////// static Mutex lapack_mutex; //////////////////////////////////// /* Array conjugate_transpose_matrix(Array& M) {return Array(conj(M.transpose(1,0)));} Array conjugate_transpose_matrix(Array& M) {return M.transpose(1,0);} template bool svd_lapack(const Data& A, Data& U, Data& sigma, Data& V) { Log odinlog("","svd_lapack"); int M=A.extent(0); // rows int N=A.extent(1); // cols ODINLOG(odinlog,normalDebug) << "M/N=" << M << "/" << N << STD_endl; Array A_fortran(A.shape(), ColumnMajorArray<2>()); // Array with Fortran storage order A_fortran=A; // creates unique copy sigma.resize(N); Array U_fortran(A.shape(), ColumnMajorArray<2>()); // Array with Fortran storage order Array VT_fortran(TinyVector(N,N), ColumnMajorArray<2>()); // Array with Fortran storage order Array WORK(1); int LWORK=-1; // get optimal workspace size Array RWORK(5*STD_min(M,N)); int NRHS=1; int RANK; int INFO; char JOBU='A'; char JOBVT='A'; #ifndef HAVE_THREADSAFE_LAPACK MutexLock lock(lapack_mutex); //LAPACK is generally not thread safe, so we will serialize use of LAPACK #endif // call once to get optimal size of the WORK array LWORK=gesvd( &JOBU, &JOBVT, &M, &N, A_fortran.data(), &M, sigma.data(), U_fortran.data(), &M, VT_fortran.data(), &N, WORK.data(), &LWORK, RWORK.data(), &INFO); ODINLOG(odinlog,normalDebug) << "INFO/LWORK=" << INFO << "/" << LWORK << STD_endl; if(report_error(INFO,"svd_lapack(worksize)")) return false; WORK.resize(LWORK); // perform SVD gesvd( &JOBU, &JOBVT, &M, &N, A_fortran.data(), &M, sigma.data(), U_fortran.data(), &M, VT_fortran.data(), &N, WORK.data(), &LWORK, RWORK.data(), &INFO); ODINLOG(odinlog,normalDebug) << "INFO=" << INFO << STD_endl; if(report_error(INFO,"svd_lapack(svd)")) return false; U.resize(M,N); U=U_fortran; V.resize(N,N); V=conjugate_transpose_matrix(VT_fortran); return true; } */ //////////////////////////////////// template bool solve_linear_lapack(Data& result, const Data& A, const Data& b, float sv_truncation) { Log odinlog("","solve_linear_lapack"); int M=A.extent(0); // rows int N=A.extent(1); // cols ODINLOG(odinlog,normalDebug) << "M/N=" << M << "/" << N << STD_endl; Array A_fortran(A.shape(), ColumnMajorArray<2>()); // Array with Fortran storage order A_fortran=A; // creates unique copy Array B_X(M); // Use Copy because it is used for in- and output B_X=b; Array S(N); Array WORK(1); int LWORK=-1; // get optimal workspace size Array RWORK(5*STD_min(M,N)); int NRHS=1; int RANK; int INFO; #ifndef HAVE_THREADSAFE_LAPACK MutexLock lock(lapack_mutex); //LAPACK is generally not thread safe, so we will serialize use of LAPACK #endif // call once to get optimal size of the WORK array LWORK=gelss( &M, &N, &NRHS, A_fortran.data(), &M, B_X.data(), &M, S.data(), &sv_truncation, &RANK, WORK.data(), &LWORK, RWORK.data(), &INFO ); ODINLOG(odinlog,normalDebug) << "INFO/LWORK=" << INFO << "/" << LWORK << STD_endl; if(report_error(INFO,"solve_linear_lapack(worksize)")) return false; WORK.resize(LWORK); // perform SVD gelss( &M, &N, &NRHS, A_fortran.data(), &M, B_X.data(), &M, S.data(), &sv_truncation, &RANK, WORK.data(), &LWORK, RWORK.data(), &INFO ); ODINLOG(odinlog,normalDebug) << "INFO=" << INFO << STD_endl; if(report_error(INFO,"solve_linear_lapack(svd)")) return false; result.resize(N); result=B_X(Range(0,N-1)); return true; } #endif /////////////////////////////////////////////////////////////////////////////////////////////////////// bool shape_error(const TinyVector& A_shape, int b_extent) { Log odinlog("solve_linear","shape_error"); int A_nrows=A_shape(0); int A_ncols=A_shape(1); if(A_nrows==0 || A_ncols==0) { ODINLOG(odinlog,errorLog) << "Zero-size matrix" << STD_endl; return true; } if(A_ncols>A_nrows) { ODINLOG(odinlog,errorLog) << "cols>rows matrices not supported" << STD_endl; return true; } if(b_extent!=A_nrows) { ODINLOG(odinlog,errorLog) << "size mismatch (b_extent=" << b_extent << ") != (A_nrows=" << A_nrows << ")" << STD_endl; return true; } return false; } ////////////////////////////////////////////////// /* ComplexData<2> matrix_inverse(const ComplexData<2>& A, float sv_truncation) { Log odinlog("","matrix_inverse(complex)"); Range all=Range::all(); ComplexData<2> result; bool svdresult=false; ComplexData<2> U; Data sigma; ComplexData<2> V; #ifdef HAVE_LAPACK svdresult=svd_lapack(A, U, sigma, V); #endif if(!svdresult) { ODINLOG(odinlog,errorLog) << "SVD failed" << STD_endl; } // Regularization int ncol=sigma.size(); float threshold=sv_truncation*sigma(0); ComplexData<1> Sinv(ncol); for(int icol=0; icol solve_linear(const Data& A, const Data& b, float sv_truncation) { Log odinlog("","solve_linear(float)"); Data result; if(shape_error(A.shape(),b.extent(0))) return result; #ifdef HAVE_LAPACK solve_linear_lapack(result,A, b, sv_truncation); #else #ifdef HAVE_LIBGSL Range all=Range::all(); int nrows=A.extent(0); int ncols=A.extent(1); ODINLOG(odinlog,normalDebug) << "nrows/ncols=" << nrows << "/" << ncols << STD_endl; gsl_matrix *A_gsl=gsl_matrix_alloc (nrows, ncols); gsl_matrix *V_gsl=gsl_matrix_alloc (ncols, ncols); gsl_vector *S_gsl=gsl_vector_alloc (ncols); gsl_vector *work =gsl_vector_alloc (ncols); gsl_matrix *X_gsl=0; // additional workspace if( nrows > (2*ncols) ) X_gsl=gsl_matrix_alloc (ncols, ncols); // Use modified SVD for massively over-determined matrices for(int irow=0; irow U(nrows,ncols); for(int irow=0; irow S(ncols); for(int icol=0; icol solve_linear(const ComplexData<2>& A, const ComplexData<1>& b, float sv_truncation) { Log odinlog("","solve_linear(complex)"); ComplexData<1> result; if(shape_error(A.shape(),b.extent(0))) return result; #ifdef HAVE_LAPACK solve_linear_lapack(result, A, b, sv_truncation); #else // create real matrix according to NRC, section 2.3 int A_nrows=A.extent(0); int A_ncols=A.extent(1); Data Af(2*A_nrows,2*A_ncols); for(int irow=0; irow bf(2*nb); for(int i=0; i xf=solve_linear(Af,bf,sv_truncation); int nx=xf.extent(0)/2; result.resize(nx); for(int i=0; i eigenvalues(const Data& A) { Log odinlog("","eigenvalues"); Data result; int N=A.extent(0); if(A.extent(1)!=N) { ODINLOG(odinlog,errorLog) << "Matrix not quadratic" << STD_endl; return result; } ODINLOG(odinlog,normalDebug) << "N=" << N << STD_endl; result.resize(N); result=0.0; #ifdef HAVE_LAPACK Array A_fortran(A.shape(), ColumnMajorArray<2>()); // Array with Fortran storage order A_fortran=A; // creates unique copy char JOBZ='N'; char UPLO='U'; Array WORK(1); int LWORK=-1; // get optimal workspace size int INFO; #ifndef HAVE_THREADSAFE_LAPACK MutexLock lock(lapack_mutex); //LAPACK is generally not thread safe, so we will serialize use of LAPACK #endif // call once to get optimal size of the WORK array ssyev_(&JOBZ, &UPLO, &N, A_fortran.data(), &N, result.data(), WORK.data(), &LWORK, &INFO); LWORK=int(WORK(0)); if(report_error(INFO,"eigenvalues(worksize)")) return result; WORK.resize(LWORK); // perform actual diagonalization ssyev_(&JOBZ, &UPLO, &N, A_fortran.data(), &N, result.data(), WORK.data(), &LWORK, &INFO); ODINLOG(odinlog,normalDebug) << "INFO=" << INFO << STD_endl; if(report_error(INFO,"eigenvalues(diagonalization)")) return result; #else #ifdef HAVE_LIBGSL gsl_matrix* m=gsl_matrix_alloc(N, N); for(int j=0; j odinlog(this,"check"); // Self-consistency check ComplexData<2> A(3,3); for(int i=0; i<9; i++) A(A.create_index(i))=STD_complex(float(i),sqrt(float(i))); ComplexData<1> b(3); b(0)=STD_complex(0.1,4.5); b(1)=STD_complex(4.1,0.2); b(2)=STD_complex(-3.4,-7.5); ComplexData<1> x=solve_linear(A,b); ComplexData<1> b_test(3); b_test=matrix_product(A,x); if(cabs(sum(b_test-b))>1.0e-3) { ODINLOG(odinlog,errorLog) << "A=" << A << STD_endl; ODINLOG(odinlog,errorLog) << "x=" << x << STD_endl; ODINLOG(odinlog,errorLog) << "b=" << b << STD_endl; ODINLOG(odinlog,errorLog) << "b_test=" << b_test << STD_endl; ODINLOG(odinlog,errorLog) << "test failed" << STD_endl; return false; } // Test overdetermined system and its errors int nrows=100; int ncols=4; int errcol=1; A.resize(nrows,ncols); b.resize(nrows); ComplexData<1> x_expected(ncols); for(int i=0; i x_solved=solve_linear(A,b,0.02); // Actual solution by GSL x_expected(0)=STD_complex(0.941546,-6.1919); x_expected(1)=STD_complex(1.4224,-6.87925); x_expected(2)=STD_complex(1.03419,-6.38178); x_expected(3)=STD_complex(1.07938,-6.4723); if(cabs(sum(x_solved-x_expected))>1.0e-3) { ODINLOG(odinlog,errorLog) << "A=" << A << STD_endl; ODINLOG(odinlog,errorLog) << "b=" << b << STD_endl; ODINLOG(odinlog,errorLog) << "x_expected=" << x_expected << STD_endl; ODINLOG(odinlog,errorLog) << "x_solved=" << x_solved << STD_endl; return false; } // Testing eigenvalues Data Asimple(2,2); Asimple(0,0)=13; Asimple(1,1)=7; Asimple(1,0)=Asimple(0,1)=-4; // symmetric Data eig_calculated(eigenvalues(Asimple)); Data eig_expected(2); eig_expected(0)=5; eig_expected(1)=15; if(sum(fabs(eig_calculated-eig_expected))) { ODINLOG(odinlog,errorLog) << "eig_calculated=" << eig_calculated << STD_endl; ODINLOG(odinlog,errorLog) << "eig_expected=" << eig_expected << STD_endl; return false; } return true; } }; void alloc_LinAlgTest() {new LinAlgTest();} // create test instance #endif odin-1.8.5/odindata/filter.cpp0000644000175000017500000000341411322062337013154 00000000000000#include "filter.h" bool FilterChain::create(const svector& args) { Log odinlog("FilterChain","create"); filters.clear(); ODINLOG(odinlog,normalDebug) << "args=" << args.printbody() << STD_endl; unsigned int nargs=args.size(); for(unsigned int i=0; inumof_args()) { STD_string argstr=args[i+1]; ODINLOG(odinlog,normalDebug) << "argstr=" << argstr << STD_endl; if(argstr.length()) filter->set_args(argstr); i++; } filters.push_back(filter); } } } return true; } FilterChain::FilterChain(int argc,char *argv[]) { Log odinlog("FilterChain","FilterChain"); int nargs=argc-1; if(nargs<=0) return; svector args; args.resize(nargs); for(int i=0; i odinlog("FilterChain","apply"); for(STD_list::const_iterator fit=filters.begin();fit!=filters.end();fit++){ ODINLOG(odinlog,normalDebug) << "Applying " << (*fit)->label() << " to the whole Dataset" << STD_endl; FilterStep *step=*fit; if(!step->process(pdmap)) return false; } return true; } bool FilterChain::apply(Protocol& prot, Data& data) const { Log odinlog("FilterChain","apply"); for(STD_list::const_iterator fit=filters.begin();fit!=filters.end();fit++){ ODINLOG(odinlog,normalDebug) << "Applying " << (*fit)->label() << STD_endl; if(!(*fit)->process(data, prot)) return false; } return true; } odin-1.8.5/odindata/integration.cpp0000644000175000017500000000457011322062337014216 00000000000000#include "integration.h" #include #ifdef HAVE_LIBGSL #include double Integrand::get_integral(double xmin, double xmax, unsigned int max_subintervals, double error_limit) const { FunctionIntegral fi(*this,max_subintervals,error_limit); return fi.get_integral(xmin,xmax); } ////////////////////////////////////////////////////////////// struct GslData4Integr { gsl_integration_workspace* w; }; ////////////////////////////////////////////////////////////// FunctionIntegral::FunctionIntegral(const Integrand& func, unsigned int max_subintervals, double error_limit) : f(func), n_intervals(max_subintervals), errlimit(error_limit) { gsldata=new GslData4Integr; gsldata->w = gsl_integration_workspace_alloc(n_intervals); } FunctionIntegral::~FunctionIntegral() { gsl_integration_workspace_free(gsldata->w); delete gsldata; } double FunctionIntegral::get_integral(double xmin, double xmax) const { double result, error; gsl_function gsl_F; gsl_F.function = &integrand; gsl_F.params = (void*)&f; gsl_integration_qags (&gsl_F, xmin, xmax, 0, errlimit, n_intervals, gsldata->w, &result, &error); return result; } double FunctionIntegral::integrand(double x, void *params) { const Integrand* integr=(const Integrand*)params; return integr->evaluate(x); } ////////////////////////////////////////////////////////////// // Unit test #ifndef NO_UNIT_TEST class FunctionIntegralTest : public UnitTest { struct QuadrFunction : public Integrand { double evaluate(double x) const {return x*x;} }; struct QuadrIntFunction : public Integrand { double evaluate(double x) const {return qf.get_integral(0.0,x);} QuadrFunction qf; }; public: FunctionIntegralTest() : UnitTest("FunctionIntegral") {} private: bool check() const { Log odinlog(this,"check"); // testing quadratic integral function QuadrIntFunction func; STD_string expected_str=ftos(1.0/12.0); STD_string calculated_str=ftos(func.get_integral(0.0,1.0)); if(calculated_str!=expected_str) { ODINLOG(odinlog,errorLog) << "integral=" << calculated_str << ", but expected integral=" << expected_str << STD_endl; return false; } return true; } }; void alloc_FunctionIntegralTest() {new FunctionIntegralTest();} // create test instance #endif #else #error "GNU Scientific library is missing!" #endif odin-1.8.5/odindata/filter_lowpass.h0000644000175000017500000000262311455553535014406 00000000000000/*************************************************************************** filter_lowpass.h - description ------------------- begin : Thu Apr 22 2010 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_LOWPASS_H #define FILTER_LOWPASS_H #include class FilterLowPass : public FilterStep { JDXfloat freq; STD_string label() const {return "lowpass";} STD_string description() const {return "Lowpass filtering";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterLowPass();} void init(); }; #endif odin-1.8.5/odindata/filter_clip.h0000644000175000017500000000513011322062337013625 00000000000000/*************************************************************************** filter_scale.h - description ------------------- begin : Thu Jan 31 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_CLIP_H #define FILTER_CLIP_H #include class FilterMin : public FilterStep { JDXfloat thresh; STD_string label() const {return "min";} STD_string description() const {return "Clip all values below mininum value";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterMin();} void init(); }; //////////////////////////////////////////////////////////////////////////// class FilterMax : public FilterStep { JDXfloat thresh; STD_string label() const {return "max";} STD_string description() const {return "Clip all values above maximum value";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterMax();} void init(); }; //////////////////////////////////////////////////////////////////////////// class FilterType : public FilterStep { protected: JDXstring type; float getThresh(bool upper)const; void init(); }; class FilterTypeMin : public FilterType { STD_string label() const {return "typemin";} STD_string description() const {return "Clip all values below mininum of a specific datatype";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterTypeMin();} }; class FilterTypeMax : public FilterType { STD_string label() const {return "typemax";} STD_string description() const {return "Clip all values above maximum of a specific datatype";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterTypeMax();} }; #endif odin-1.8.5/odindata/converter.cpp0000644000175000017500000000020711712547770013707 00000000000000#include "converter.h" #include const char* OdinData::get_compName() {return "Data";} LOGGROUNDWORK(OdinData) odin-1.8.5/odindata/statistics.cpp0000644000175000017500000000400411322062337014055 00000000000000#include "statistics.h" #include STD_ostream& operator << (STD_ostream& s, statisticResult stats) { s << stats.mean << " +/- " << stats.meandev << " (min=" << stats.min << ", max=" << stats.max << ", stdev=" << stats.stdev << ")"; return s; } ///////////////////////////////////////////////////// // instantiate one special template for checking at compile time #ifdef ODIN_DEBUG template statisticResult statistics(const Array&, const Array*); template float median(const Array&); template double weightmean(const Array& , const Array&); #endif ///////////////////////////////////////////////////// // unit test #ifndef NO_UNIT_TEST class StatisticsTest : public UnitTest { public: StatisticsTest() : UnitTest("statistics") {} private: bool check() const { Log odinlog(this,"check"); int testsize=10; Data testarray(testsize,testsize); TinyVector index; for(int i=0; i template class FilterFlip : public FilterStep { STD_string label() const {return STD_string(1,STD_string(dataDimLabel[Dir])[0])+"flip";} // Use only 1st letter STD_string description() const {return "Flip data in "+STD_string(dataDimLabel[Dir])+" direction";} bool process(Data& data, Protocol& prot) const { data.reverseSelf(Dir); // Adjust protocol dvector sign(3); sign=1.0; sign[3-Dir]=-1.0; prot.geometry.set_orientation_and_offset( sign[0]*prot.geometry.get_readVector(), sign[1]*prot.geometry.get_phaseVector(), sign[2]*prot.geometry.get_sliceVector(), prot.geometry.get_center()); return true; } FilterStep* allocate() const {return new FilterFlip

    ();} void init() {} }; #endif odin-1.8.5/odindata/gridding.cpp0000644000175000017500000000433311322062337013457 00000000000000#include "gridding.h" #include // instantiate one special template for checking at compile time #ifdef ODIN_DEBUG template class Gridding; template class CoordTransformation; #endif ///////////////////////////////////////////////////// // unit test #ifndef NO_UNIT_TEST #include "statistics.h" class GriddingTest : public UnitTest { public: GriddingTest() : UnitTest("Gridding") {} private: bool check() const { Log odinlog(this,"check"); // Test using a 3*FOV/4 (filled with 1) and FOV/2 (filled with 2) box int testsize=128; Data testbox(testsize,testsize); testbox=0.0; Range inner(testsize/8, 7*testsize/8-1); testbox(inner,inner)=1.0; inner=Range(testsize/4, 3*testsize/4-1); testbox(inner,inner)=2.0; // testbox.autowrite("testbox.jdx"); float radialfactor=1.2; // so that sampling disk covers the whole box int ncycles=int(radialfactor*testsize/2+0.5); // suffucient sampling in radial direction int spirsize=int(radialfactor*int(2.0*PII*ncycles*testsize)+0.5); // suffucient along spiral STD_vector > src_coords(spirsize); Data src(spirsize); src=0.0; for(int i=0; i dst(testbox.shape()); JDXfilter gridkernel; gridkernel.set_function("Gauss"); Gridding gridder; gridder.init(dst.shape(), 2.0, src_coords, gridkernel, sqrt(2.0)*2.0/float(testsize)); Data griddedbox(gridder(src)); // griddedbox.autowrite("griddedbox.jdx"); Data diff(testbox-griddedbox); // diff.autowrite("diff.jdx"); float absdiff=sum(fabs(diff)); if(absdiff>30.0) { ODINLOG(odinlog,errorLog) << "absdiff=" << absdiff << STD_endl; return false; } return true; } }; void alloc_GriddingTest() {new GriddingTest();} // create test instance #endif odin-1.8.5/odindata/statistics.h0000644000175000017500000001135311322062337013527 00000000000000/*************************************************************************** statistics.h - description ------------------- begin : Fri Apr 6 2001 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STATISTICS_H #define STATISTICS_H #include #include /** * @addtogroup odindata * @{ */ /////////////////////////////////////////////////////////// /** * Results of a statistical analysis * */ struct statisticResult { /** * The minimum value */ double min; /** * The minimum value */ double max; /** * The mean value */ double mean; /** * The standard deviation */ double stdev; /** * The standard deviation of the mean value */ double meandev; /** * Prints statistics to ostream */ friend STD_ostream& operator << (STD_ostream& s, statisticResult stats); }; /////////////////////////////////////////////////////////// /** * Returns a statistical description of 'ensemble'. If mask is non-zero, * only values with mask!=0 are considered. * */ template statisticResult statistics(const Array& ensemble, const Array* mask=0) { Log odinlog("","statistics"); statisticResult result; result.min=0.0; result.max=0.0; result.mean=0.0; result.stdev=0.0; result.meandev=0.0; if(mask && !same_shape(ensemble,*mask)) { ODINLOG(odinlog,errorLog) << "size mismatch (ensemble.shape()=" << ensemble.shape() << ") != (mask.shape()=" << mask->shape() << ")" << STD_endl; return result; } int n=ensemble.numElements(); Data ensemble_copy(ensemble); int nvals=0; TinyVector index; for(int i=0; iresult.max) result.max=val; } } } result.mean=secureDivision(result.mean,double(nvals)); nvals=0; for(int i=0; i1) result.stdev=sqrt(result.stdev/double(nvals-1)); else result.stdev=0.0; result.meandev=result.stdev/sqrt(double(nvals)); return result; } /////////////////////////////////////////////////////////// /** * Returns the median of 'ensemble'. * */ template T median(const Array& ensemble) { Data ensemble_copy(ensemble); Array diff(ensemble.shape()); TinyVector index; for(int i=0; i T weightmean(const Array& ensemble, const Array& weight) { Log odinlog("","weightmean"); T result; result=0; // double-stage init for TinyVector Data ensemble_copy(ensemble); if(ensemble.shape()!=weight.shape()) { ODINLOG(odinlog,errorLog) << "size mismatch (ensemble.shape()=" << ensemble.shape() << ") != (weight.shape()=" << weight.shape() << ")" << STD_endl; return result; } float weightsum=0.0; TinyVector index; for(int i=0; i /** * @addtogroup odindata * @{ */ /////////////////////////////////////////////////////////////////////////////////// /** * Base class for all steps (functors). * The template argument is the type of the specialized, derived class. */ template class Step { public: virtual ~Step() {} /** * Overload this function to return a unique label for the functor. */ virtual STD_string label() const = 0; /** * Overload this function to return a brief description of the functor. */ virtual STD_string description() const = 0; /** * Overload this function to allocate an empty object of the step. */ virtual T* allocate() const = 0; /** * Initialize the step, i.e. initiliaze its parameters and append them by 'append_arg'. */ virtual void init() = 0; /** * Clone this step (including its arguments). */ T* clone() const; /** * Overrides the arguments of the functor using a string with comma-separated argument values. */ void set_args(const STD_string& argstr); /** * Returns description of arguments as comma-separated list. */ STD_string args_description() const; /** * Returns the number of arguments. */ unsigned int numof_args() const {return args.numof_pars();} /** * Append arguments of the functor to parblock. */ void append_opts(JcampDxBlock& parblock); protected: /** * Append step argument, to be used in init() of each step. */ void append_arg(JcampDxClass& arg, const STD_string& arglabel); const char* c_label() const {if(!label_cache.size()) label_cache=label(); return label_cache.c_str();} // For Debug private: JcampDxBlock args; mutable STD_string label_cache; }; /////////////////////////////////////////////////////////////////////////////////// /** * Factory for steps (functors). * The template argument is the type of the step to be created by the factory. */ template class StepFactory { public: /** * Set up factory (creates template objects). Appends parameters of all steps to 'parblock'. */ StepFactory(JcampDxBlock* parblock=0); ~StepFactory(); /** * Returns allocated step functor which matches given 'label'. */ T* create(const STD_string& label) const; /** * Returns documention 'code' for doxygen. */ STD_string manual() const; /** * Returns documention for command line. */ STD_string get_cmdline_usage(const STD_string& lineprefix) const; private: typedef STD_map StepMap; StepMap templates; mutable STD_list garbage; }; /** @} */ #endif odin-1.8.5/odindata/filter_detrend.h0000644000175000017500000000265611712547771014352 00000000000000/*************************************************************************** filter_detrend.h - description ------------------- begin : Sun May 17 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_DETREND_H #define FILTER_DETREND_H #include class FilterDeTrend : public FilterStep { JDXint nlow; JDXbool zeromean; STD_string label() const {return "detrend";} STD_string description() const {return "Remove slow drift over time";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterDeTrend();} void init(); }; #endif odin-1.8.5/odindata/filter_nan.h0000644000175000017500000000113211322062337013450 00000000000000// // C++ Interface: filter_nan // // Description: // // // Author: , (C) 2007 // // Copyright: See COPYING file that comes with this distribution // // #ifndef FILTER_NAN_H #define FILTER_NAN_H #include /** @author Enrico Reimer */ class FilterNaN : public FilterStep { JDXfloat replace; STD_string label() const {return "noNaN";} STD_string description() const {return "Replaces every NaN by the given value";} bool process(Data& data, Protocol& prot)const; FilterStep* allocate() const {return new FilterNaN();} void init(); }; #endif odin-1.8.5/odindata/filter_rot.h0000644000175000017500000000262011322062337013503 00000000000000/*************************************************************************** filter_rot.h - description ------------------- begin : Sun Jan 20 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_ROT_H #define FILTER_ROT_H #include class FilterRot : public FilterStep { JDXdouble angle; JDXdouble kernel; STD_string label() const {return "rot";} STD_string description() const {return "In-plane rotation";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterRot();} void init(); }; #endif odin-1.8.5/odindata/utils.h0000644000175000017500000001135411734622162012503 00000000000000/*************************************************************************** mri_utils.h - description ------------------- begin : Wed Feb 9 2005 copyright : (C) 2005 by Thies H. Jochimsen email : ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef UTILS_H #define UTILS_H #include /** * @addtogroup odindata * @{ */ /** * unwrap phase in one dimension, starting at position 'startindex' */ Data unwrap_phase(const Data& phase, int startindex=0); ////////////////////////////////////////////////////////// /** * matrix-vector product */ template Array matrix_product(const Array& matrix, const Array& vector) { Log odinlog("","matrix_product"); int nrows=matrix.extent()(0); int ncols=matrix.extent()(1); Array result(nrows); result=0; int vector_extent=vector.extent(0); if(vector.extent(0)!=ncols) { ODINLOG(odinlog,errorLog) << "size mismatch (vector_extent=" << vector_extent << ") != (ncols=" << ncols << ")" << STD_endl; return result; } for(int icol=0; icol Array matrix_product(const Array& matrix1, const Array& matrix2) { Log odinlog("","matrix_product"); int nrows=matrix1.extent()(0); int ncols=matrix2.extent()(1); ODINLOG(odinlog,normalDebug) << "nrows/ncols=" << nrows << "/" << ncols << STD_endl; Array result(nrows,ncols); result=0; if(matrix1.extent(1)!=matrix2.extent(0)) { ODINLOG(odinlog,errorLog) << "size mismatch (matrix1=" << matrix1.shape() << ", matrix2=" << matrix2.shape() << ")" << STD_endl; return result; } int nprod=matrix1.extent(1); ODINLOG(odinlog,normalDebug) << "nprod=" << nprod << STD_endl; for(int irow=0; irow Array vector_product(const Array& u, const Array& v) { Log odinlog("","vector_product"); Array result(3); if(u.extent(0)!=3 || v.extent(0)!=3) { ODINLOG(odinlog,errorLog) << "input size != 3" << STD_endl; return result; } result(0)=u(1)*v(2)-u(2)*v(1); result(1)=u(2)*v(0)-u(0)*v(2); result(2)=u(0)*v(1)-u(1)*v(0); return result; } ////////////////////////////////////////////////////////// /** * Equal-comparison operator for TinyVectors */ template bool operator == (const TinyVector& t1, const TinyVector& t2) { return sum(abs(t1-t2))==0; } ////////////////////////////////////////////////////////// /** * Unequal-comparison operator for TinyVectors */ template bool operator != (const TinyVector& t1, const TinyVector& t2) { return !(t1==t2); } ////////////////////////////////////////////////////////// /** * Compares array shapes while discarding dimensions with zero value in dimmask. Returns true if equal. */ template bool same_shape(const Array& a1, const Array& a2, const TinyVector& dimmask=1) { for(int i=0; i bool check_range(T& val, T min, T max) { bool in_range=true; if(valmax) {val=max; in_range=false;} return in_range; } /** @} */ #endif odin-1.8.5/odindata/filter_mask.h0000644000175000017500000000533211725203122013631 00000000000000/*************************************************************************** filter_mask.h - description ------------------- begin : Wed Nov 5 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_MASK_H #define FILTER_MASK_H #include class FilterGenMask : public FilterStep { JDXfloat min; JDXfloat max; STD_string label() const {return "genmask";} STD_string description() const {return "Create mask including all voxels with value in given range";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterGenMask();} void init(); }; /////////////////////////////////////////////////////////////////////////// class FilterAutoMask : public FilterStep { STD_string label() const {return "automask";} STD_string description() const {return "Create mask using automatic histogram-based threshold";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterAutoMask();} void init() {} }; /////////////////////////////////////////////////////////////////////////// class FilterQuantilMask : public FilterStep { JDXfloat fraction; STD_string label() const {return "quantilmask";} STD_string description() const {return "Create mask including all voxels above the given fractional threshold";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterQuantilMask();} void init(); }; /////////////////////////////////////////////////////////////////////////// class FilterUseMask : public FilterStep { JDXfileName fname; STD_string label() const {return "usemask";} STD_string description() const {return "Create 1D dataset including all values within mask from file";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterUseMask();} void init(); }; #endif odin-1.8.5/odindata/correlation.cpp0000644000175000017500000000323211455553535014222 00000000000000#include "correlation.h" fmriResult fmri_eval(const Data& timecourse, const Data& designvec) { Log odinlog("","fmri_eval"); fmriResult result; if( !same_shape(timecourse, designvec) ) { ODINLOG(odinlog,errorLog) << "design file size mismatch" << STD_endl; return result; } int nrep=timecourse.numElements(); float maxdesign=max(designvec); float mindesign=min(designvec); // Calculate baseline int nbaseline=0; for(int i=0; i restdata(nrest); Array stimdata(nstim); int irest=0; int istim=0; for(int i=0; i&, const Array&); #endif odin-1.8.5/odindata/step.cpp0000644000175000017500000000002211322062337012632 00000000000000#include "step.h" odin-1.8.5/odindata/filter_range.h0000644000175000017500000000624211322062337013777 00000000000000/*************************************************************************** filter_range.h - description ------------------- begin : Tue Jan 29 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_RANGE_H #define FILTER_RANGE_H #include bool str2range(const STD_string& str, Range& range, int srcsize); template class FilterRange : public FilterStep { JDXstring range; STD_string label() const {return STD_string(1,STD_string(dataDimLabel[Dir])[0])+"range";} // Use only 1st letter STD_string description() const {return "Select range in "+STD_string(dataDimLabel[Dir])+" direction";} bool process(Data& data, Protocol& prot) const { Range all=Range::all(); Range rng[4]; for(int i=0; i<4; i++) rng[i]=Range::all(); if(!str2range(range,rng[Dir],data.extent(Dir))) return false; TinyVector newshape=data.shape(); newshape(Dir)=rng[Dir].length(); float fovfraction=secureDivision(rng[Dir].last()-rng[Dir].first()+1, data.shape()[Dir]); float offsetfactor=secureDivision(0.5*(rng[Dir].first()+rng[Dir].last()), data.shape()[Dir])-0.5; Data data_copy(data.copy()); data.resize(newshape); data(all,all,all,all)=data_copy(rng[timeDim],rng[sliceDim],rng[phaseDim],rng[readDim]); // adapt protocol int stride=rng[Dir].stride(); if(Dir==timeDim) { prot.seqpars.set_NumOfRepetitions(newshape(timeDim)); if(stride>1) prot.seqpars.set_RepetitionTime(prot.seqpars.get_RepetitionTime()*stride); } else { direction geodir=direction(3-Dir); prot.geometry.set_offset(geodir,prot.geometry.get_offset(geodir)+offsetfactor*prot.geometry.get_FOV(geodir)); prot.geometry.set_FOV(geodir,fovfraction*prot.geometry.get_FOV(geodir)); prot.seqpars.set_MatrixSize(geodir,newshape(Dir)); if(Dir==sliceDim) { if(prot.geometry.get_Mode()==slicepack) { prot.geometry.set_nSlices(newshape(sliceDim)); if(stride>1) prot.geometry.set_sliceDistance(prot.geometry.get_sliceDistance()*stride); prot.seqpars.set_MatrixSize(sliceDirection,1); } } } return true; } FilterStep* allocate() const {return new FilterRange();} void init() { range.set_description("Single value or range, optionally with increment (e.g. 1-10:3)"); append_arg(range,"range"); } }; #endif odin-1.8.5/odindata/fileio_asc.cpp0000644000175000017500000001105511712547771014001 00000000000000#include "fileio.h" ////////////////////////////////////////////////////////////// struct AsciiFormat : public FileFormat { STD_string description() const {return "ASCII";} svector suffix() const { svector result; result.resize(1); result[0]="asc"; return result; } svector dialects() const { svector result; result.resize(1); result[0]="tcourse"; return result; } int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { STD_string ascfile; ::load(ascfile,filename); unsigned int nelements=tokens(ascfile).size(); if(tolowerstr(opts.dialect)=="tcourse") data.resize(nelements,1,1,1); else data.resize(1,nelements,1,1); if(data.read_asc_file(filename)<0) return -1; return nelements; } int write(const Data& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { return data.write_asc_file(filename); } }; ////////////////////////////////////////////////////////////// struct MatlabAsciiFormat : public FileFormat { STD_string description() const {return "Matlab ascii 2D data matrix";} svector suffix() const { svector result; result.resize(1); result[0]="dat"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { STD_string str; if(::load(str, filename)<0) return -1; sarray table(parse_table(str)); int nrows=table.size(0); int ncols=table.size(1); data.resize(1,1,nrows,ncols); for(int irow=0; irow& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { int nrows=data.extent(2); int ncols=data.extent(3); sarray table(nrows,ncols); for(int irow=0; irow& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("PosFormat","read"); ODINLOG(odinlog,errorLog) << "Implement me" << STD_endl; return -1; } int write(const Data& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { int nx=data.extent(3); int ny=data.extent(2); STD_ofstream ofs(filename.c_str()); if(ofs.bad()) return -1; for(int i=0; i index=data.create_index(i); if(data(index)>0.0) { int ix=index(3); int iy=index(2); ofs << ftos(float(ix)/float(nx)-0.5) << " " << ftos(float(iy)/float(ny)-0.5) << STD_endl; } } return 1; } }; ////////////////////////////////////////////////////////////// struct IndexFormat : public FileFormat { STD_string description() const {return "3D-indices of non-zeroes in ASCII";} svector suffix() const { svector result; result.resize(1); result[0]="idx"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("IndexFormat","read"); ODINLOG(odinlog,errorLog) << "Implement me" << STD_endl; return -1; } int write(const Data& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { STD_ofstream ofs(filename.c_str()); if(ofs.bad()) return -1; for(int i=0; i index=data.create_index(i); if(data(index)) ofs << index(sliceDim) << " " << index(phaseDim) << " " << index(readDim) << STD_endl; } return 1; } }; ////////////////////////////////////////////////////////////// void register_asc_format() { static AsciiFormat af; static PosFormat pf; static IndexFormat idf; static MatlabAsciiFormat mf; af.register_format(); pf.register_format(); idf.register_format(); mf.register_format(); } odin-1.8.5/odindata/filter_step.cpp0000644000175000017500000000624611734622163014223 00000000000000#include "filter.h" #include "filter_step.h" #include "filter_align.h" #include "filter_clip.h" #include "filter_detrend.h" #include "filter_lowpass.h" #include "filter_mask.h" #include "filter_merge.h" #include "filter_nan.h" #include "filter_resize.h" #include "filter_rot.h" #include "filter_flip.h" #include "filter_range.h" #include "filter_reduction.h" #include "filter_reslice.h" #include "filter_scale.h" #include "filter_shift.h" #include "filter_tile.h" #include "filter_splice.h" #include #include // Instantiate template classes template class Step; template class StepFactory; const char* Filter::get_compName() {return "Filter";} LOGGROUNDWORK(Filter); void FilterStep::create_templates(STD_list& result) { result.push_back(new FilterAlign()); result.push_back(new FilterMin()); result.push_back(new FilterMax()); result.push_back(new FilterTypeMax()); result.push_back(new FilterTypeMin()); result.push_back(new FilterDeTrend()); result.push_back(new FilterLowPass()); result.push_back(new FilterGenMask()); result.push_back(new FilterAutoMask()); result.push_back(new FilterQuantilMask()); result.push_back(new FilterUseMask()); result.push_back(new FilterNaN()); result.push_back(new FilterRot()); result.push_back(new FilterFlip()); result.push_back(new FilterFlip()); result.push_back(new FilterFlip()); result.push_back(new FilterRange()); result.push_back(new FilterRange()); result.push_back(new FilterRange()); result.push_back(new FilterRange()); result.push_back(new FilterScale()); result.push_back(new FilterShift()); result.push_back(new FilterReSlice()); result.push_back(new FilterSwapdim()); result.push_back(new FilterResize()); result.push_back(new FilterResample()); result.push_back(new FilterIsotrop()); result.push_back(new FilterTile()); result.push_back(new FilterMerge()); result.push_back(new FilterSplice()); result.push_back(new FilterReduction()); result.push_back(new FilterReduction()); result.push_back(new FilterReduction()); } bool FilterStep::process(Data& data, Protocol& prot)const{ Log odinlog("FilterStep","process"); ODINLOG(odinlog,errorLog) << "process seems not to be implemented for " << label() << STD_endl; return false; } bool FilterStep::process(FileIO::ProtocolDataMap& pdmap)const{ Log odinlog("FilterStep","process"); bool ret=true; FileIO::ProtocolDataMap pdmap_out; while(!pdmap.empty()){ STD_pair > pdpair=*pdmap.begin(); pdmap.erase(pdmap.begin());//in case we modify the protocol it is better to completly remove the pd-pair and insert it cleanly afterwards if(process(pdpair.second,pdpair.first)){ pdmap_out.insert(pdpair);//.. and insert it into the result-map } else { int number;STD_string desc; pdpair.first.study.get_Series(desc,number); ODINLOG(odinlog,errorLog) << "processing " << label() << " on S" << number << " failed"<< STD_endl; ret=false; } } pdmap=pdmap_out; return ret; } odin-1.8.5/odindata/filter_step.h0000644000175000017500000000206411322062337013654 00000000000000// // C++ Interface: filterstep // // Description: // // // Author: , (C) 2007 // // Copyright: See COPYING file that comes with this distribution // // #ifndef FILTERSTEP_H #define FILTERSTEP_H #include #include #include /** @author Enrico Reimer */ class FilterStep : public Step { public: virtual ~FilterStep() {} /** * Apply filter to protocol-data pair. */ virtual bool process(Data& data, Protocol& prot)const; /** * Apply filter to a 'pdmap'. */ virtual bool process(FileIO::ProtocolDataMap& pdmap)const; // To be used by factory via duck typing static void create_templates(STD_list& result); static STD_string manual_group() {return "filter_steps";} static void interface_description(const FilterStep* step, STD_string& in, STD_string& out) {} }; /////////////////////////////////////////////////////////////////////////////////// typedef StepFactory FilterFactory; // The factory for filter steps #endif odin-1.8.5/odindata/filter_tile.h0000644000175000017500000000262111322062337013635 00000000000000/*************************************************************************** filter_tile.h - description ------------------- begin : Wed Nov 5 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef FILTER_TILE_H #define FILTER_TILE_H #include class FilterTile : public FilterStep { JDXint cols; STD_string label() const {return "tile";} STD_string description() const {return "Combine slices into a square 2D image";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterTile();} void init(); }; #endif odin-1.8.5/odindata/filter_flip.cpp0000644000175000017500000000003111322062337014156 00000000000000#include "filter_flip.h" odin-1.8.5/odindata/image.h0000644000175000017500000000746711322062337012432 00000000000000/*************************************************************************** image.h - description ------------------- begin : Fr Feb 25 2005 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef IMAGE_H #define IMAGE_H #include //#include class Sample; // forward declaration /** * @addtogroup odindata * @{ */ ///////////////////////////////////////////////////////////////// /** * Class to hold reconstructed images of one Geometry */ class Image : public JcampDxBlock { public: /** * Default constructor */ Image(const STD_string& label="unnamedImage"); /** * Copy constructor */ Image(const Image& i) {Image::operator = (i);} /** * Assignment operator */ Image& operator = (const Image& i); /** * Sets the magnitude data */ Image& set_magnitude(const farray& magn) {magnitude=magn; return *this;} /** * Scale magnitude to values between 0 and 1 */ Image& normalize_magnitude() {magnitude.normalize(); return *this;} /** * Returns the magnitude data */ const farray& get_magnitude() const {return magnitude;} /** * Interpret data as 3D volume data and return size for given axis */ unsigned int size(axis ax) const; /** * Sets the parameter set which describes the area imaged */ Image& set_geometry(const Geometry& g) {geo=g; return *this;} /** * Returns the parameter set which describes the area imaged */ const Geometry& get_geometry() const {return geo;} /** * Transpose image in-plane, 'reverse_read' and 'reverse_phase' * can be used to reverse read/phase direction before transposing. */ Image& transpose_inplane(bool reverse_read=false, bool reverse_phase=false); // dummy comparison operator for lists bool operator < (const Image& img) const {return STD_string(get_label()) images; Image dummy; }; /** @} */ #endif odin-1.8.5/odindata/fileio_vtk.cpp0000644000175000017500000000714411712547771014043 00000000000000#include "fileio.h" #ifdef VTKSUPPORT #include #include ////////////////////////////////////////////////////////////// struct VtkFormat : public FileFormat { STD_string description() const {return "Visualization Toolkit";} svector suffix() const { svector result; result.resize(1); result[0]="vtk"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("VtkFormat","read"); ODINLOG(odinlog,errorLog) << "Implement me" << STD_endl; return -1; } int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { Log odinlog("VtkFormat","write"); vtkStructuredPointsWriter *out_write=vtkStructuredPointsWriter::New(); vtkStructuredPoints *out=vtkStructuredPoints::New(); out_write->SetInput(out); // setting format STD_string datatype=selectDataType(prot,opts); if(datatype==TypeTraits::type2label((float)0)) out->SetScalarTypeToFloat (); if(datatype==TypeTraits::type2label((double)0)) out->SetScalarTypeToDouble (); if(datatype==TypeTraits::type2label((s32bit)0)) out->SetScalarTypeToInt (); if(datatype==TypeTraits::type2label((u32bit)0)) out->SetScalarTypeToUnsignedInt (); if(datatype==TypeTraits::type2label((s16bit)0)) out->SetScalarTypeToShort (); if(datatype==TypeTraits::type2label((u16bit)0)) out->SetScalarTypeToUnsignedShort (); if(datatype==TypeTraits::type2label((s8bit)0)) out->SetScalarTypeToChar (); if(datatype==TypeTraits::type2label((u8bit)0)) out->SetScalarTypeToUnsignedChar (); // Data data3d; const Geometry& geo=prot.geometry; // const STD_string type(prot.system.get_data_type()); // if(type!="float" && type!="double")data.convert_to(data3d,noupscale); // else data.convert_to(data3d); int nrep=data.extent(timeDim); int nslice=data.extent(sliceDim); int nphase=data.extent(phaseDim); int nread=data.extent(readDim); ODINLOG(odinlog,normalDebug) << "nrep/nslice/nphase/nread "<< nrep << "/" << nslice << "/" << nphase << "/" << nread << STD_endl; out->SetDimensions(nread,nphase,nslice); out->SetSpacing(voxel_extent(geo, readDirection, nread), voxel_extent(geo, phaseDirection, nphase),voxel_extent(geo, sliceDirection, nslice)); out->SetOrigin(0,0,0); out->SetNumberOfScalarComponents(1); JDXfileName fname(filename); for(int irep=0; irepSetScalarComponentFromFloat(i,j,k,0,data(irep,k,j,i)); } } } STD_string onefilename=fname.get_dirname()+SEPARATOR_STR+fname.get_basename_nosuffix(); if(nrep>1) onefilename+="_time"+itos(irep,nrep-1); onefilename+="."+fname.get_suffix(); ODINLOG(odinlog,normalDebug) << "writing file "<< onefilename << STD_endl; out_write->SetFileName(onefilename.c_str()); out_write->SetScalarsName(onefilename.c_str()); // if(ascii) out_write->SetFileTypeToASCII(); // else out_write->SetFileTypeToBinary(); ostream *fp=out_write->OpenVTKFile(); out_write->Write(); out_write->CloseVTKFile(fp); } out->Delete(); out_write->Delete(); return nslice; } }; #endif ////////////////////////////////////////////////////////////// void register_vtk_format() { #ifdef VTKSUPPORT static VtkFormat vf; vf.register_format(); #endif } odin-1.8.5/odindata/converter.h0000644000175000017500000002743311712547771013367 00000000000000/*************************************************************************** converter.h - description ------------------- begin : Tue Dec 4 2001 copyright : (C) 2001 by Michael von Mengershausen email : mengers@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef CONVERTER_H #define CONVERTER_H #include #include #include #include #include #include /** * @addtogroup odindata * @{ */ // helper class used for debugging the odindata component class OdinData { public: static const char* get_compName(); }; //////////////////////////////////////////////////////////////////// /** * Scaling strategy when converting data to integer types: * - noscale: No scaling * - autoscale: scale/offset values so they will fit into the numeric limits of the destination (0 < scaling factor < inv) * - noupscale: dont upscale values to fit them into the destination (0 < scaling factor <=1) * Note: if destination is non integer no scaling is done at all */ enum autoscaleOption {noscale, autoscale,noupscale}; //////////////////////////////////////////////////////////////////// /** * Helper class for conversion between numbers */ class Converter { public: ////////////////////////////////////////////////////////// // get_elements function overloading // specializations for complex type static unsigned int get_elements(const STD_complex&) { return 2; } /** * Returns number of scalar numbers in this number type, e.g. complex has 2 */ template static unsigned int get_elements(const T&) { return 1; } ////////////////////////////////////////////////////////// /** * Converts array 'src' with 'srcsize' elements to array 'dst' with 'dstsize' elements * Will scale "around 0" if 0 is part of the source value range. Elsewise values will be offset towards 0. * If destination is unsigned values will be offset to be positive domain if necessary. * If autoscaleOption is "noscale" or if destination is floating point no scaling is done at all. */ template static void convert_array(const Src* src, Dst* dst, unsigned int srcsize, unsigned int dstsize, autoscaleOption scaleopt=autoscale) { Log odinlog("Converter","convert_array"); unsigned int srcstep=get_elements(*dst); unsigned int dststep=get_elements(*src); bool doScale = (scaleopt!=noscale && std::numeric_limits::is_integer); if(dststep*srcsize != srcstep*dstsize) { ODINLOG(odinlog,warningLog) << "size mismatch: dststep(" << dststep << ") * srcsize(" << srcsize << ") != srcstep(" << srcstep << ") * dstsize(" << dstsize << ")" << STD_endl; } double scale=1.0; double offset=0.0; if(doScale) { const double domain_minus=creal(std::numeric_limits::min());//negative value domain of this dst const double domain_plus =creal(std::numeric_limits::max());//positive value domain of this dst double minval=std::numeric_limits::min(); double maxval=std::numeric_limits::max(); if(srcsize>0) minval=maxval=creal(src[0]); for(unsigned int i=1; imaxval) maxval=creal(src[i]); } ODINLOG(odinlog,normalDebug) << "src Range:" << minval << "=>" << maxval << STD_endl; ODINLOG(odinlog,normalDebug) << "dst Domain:" << domain_minus << "=>" << domain_plus << STD_endl; assert(domain_minus<=0 && domain_plus>=0); //I think we can assume this assert(domain_minus0 || !domain_minus)offset=-minval; else if(maxval<0 || !domain_plus)offset=-maxval; //calculate range of values which will be on postive/negative domain when offset is applied const double range_plus =maxval+offset; //allways >=0 const double range_minus=minval+offset; //allways <=0 //set scaling factor to fit src-range into dst domain //some compilers dont make x/0 = inf, so we use std::numeric_limits::max() instead, in this case const double scale_plus = range_plus ? domain_plus/range_plus : std::numeric_limits::max(); const double scale_minus= range_minus ? domain_minus/ range_minus: std::numeric_limits::max(); ODINLOG(odinlog,normalDebug) << "scale_minus/scale_plus=" << scale_minus << "/" << scale_plus << STD_endl; scale = STD_min(scale_plus,scale_minus);//get the smaller scaling factor so the bigger range will fit into his domain if(scale<1){ ODINLOG(odinlog,normalDebug) << "Downscaling your values by Factor " << scale << " you might lose information."<< STD_endl; } else if(scaleopt==noupscale){ if(scale>1) { ODINLOG(odinlog,normalDebug) << "upscale not given, clamping scale " << scale << " to 1"<< STD_endl; } scale=1; } doScale=(scale!=1. || offset); offset*=scale;//calc offset for dst } if(doScale)ODINLOG(odinlog,normalDebug) << "converting with scale/offset=" << scale << "/" << offset << STD_endl; else ODINLOG(odinlog,normalDebug) << "converting without scaling" << STD_endl; if(srcstep==dststep)//use common convert for data of same complexity { if(doScale) convert_array_impl(src,dst, srcsize < dstsize?srcsize:dstsize,scale,offset); else convert_array_impl(src,dst, srcsize < dstsize?srcsize:dstsize); } else //do generic convert for data of different complexity { unsigned int srcindex=0, dstindex=0; while(srcindex static void convert_array_impl(const Src* src, Dst* dst, unsigned int count,double scale=1,double offset=0) { Log odinlog("Converter","convert_array_impl(generic)"); ODINLOG(odinlog,normalDebug) << "generic convert " << TypeTraits::type2label(*src) << "=>" << TypeTraits::type2label(*dst) << STD_endl; ODINLOG(odinlog,normalDebug) << "scale/offset=" << scale << "/" << offset << STD_endl; while(count--) convert(src++, dst++,scale,offset); } // Implementing our own round functions since lround/lroundf do not work for unsigned numbers, and they are flawed in MinGW template static T round(double x) { return (T)(x < 0 ? x - 0.5 : x + 0.5); } // specialized converter functions // to complex static void convert(const s8bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const u8bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const u16bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const s16bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const u32bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const s32bit* src, STD_complex* dst,float scale,float offset) { (*dst)=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const float *src, STD_complex* dst,float scale,float offset) { dst[0]=STD_complex(src[0]*scale+offset,src[1]*scale); } static void convert(const double *src, STD_complex* dst,float scale,float offset) { dst[0]=STD_complex(src[0]*scale+offset,src[1]*scale); } // from complex static void convert(const STD_complex* src, s8bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, u8bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, s16bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, u16bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, s32bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, u32bit* dst,float scale,float offset) { dst[0]=round(src->real()*scale+offset); dst[1]=round(src->imag()*scale); } static void convert(const STD_complex* src, float* dst,float scale,float offset) { dst[0]=src->real()*scale+offset; dst[1]=src->imag()*scale; } static void convert(const STD_complex* src, double* dst,float scale,float offset) { dst[0]=src->real()*scale+offset; dst[1]=src->imag()*scale; } // from float to integer static void convert(const float* src, s8bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const float* src, u8bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const float* src, s16bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const float* src, u16bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const float* src, s32bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const float* src, u32bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } // from double to integer static void convert(const double* src, s8bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const double* src, u8bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const double* src, s16bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const double* src, u16bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const double* src, s32bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } static void convert(const double* src, u32bit* dst,float scale,float offset) { dst[0]=round(src[0]*scale+offset); } //default template static void convert(const Src* src, Dst* dst,float scale,float offset) { dst[0]=(Dst)(src[0]*scale+offset); } ////////////////////////////////////////////////////////// Converter() {} // Do not allow instances }; /** @} */ #endif odin-1.8.5/odindata/gridding.h0000644000175000017500000002476611322062337013140 00000000000000/*************************************************************************** gridding.h - description ------------------- begin : Fri Jun 25 2004 copyright : (C) 2004 by Michael von Mengershausen email : mengers@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef GRIDDING_H #define GRIDDING_H #include #include #include /** * @addtogroup odindata * @{ */ /** * Coordinate with extra weight for gridding */ template struct GriddingPoint { GriddingPoint(const TinyVector& c=0.0, float w=1.0) : coord(c), weight(w) {} TinyVector coord; float weight; }; ///////////////////////////////////////////////////// /** * Functor for gridding, i.e. bringing values with arbitrary * coordinates onto a rectangular grid. */ template class Gridding { public: /** * Creates uninitialized gridding object */ Gridding() : shape(0) {} /** * Initializes a gridding object to perform a gridding operation with the following parameters: * - dst_shape: The dimensions of the gridded array * - dst_extent: The total extent of the gridded array, the gridded array is created symmetrically about the origin * - src_coords: The coordinates of the input array: First is tthe coordinate, second is an extra weight for the coordinate * - kernel: The gridding kernel used * - kernel_diameter: The maximum diameter of the gridding kernel in units of the source coordinates * Returns the density of source points on the gridded array */ Array init(const TinyVector& dst_shape, const TinyVector& dst_extent, const STD_vector >& src_coords, const JDXfilter& kernel, float kernel_diameter); /** * Put input array 'src' on the grid by stepping linearly through the inidices. * Gridding will start at the linear index 'offset' of the 'src_coords' * specified in the init() function. * Returns gridded array. */ template Array operator () (const Array& src, unsigned int offset=0) const; private: TinyVector shape; // numof src-steps x numof indices on dst grid x pair(dst-index, weight) STD_vector< STD_vector< STD_pair, float> > > recipe; }; ///////////////////////////////////////////////////// template Array Gridding::init(const TinyVector& dst_shape, const TinyVector& dst_extent, const STD_vector >& src_coords, const JDXfilter& kernel, float kernel_diameter) { Log odinlog("Gridding","init"); shape=dst_shape; unsigned int nsrc=src_coords.size(); ODINLOG(odinlog,normalDebug) << "nsrc/kernel/kernel_diameter=" << nsrc << "/" << kernel.get_function_name() << "/" << kernel_diameter << STD_endl; recipe.resize(nsrc); // array to collect sum of all weights for later normalization Array weight_sum(dst_shape); weight_sum=0.0; TinyVector dst_step=dst_extent/dst_shape; ODINLOG(odinlog,normalDebug) << "dst_step=" << dst_step << STD_endl; TinyVector kernel_extent; // In units of indices for(int irank=0; irank0.0) kernel_extent(irank)=kernel_diameter/dst_step(irank); else kernel_extent(irank)=0.0; } ODINLOG(odinlog,normalDebug) << "kernel_extent=" << kernel_extent << STD_endl; TinyVector offset=0.5*(dst_shape-1.0); // coordinate is at center of destination voxels // Iterate over src coordinates for(unsigned int isrc=0; isrc& point=src_coords[isrc]; // Find grid points in neighboordhood TinyVector root; // In units of indices on destination grid for(int irank=0; irank0.0) root(irank)=point.coord(irank)/dst_step(irank); else root(irank)=0.0; } root += offset; ODINLOG(odinlog,normalDebug) << "root=" << root << STD_endl; TinyVector lowindex=(root-0.5*kernel_extent)+0.5; // round up to next higher grid point TinyVector uppindex=(root+0.5*kernel_extent); // round down to next lower grid point ODINLOG(odinlog,normalDebug) << "lowindex/uppindex=" << lowindex << "/" << uppindex << STD_endl; // Possible points in neighboorhood TinyVector neighbours=uppindex-lowindex+1; ODINLOG(odinlog,normalDebug) << "neighbours=" << neighbours << STD_endl; // Get actual points in neighbourhood and their weight if they are within the support of the given kernel and whether point lies on destination grid STD_vector, float> >& dstvec=recipe[isrc]; dstvec.clear(); for(int ineighb=0; ineighb neighb_index=index2extent(neighbours, ineighb); // Check whether point is on grid TinyVector index=lowindex+neighb_index; bool ongrid=true; for(int i=0; i=dst_shape(i)) ongrid=false; } // Check whether point is within the support of the kernel if(ongrid) { TinyVector diff=(root-index)*dst_step; float radius=sqrt(sum(diff*diff))/(0.5*kernel_diameter); float weight=point.weight*kernel.calculate(radius); if(weight>=0.0) dstvec.push_back(STD_pair, float>(index,weight)); } } // Sum up weights for each index for(unsigned int idst=0; idst, float> >& dstvec=recipe[isrc]; for(unsigned int idst=0; idst, float>& weightpair=dstvec[idst]; float weightsum=weight_sum(weightpair.first); if(weightsum>0.0) weightpair.second/=weightsum; } } return weight_sum; } ///////////////////////////////////////////////////// template template Array Gridding::operator () (const Array& src, unsigned int offset) const { Log odinlog("Gridding","()"); Array result; unsigned int nsrc=src.size(); if((offset+nsrc)>recipe.size()) { ODINLOG(odinlog,errorLog) << "Max index of src=" << offset+nsrc << " exceeds recipe.size()=" << recipe.size() << STD_endl; return result; } result.resize(shape); result=T(0); for(unsigned int isrc=0; isrc, float> >& dstvec=recipe[offset+isrc]; for(unsigned int idst=0; idst, float>& weightpair=dstvec[idst]; result(weightpair.first) += weightpair.second * src(index2extent(src.shape(),isrc)); } } return result; } ///////////////////////////////////////////////////////////////////////////////// /** * Functor for coordinate transformation using gridding */ template class CoordTransformation { public: /** * Initializes a transformation of an array with shape 'shape' to new coordinates using a gridding algorithm. * New coordinates (...z',y',x') are obtained by multiplying (...z,y,x) * with 'rotation' and adding 'offset'. Origin is the center of the data set. */ CoordTransformation(const TinyVector& shape, const TinyMatrix& rotation, const TinyVector& offset, float kernel_size=2.5); /** * Transforms 'A' to new coordinates and returns the result */ Array operator () (const Array& A) const; private: TinyVector shape_cache; Gridding gridder; }; ///////////////////////////////////////////////////// template CoordTransformation::CoordTransformation(const TinyVector& shape, const TinyMatrix& rotation, const TinyVector& offset, float kernel_size) : shape_cache(shape) { Log odinlog("CoordTransformation","CoordTransformation"); int nsrc=product(shape); STD_vector > src_coords(nsrc); ODINLOG(odinlog,normalDebug) << "N_rank/nsrc=" << N_rank << "/" << nsrc << STD_endl; TinyVector extent_half; if(OnPixelRot) extent_half=shape/2; // suitable for rotating k-space else extent_half=0.5*(shape-1); // center of even size is between voxels TinyVector index; TinyVector findex; for(int isrc=0; isrc Array CoordTransformation::operator () (const Array& A) const { Log odinlog("CoordTransformation","()"); if(A.shape()!=shape_cache) { ODINLOG(odinlog,errorLog) << "Shape mismatch" << STD_endl; return A; } return gridder(A); } /** @} */ #endif odin-1.8.5/odindata/fileio_3db.cpp0000644000175000017500000000374511322062337013675 00000000000000// // C++ Implementation: fileio_3Db // // Description: // // // Author: <>, (C) 2008 // // Copyright: See COPYING file that comes with this distribution // // #include "fileio.h" #include "complexdata.h" ////////////////////////////////////////////////////////////// struct Iris3DFormat : public FileFormat { struct i3Dblock { short nx, ny, nz, veclen; float x0, y0, z0, dx, dy, dz; }; STD_string description() const {return "Iris3D binary data";} svector suffix() const { svector result; result.resize(1); result[0]="3db"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("Iris3DFormat","read"); ODINLOG(odinlog,errorLog) << "Read of Iris3D not yet supported, sorry"<< STD_endl; return -1; } int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { Log odinlog("Iris3DFormat","write"); FILE *out=FOPEN( filename.c_str(), "w"); if(!out){ ODINLOG(odinlog,errorLog) << "could not open "<< filename <<" for writing"<< STD_endl; return -1; } Data data_copy(data); const TinyVector data_shape=data.shape(); const dvector center(prot.geometry.get_center()); const i3Dblock head={ data_shape[3],data_shape[2],data_shape[1], 1, center[0],center[2],center[2], voxel_extent(prot.geometry,readDirection, data.extent(3)), voxel_extent(prot.geometry,phaseDirection, data.extent(2)), prot.geometry.get_sliceDistance() }; fwrite(&head,sizeof(i3Dblock),1,out); size_t cnt=fwrite(data_copy.c_array(),sizeof(float),product(data_shape),out); fclose(out); return int(cnt)==product(data_shape); } }; ////////////////////////////////////////////////////////////// void register_Iris3D_format() { static Iris3DFormat iris; iris.register_format(); } odin-1.8.5/odindata/filter_tile.cpp0000644000175000017500000000250011322062337014164 00000000000000#include "filter_tile.h" void FilterTile::init(){ cols.set_description("columns"); append_arg(cols,"cols"); } bool FilterTile::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Range all=Range::all(); int nrep=data.extent(0); int nslice=data.extent(1); int nphase=data.extent(2); int nread=data.extent(3); if(cols<=0 || cols>nslice) { ODINLOG(odinlog,errorLog) << "cols=" << int(cols) << " out of range" << STD_endl; return false; } int rows=nslice/cols; if(nslice%cols) rows++; ODINLOG(odinlog,normalDebug) << "nslice/cols/rows=" << nslice << "/" << int(cols) << "/" << rows << STD_endl; int newnphase=rows*nphase; int newnread=cols*nread; Data outdata(nrep,1,newnphase,newnread); outdata=0.0; int icol=0; int irow=0; for(int islice=0; islice=cols) { icol=0; irow++; } } data.reference(outdata); // adjust protocol prot.geometry.set_nSlices(1); prot.seqpars.set_MatrixSize(phaseDirection,newnphase); prot.seqpars.set_MatrixSize(readDirection,newnread); return true; } odin-1.8.5/odindata/fileio_png.cpp0000644000175000017500000001564411725203122014006 00000000000000#include "fileio.h" #ifdef PNGSUPPORT #include /* write a png file */ bool write_png(const char *filename, Data &buff){ FILE *fp; png_structp png_ptr; png_infop info_ptr; Log odinlog("PNGFormat","write"); ODINLOG(odinlog,normalDebug) << "Saving data of shape " << buff.shape() << " to " << filename << STD_endl; /* open the file */ fp = fopen(filename, "wb"); if (fp == NULL){ ODINLOG(odinlog,errorLog) << "Opening " << filename << " failed: " << strerror(errno) << STD_endl; errno=0; return false; } /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible with the one used at compile time, * in case we are using dynamically linked libraries. REQUIRED. */ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL /*user_error_ptr*/, NULL /*user_error_fn*/, NULL /*user_warning_fn*/); if (png_ptr == NULL){ fclose(fp); ODINLOG(odinlog,errorLog) << "png_create_write_struct failed: " << (errno ? strerror(errno):"") << STD_endl; errno=0; return false; } /* Allocate/initialize the image information data. REQUIRED */ info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL){ fclose(fp); ODINLOG(odinlog,errorLog) << "png_create_info_struct failed: " << (errno ? strerror(errno):"") << STD_endl; errno=0; return false; } /* Set error handling. REQUIRED if you aren't supplying your own * error handling functions in the png_create_write_struct() call. */ if (setjmp(png_jmpbuf(png_ptr))){ /* If we get here, we had a problem writing the file */ ODINLOG(odinlog,errorLog) << "Could not write to " << filename << " " << (errno ? strerror(errno):"") << STD_endl; errno=0; fclose(fp); png_destroy_write_struct(&png_ptr, &info_ptr); return false; } /* set up the output control if you are using standard C streams */ png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, buff.shape()(readDim), buff.shape()(phaseDim),8, PNG_COLOR_TYPE_GRAY, PNG_INTERLACE_NONE,PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); /* png needs a pointer to each row */ u8bit *rp=buff.c_array(); png_byte** row_pointers= new png_byte*[buff.shape()(thirdDim)]; for (unsigned short r=0; r read_png(const char *filename){ Log odinlog("PNGFormat","read_png"); Data ret; png_byte header[8]; // 8 is the maximum size that can be checked /* open file and test for it being a png */ FILE *fp = fopen(filename, "rb"); if (!fp){ ODINLOG(odinlog,normalDebug) << "File " << filename << " could not be opened." << STD_endl; return -1; } fread(header, 1, 8, fp); if (png_sig_cmp(header, 0, 8)){ ODINLOG(odinlog,normalDebug) << "File " << filename << " is not recognized as a PNG file." << STD_endl; return -1; } png_structp png_ptr; png_infop info_ptr; /* initialize stuff */ png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); assert(png_ptr); info_ptr = png_create_info_struct(png_ptr); assert(info_ptr); if (setjmp(png_jmpbuf(png_ptr))); png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, 8); png_read_info(png_ptr, info_ptr); unsigned int height=png_get_image_height(png_ptr, info_ptr); // = info_ptr->height; unsigned int width=png_get_image_width(png_ptr, info_ptr); // = info_ptr->width; unsigned char colortype=png_get_color_type(png_ptr, info_ptr); // = info_ptr->color_type; unsigned char bitdepth=png_get_bit_depth(png_ptr, info_ptr); // = info_ptr->bit_depth; ret.resize(height, width); png_set_interlace_handling(png_ptr); ODINLOG(odinlog,normalDebug) << "color_type/bit_depth=" << int(colortype) << "/" << int(bitdepth) << STD_endl; if(colortype!=PNG_COLOR_TYPE_GRAY) { ODINLOG(odinlog,errorLog) << "Unsupported color mode, only grayscale images are supported" << STD_endl; fclose(fp); return -1; } png_read_update_info(png_ptr, info_ptr); /* png needs a pointer to each row */ png_bytep* row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * height); png_bytep rp=ret.c_array(); for (unsigned short r=0; r& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot){ read_png(filename.c_str()).convert_to(data); return 1; } int write(const Data& data, const STD_string& filename, const FileWriteOpts& opts, const Protocol& prot) { Log odinlog("PNGFormat","write"); Range all=Range::all(); TinyVector shape(data.shape()); unsigned short time=shape(timeDim),slices=shape(sliceDim); ODINLOG(odinlog,normalDebug) << "filename=" << filename << STD_endl; JDXfileName fname(filename); bool ok=true; int s=0,t=0; Data buff; const STD_string type(prot.system.get_data_type()); if(type!="float" && type!="double")data.convert_to(buff,noupscale); else data.convert_to(buff); for(t=0;ok && t1) onefilename+="_time"+itos(t,time-1); if(slices>1) onefilename+="_slice"+itos(s,slices-1); onefilename+="."+fname.get_suffix(); ODINLOG(odinlog,normalDebug) << "Writing " << onefilename << STD_endl; Data slice(buff(Range(t),Range(s),all,all)); ok = write_png(onefilename.c_str(), slice); } if(ok){ODINLOG(odinlog,normalDebug) << "Wrote " << t*s << " images" << STD_endl;return t*s;} else return -1; } }; #endif ////////////////////////////////////////////////////////////// void register_png_format() { #ifdef PNGSUPPORT static PNGFormat format; format.register_format(); #endif } odin-1.8.5/odindata/fileio_jdx.cpp0000644000175000017500000001417211363773554014025 00000000000000#include "fileio.h" #include "image.h" ///////////////////////////////////////////////////////////// void resize4dim(farray& fdata) { if(fdata.dim()==4) return; // leave untouched if it is already 4dim fdata.autosize(); ndim nn=fdata.get_extent(); bool add_first_dim=true; if(nn.dim()==1) add_first_dim=false; while(nn.dim()<4) nn.add_dim(1,add_first_dim); while(nn.dim()>4) --nn; fdata.redim(nn); } ///////////////////////////////////////////////////////////// struct JdxFormat : public FileFormat { STD_string description() const {return "JCAMP-DX data sets";} svector suffix() const { svector result; result.resize(2); result[0]="smp"; result[1]="coi"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("JdxFormat","read"); STD_string arrlabel=opts.jdx; if(arrlabel=="") { if(JDXfileName(filename).get_suffix()=="smp") arrlabel="spinDensity"; else { ODINLOG(odinlog,errorLog) << "No array label provided, use the 'jdx' option to specify one" << STD_endl; return -1; } } JcampDxBlock block; farray fdata; bool valid_type=false; if(!valid_type) { JDXdoubleArr dpar; dpar.set_label(arrlabel); block.clear(); block.append(dpar); if(block.load(filename)>0) { ODINLOG(odinlog,normalDebug) << "JDXdoubleArr detected" << STD_endl; fdata.redim(dpar.get_extent()); for(unsigned int i=0; i0) { ODINLOG(odinlog,normalDebug) << "JDXfloatArr detected" << STD_endl; fdata.redim(fpar.get_extent()); for(unsigned int i=0; i0) { ODINLOG(odinlog,normalDebug) << "JDXcomplexArr detected" << STD_endl; ndim nn=cpar.get_extent(); nn[0]*=2; fvector amp=amplitude(cpar); fvector pha=phase(cpar); ODINLOG(odinlog,normalDebug) << "nn=" << STD_string(nn) << STD_endl; fdata.redim(nn); unsigned int n=cpar.length(); for(unsigned int i=0; i& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { Log odinlog("JdxFormat","write"); ODINLOG(odinlog,errorLog) << "Not implemented" << STD_endl; return -1; } }; ///////////////////////////////////////////////////////////// struct ImageFormat : public FileFormat { STD_string description() const {return "JCAMP-DX image format";} svector suffix() const { svector result; result.resize(1); result[0]="jdx"; return result; } svector dialects() const {return svector();} int read(FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileReadOpts& opts, const Protocol& protocol_template) { Log odinlog("ImageFormat","read"); int result=0; ImageSet imgset; if(imgset.load(filename)<0) return -1; int nsets=imgset.get_numof_images(); if(nsets<=0) return -1; ODINLOG(odinlog,normalDebug) << "nsets=" << nsets << STD_endl; Protocol prot(protocol_template); for(int i=0; i& data=pdmap[prot]; farray fdata=imgset.get_image(i).get_magnitude(); resize4dim(fdata); data=fdata; result+=data.extent(0)*data.extent(1); } return result; } int write(const FileIO::ProtocolDataMap& pdmap, const STD_string& filename, const FileWriteOpts& opts) { Log odinlog("ImageFormat","write"); int result=0; ImageSet imgset(filename); for(FileIO::ProtocolDataMap::const_iterator pdit=pdmap.begin(); pdit!=pdmap.end(); ++pdit) { STD_string series; int number; pdit->first.study.get_Series(series, number); Image img(series); // use series description as image label img.set_geometry(pdit->first.geometry); img.set_magnitude(pdit->second); imgset.append_image(img); result+=pdit->second.extent(0)*pdit->second.extent(1); } if(imgset.write(filename)<0) return -1; return result; } }; ///////////////////////////////////////////////////////////// struct ProtFormat : public FileFormat { STD_string description() const {return "ODIN measurement protocols";} svector suffix() const { svector result; result.resize(1); result[0]="pro"; return result; } svector dialects() const {return svector();} int read(Data& data, const STD_string& filename, const FileReadOpts& opts, Protocol& prot) { Log odinlog("ProtFormat","read"); if(prot.load(filename)<0) return false; data.resize(1, prot.seqpars.get_MatrixSize(sliceDirection), prot.seqpars.get_MatrixSize(phaseDirection), prot.seqpars.get_MatrixSize(readDirection)); // only one repetition data=0.0; return data.extent(0)*data.extent(1); } int write(const Data& data, const STD_string& filename, const FileWriteOpts&, const Protocol& prot) { Log odinlog("ProtFormat","write"); return prot.write(filename); } }; ////////////////////////////////////////////////////////////// void register_jdx_format() { static JdxFormat jf; static ImageFormat imf; static ProtFormat pf; jf.register_format(); imf.register_format(); pf.register_format(); } odin-1.8.5/odindata/filter_detrend.cpp0000644000175000017500000000344211712547770014676 00000000000000#include "filter_detrend.h" #include "fitting.h" void FilterDeTrend::init(){ nlow=5; nlow.set_description("Number of low frequency components to be removed"); append_arg(nlow,"nlow"); zeromean=false; zeromean.set_description("Zero mean of resulting timecourse"); append_arg(zeromean,"zeromean"); } bool FilterDeTrend::process(Data& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Range all=Range::all(); TinyVector shape=data.shape(); if(nlow<2 || shape(0)<2) { ODINLOG(odinlog,warningLog) << "Too few time points: nlow=" << int(nlow) << ", shape=" << shape << STD_endl; return true; } if(nlow==2) { // Remove linear trend LinearFunction linf; for(int islice=0; islice lowshape=shape; lowshape(0)=nlow; Data lowdata(data.copy()); lowdata.congrid(lowshape); lowdata.congrid(shape); if(!zeromean) { for(int islice=0; islice class FilterScale : public FilterStep { JDXfloat slope; JDXfloat offset; STD_string label() const {return "scale";} STD_string description() const {return "Rescale image values";} bool process(Data& data, Protocol& prot) const; FilterStep* allocate() const {return new FilterScale();} void init(); }; #endif odin-1.8.5/odindata/fileio_opts.cpp0000644000175000017500000000673611665172216014225 00000000000000#include "fileio_opts.h" #include "fileio.h" FileReadOpts::FileReadOpts() { format.add_item(AUTODETECTSTR); svector formats(FileIO::autoformats()); for(unsigned int i=0; i& data, Protocol& prot) const { Log odinlog(c_label(),"process"); Range all=Range::all(); ODINLOG(odinlog,normalDebug) << "angle=" << angle << STD_endl; RotMatrix rotmat; rotmat.set_inplane_rotation(angle*PII/180.0); ODINLOG(odinlog,normalDebug) << "rotmat=" << rotmat.print() << STD_endl; TinyVector offset=0.0; TinyMatrix rotation; for(int irow=0; irow<2; irow++) { for(int icol=0; icol<2; icol++) { rotation(1-irow,1-icol)=rotmat[irow][icol]; } } CoordTransformation transform(TinyVector(data.extent(phaseDim),data.extent(readDim)), rotation, offset, kernel); for(int irep=0; irep /** * @addtogroup odindata * @{ */ /** * Solves the linear system A x = b and returns x. * All singular values less than sv_truncation * max_singular_value * will be set to zero. * The algorithm uses the singular value decomposition from LAPACK (or from GSL if LAPACK is not available). * */ Data solve_linear(const Data& A, const Data& b, float sv_truncation=0.0); /** * Solves the complex linear system A x = b and returns x. * All singular values less than sv_truncation * max_singular_value * will be set to zero. * The algorithm uses the singular value decomposition from LAPACK (or from GSL if LAPACK is not available). * */ ComplexData<1> solve_linear(const ComplexData<2>& A, const ComplexData<1>& b, float sv_truncation=0.0); /** * Computes the eigenvalues of symmetric matrix A using LAPACK (or with GSL if LAPACK is not available). * */ Data eigenvalues(const Data& A); /** @} */ #endif odin-1.8.5/odindata/utils.cpp0000644000175000017500000000610111734622163013031 00000000000000#include "utils.h" #include "fitting.h" // for unit test #include "complexdata.h" // for unit test #include Data unwrap_phase(const Data& phase, int startindex) { Log odinlog("","unwrap_phase"); int n=phase.size(); Data result(n); if(startindex<0 || startindex>=n) { ODINLOG(odinlog,errorLog) << "startindex=" << startindex << " out of range (0," << (n-1) << ")" << STD_endl; return result; } for(int j=0; jPII) { ODINLOG(odinlog,errorLog) << "phase(" << j << ")=" << phase(j) << " out of range (" << -PII << "," << PII << ")" << STD_endl; return result; } } result(startindex)=phase(startindex); // unwrap going to higher indices int i=startindex; int mod=0; while( (i+1) < n ) { float diff=phase(i+1)-phase(i); if(diff>PII) mod--; if(diff<-PII) mod++; result(i+1)=phase(i+1)+mod*2.0*PII; i++; } // unwrap going to lower indices i=startindex; mod=0; while( (i-1) >= 0 ) { float diff=phase(i-1)-phase(i); if(diff>PII) mod--; if(diff<-PII) mod++; result(i-1)=phase(i-1)+mod*2.0*PII; i--; } return result; } ////////////////////////////////////////////////// // Unit Test #ifndef NO_UNIT_TEST class DataUtilsTest : public UnitTest { public: DataUtilsTest() : UnitTest("DataUtils") {} private: bool check() const { Log odinlog(this,"check"); PolynomialFunction<3> poly; poly.a[0].val=-20.0; poly.a[1].val=-10.0; poly.a[2].val=2.0; poly.a[3].val=0.5; int nx=1000; float xrange=10.0; Data xvals(nx); for(int i=0; i yvals(poly.get_function(xvals)); // yvals.autowrite("yvals.asc"); ComplexData<1> cplxdata(expc(float2imag(yvals))); Data pha(phase(cplxdata)); // pha.autowrite("pha.asc"); int nstart=5; int startindex[nstart]; startindex[0]=0; startindex[1]=nx/3; startindex[2]=nx/2; startindex[3]=3*nx/4; startindex[4]=nx-1; for(int istart=0; istart pha_unwrap(unwrap_phase(pha,startindex[istart])); pha_unwrap-=pha_unwrap(startindex[istart])-yvals(startindex[istart]); // pha_unwrap.autowrite("pha_unwrap.asc"); float diff=sum(fabs(pha_unwrap-yvals))/nx; if(diff>1.0e-5) { ODINLOG(odinlog,errorLog) << "unwrap_phase(...," << startindex[istart] << "), diff=" << diff << STD_endl; return false; } } return true; } }; void alloc_DataUtilsTest() {new DataUtilsTest();} // create test instance #endif ////////////////////////////////////////////////// // Test Instantiations #ifdef ODIN_DEBUG template Array matrix_product(const Array&, const Array&); template Array vector_product(const Array&, const Array&); template bool same_shape(const Array&, const Array&,const TinyVector&); template bool check_range(float&, float, float); #endif odin-1.8.5/odinpara/0000755000175000017500000000000011735135550011261 500000000000000odin-1.8.5/odinpara/seqpars.h0000644000175000017500000001335611455553536013047 00000000000000/*************************************************************************** seqpars.h - description ------------------- begin : Mon Mar 3 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SEQPARS_H #define SEQPARS_H #include #include #include #include #include /** * @ingroup odinpara * * \brief Sequence Parameter proxy * * This class is used to hold all common sequence parameters */ class SeqPars : public JcampDxBlock { public: /** * Constructs a SeqPars with the given label */ SeqPars(const STD_string& label="unnamedSeqPars"); /** * Constructs a copy of 'sp' */ SeqPars(const SeqPars& sp) {SeqPars::operator = (sp);} /** * Specifies the size of the image in the given direction 'dir' to 'size' */ SeqPars& set_MatrixSize(direction dir,unsigned int size, parameterMode parmode=edit); /** * Returns the size of the image in the given direction */ unsigned int get_MatrixSize(direction dir) const; /** * Specifies the repetition time of the sequence */ SeqPars& set_RepetitionTime(double time, parameterMode parmode=edit); /** * Returns the repetition time of the sequence */ double get_RepetitionTime() const {return RepetitionTime;} /** * Specifies the number of times the sequence will be repeated */ SeqPars& set_NumOfRepetitions(unsigned int times, parameterMode parmode=edit); /** * Returns the number of times the sequence will be repeated */ unsigned int get_NumOfRepetitions() const {return NumOfRepetitions;} /** * Specifies the echo time of the sequence */ SeqPars& set_EchoTime(double time, parameterMode parmode=edit); /** * Returns the echo time of the sequence */ double get_EchoTime() const {return EchoTime;} /** * Specifies the sweep width of the acquisition window */ SeqPars& set_AcqSweepWidth(double sw, parameterMode parmode=edit); /** * Returns the sweep width of the acquisition window */ double get_AcqSweepWidth() const {return AcqSweepWidth;} /** * Specifies the flip angle of the excitation pulse */ SeqPars& set_FlipAngle(double fa, parameterMode parmode=edit); /** * Returns the flip angle of the excitation pulse */ double get_FlipAngle() const {return FlipAngle;} /** * Specifies the reduction factor for parallel imaging */ SeqPars& set_ReductionFactor(unsigned int factor, parameterMode parmode=edit); /** * Returns the reduction factor for parallel imaging */ unsigned int get_ReductionFactor() const {return ReductionFactor;} /** * Specifies the partial Fourier factor (0.0 = full k-space, 1.0 = half k-space) */ SeqPars& set_PartialFourier(float factor, parameterMode parmode=edit); /** * Returns the partial Fourier factor (0.0 = full k-space, 1.0 = half k-space) */ float get_PartialFourier() const {return PartialFourier;} /** * Specifies whether RF spoiling is used */ SeqPars& set_RFSpoiling(bool flag, parameterMode parmode=edit); /** * Returns whether RF spoiling is used */ bool get_RFSpoiling() const {return RFSpoiling;} /** * Specifies whether gradient intro will be played out prior to sequence */ SeqPars& set_GradientIntro(bool flag, parameterMode parmode=edit); /** * Returns whether gradient intro will be played out prior to sequence */ bool get_GradientIntro() const {return GradientIntro;} /** * Specifies whether a physiological trigger is used */ SeqPars& set_PhysioTrigger(bool flag, parameterMode parmode=edit); /** * Returns whether a physiological trigger is used */ bool get_PhysioTrigger() const {return PhysioTrigger;} /** * Sets the label of the sequence used */ SeqPars& set_Sequence(const STD_string& seqid) {Sequence=seqid; return *this;} /** * Returns the label of the sequence used */ const STD_string& get_Sequence() const {return Sequence;} /** * Sets the total duration of the sequence in minutes */ SeqPars& set_ExpDuration(double dur) {ExpDuration=dur; return *this;} /** * Returns the total duration of the sequence in minutes */ double get_ExpDuration() const {return ExpDuration;} /** * Sets the starting time point of the sequence */ SeqPars& set_AcquisitionStart(double time) {AcquisitionStart=time; return *this;} /** * Returns the starting time point of the sequence */ double get_AcquisitionStart() const {return AcquisitionStart;} /** * Assignment operator */ SeqPars& operator = (const SeqPars& pars2); private: void append_all_members(); JDXdouble ExpDuration; JDXstring Sequence; JDXdouble AcquisitionStart; JDXint MatrixSizeRead; JDXint MatrixSizePhase; JDXint MatrixSizeSlice; JDXdouble RepetitionTime; JDXint NumOfRepetitions; JDXdouble EchoTime; JDXdouble AcqSweepWidth; JDXdouble FlipAngle; JDXint ReductionFactor; JDXfloat PartialFourier; JDXbool RFSpoiling; JDXbool GradientIntro; JDXbool PhysioTrigger; }; #endif odin-1.8.5/odinpara/jdxarrays.cpp0000644000175000017500000004654211322062341013714 00000000000000#include "jdxarrays.h" #include "jdxblock.h" // for UnitTest #include #include #define ENCODING_ID_STR "Encoding:" #define BASE64_LINELEN 72 class Base64 { public: Base64() { int i; for (i = 0; i < 9; i++) { dtable_encode[i] = 'A' + i; dtable_encode[i + 9] = 'J' + i; dtable_encode[26 + i] = 'a' + i; dtable_encode[26 + i + 9] = 'j' + i; } for (i = 0; i < 8; i++) { dtable_encode[i + 18] = 'S' + i; dtable_encode[26 + i + 18] = 's' + i; } for (i = 0; i < 10; i++) { dtable_encode[52 + i] = '0' + i; } dtable_encode[62] = '+'; dtable_encode[63] = '/'; for (i = 0; i < 255; i++) dtable_decode[i] = 0x80; for (i = 'A'; i <= 'I'; i++) dtable_decode[i] = 0 + (i - 'A'); for (i = 'J'; i <= 'R'; i++) dtable_decode[i] = 9 + (i - 'J'); for (i = 'S'; i <= 'Z'; i++) dtable_decode[i] = 18 + (i - 'S'); for (i = 'a'; i <= 'i'; i++) dtable_decode[i] = 26 + (i - 'a'); for (i = 'j'; i <= 'r'; i++) dtable_decode[i] = 35 + (i - 'j'); for (i = 's'; i <= 'z'; i++) dtable_decode[i] = 44 + (i - 's'); for (i = '0'; i <= '9'; i++) dtable_decode[i] = 52 + (i - '0'); dtable_decode[(int)'+'] = 62; dtable_decode[(int)'/'] = 63; dtable_decode[(int)'='] = 0; } static const char* get_encoding_id() {return "base64";} bool encode(STD_string* ostring, STD_ostream* ostream, unsigned char* data, unsigned int nbytes) const { int i; bool hiteof=false; unsigned int counter=0; unsigned int linelength=0; while (!hiteof) { unsigned char igroup[3], ogroup[4]; int n; unsigned char c; igroup[0] = igroup[1] = igroup[2] = 0; for (n = 0; n < 3; n++) { if(counter 0) { ogroup[0] = dtable_encode[igroup[0] >> 2]; ogroup[1] = dtable_encode[((igroup[0] & 3) << 4) | (igroup[1] >> 4)]; ogroup[2] = dtable_encode[((igroup[1] & 0xF) << 2) | (igroup[2] >> 6)]; ogroup[3] = dtable_encode[igroup[2] & 0x3F]; if (n < 3) { ogroup[3] = '='; if (n < 2) { ogroup[2] = '='; } } for (i = 0; i < 4; i++) { if (linelength >= BASE64_LINELEN) { if(ostream) (*ostream) << STD_endl; if(ostring) (*ostring)+="\n"; linelength = 0; } if(ostream) (*ostream) << ogroup[i]; if(ostring) (*ostring)+=STD_string(1,ogroup[i]); linelength++; } } } return true; } bool decode(const STD_string& istring, unsigned char* data, unsigned int reserved_nbytes) const { Log odinlog("Base64","decode"); int string_counter=0; int output_counter=0; int stringsize=istring.length(); if(!stringsize) { if(reserved_nbytes) { ODINLOG(odinlog,errorLog) << "empty string" << STD_endl; return false; } return true; } unsigned char c; unsigned char a[4], b[4], o[3]; int i; string_counter=textbegin(istring,string_counter); while (string_counter>=0 && string_counter=stringsize ) { ODINLOG(odinlog,errorLog) << "string has illegal size: string_counter/stringsize=" << string_counter << "/" << stringsize << STD_endl; return false; } c = istring[string_counter]; string_counter++; string_counter=textbegin(istring,string_counter); if (dtable_decode[c] & 0x80) { ODINLOG(odinlog,errorLog) << "Illegal character >" << c << "< in input string" << STD_endl; return false; } a[i] = c; b[i] = (unsigned char) dtable_decode[c]; } o[0] = (b[0] << 2) | (b[1] >> 4); o[1] = (b[1] << 4) | (b[2] >> 2); o[2] = (b[2] << 6) | b[3]; int nbytes2copy = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3); for (i = 0; i < nbytes2copy; i++) { if(output_counter void JDXarray::common_init() { Log odinlog(this,"common_init"); JcampDxClass::set_parmode(noedit); // Do NOT call virtual function in constructor! guiprops.scale[xPlotScale].label="Data Point"; } template JDXarray::JDXarray (const A& a,const STD_string& name, bool userParameter, compatMode mode, parameterMode parameter_mode, const STD_string& parx_equivalent, float parx_assign_factor,float parx_assign_offset) : A(a) { Log odinlog(name.c_str(),"JDXarray(const A&)"); common_init(); set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); parx_equiv.name=parx_equivalent; parx_equiv.factor=parx_assign_factor; parx_equiv.offset=parx_assign_offset; JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! } template JDXarray& JDXarray::operator = (const A& a) { Log odinlog(this,"operator = (const A&)"); A::operator = (a); return *this; } template JDXarray& JDXarray::operator = (const JDXarray& ja) { JcampDxClass::operator = (ja); A::operator = (ja); parx_equiv=ja.parx_equiv; return *this; } template STD_string JDXarray::get_dim_str() const { ndim nn(A::get_extent()); J basetype; if( get_compatmode()==bruker && basetype.get_typeInfo()==STD_string("string") ) { if(nn.dim()==1 && nn[0]==1) --nn; unsigned int l=0; // val.length()*_BRUKER_MODE_STRING_CAP_FACTOR_; if(l<_BRUKER_MODE_STRING_CAP_START_) l=_BRUKER_MODE_STRING_CAP_START_; nn.add_dim(l,false); } return STD_string(nn); } template bool JDXarray::encode(STD_string* ostring, STD_ostream* ostream) const { Base64 b64; unsigned char* data=(unsigned char*)A::c_array(); if(!data) return false; JDXendianess endianess; J jdxdummy; STD_string header=STD_string(ENCODING_ID_STR) +b64.get_encoding_id()+"," +endianess.JDXenum::operator STD_string ()+"," +jdxdummy.get_typeInfo()+"\n"; if(ostring) (*ostring) += header; if(ostream) (*ostream) << header; return b64.encode(ostring,ostream,data,A::length()*A::elementsize()); } template STD_ostream& JDXarray::print2stream(STD_ostream& os) const { os << get_dim_str() << "\n"; if( !(use_compression() && encode(0,&os)) ) { A::printbody2stream(os); } return os; } template STD_string JDXarray::printvalstring() const { STD_string result; if(get_filemode()==exclude) return result; result+=get_dim_str()+"\n"; if( !(use_compression() && encode(&result,0)) ) { result+=A::printbody(); } return result; } template bool JDXarray::parsevalstring(const STD_string& parstring) { Log odinlog(this,"parsevalstring"); J basetype; STD_string ps=parstring+"\n##"; STD_string sizestring="("+extract(ps,"(",")")+")"; ndim nn(sizestring); if( get_compatmode()==bruker && basetype.get_typeInfo()==STD_string("string") ) nn--; ODINLOG(odinlog,normalDebug) << "sizestring=>" << sizestring << "<" << STD_endl; STD_string valstring=extract(ps,"\n","##"); unsigned long lnn=nn.total(); if(valstring.find(ENCODING_ID_STR)==0) { // array is encoded ODINLOG(odinlog,normalDebug) << "array data is encoded, lnn=" << lnn << STD_endl; Base64 b64; STD_string header=extract(valstring,STD_string(ENCODING_ID_STR),"\n"); svector headertokens(tokens(header,',')); if(headertokens.size()!=3) { ODINLOG(odinlog,errorLog) << "Invalid encoding header" << STD_endl; return false; } STD_string encodingtype=shrink(headertokens[0]); if(encodingtype!=b64.get_encoding_id()) { ODINLOG(odinlog,errorLog) << "Unknown encoding type " << encodingtype << STD_endl; return false; } JDXendianess endianess; STD_string endianess_string=shrink(headertokens[1]); endianess.JDXenum::operator = (endianess_string); ODINLOG(odinlog,normalDebug) << "header/encodingtype/endianess_string=" << header << "/" << encodingtype << "/" << endianess_string << STD_endl; STD_string typestring=shrink(headertokens[2]); J ldrdummy; if(typestring!=ldrdummy.get_typeInfo()) { // avoid confusing error message in miview // ODINLOG(odinlog,errorLog) << "Type mismatch of encoded data: " << typestring << "!=" << ldrdummy.get_typeInfo() << STD_endl; return false; } STD_string encoded_string=extract(valstring,header,""); unsigned int elsize=A::elementsize(); unsigned int nbytes=lnn*elsize; ODINLOG(odinlog,normalDebug) << "elsize/lnn/nbytes=" << elsize << "/" << lnn << "/" << nbytes << STD_endl; // allocate correctly aligned memory unsigned char* data=(unsigned char*)A::allocate_memory(lnn); if(data) { bool encresult; if(encresult=b64.decode(encoded_string,data,nbytes)) { if(int(endianess)!=int(little_endian_byte_order())) { ODINLOG(odinlog,normalDebug) << "swapping data" << STD_endl; swabdata(data,elsize,lnn); } A::redim(nn); ODINLOG(odinlog,normalDebug) << "nn=" << STD_string(nn) << STD_endl; A::set_c_array(data,lnn); } delete[] data; return encresult; } else return false; } // array is plain ASCII svector tokenvector(tokens(valstring)); unsigned long lstr=tokenvector.size(); if(lstr<1) { A::resize(0); return true; } if(lstr!=lnn) { ODINLOG(odinlog,errorLog) << "size mismatch ("<< lstr << "!=" << lnn << ")" << STD_endl; return false; } ODINLOG(odinlog,normalDebug) << "anlayzed " << lnn << " tokens" << STD_endl; A::redim(nn); J jdxdummy; for(unsigned long i=0;i STD_string JDXarray::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN Log odinlog(this,"get_parx_code"); STD_string result=JcampDxClass::get_parx_code(type,equiv); int d; if(type==parx_def) { J jdxdummy; d=A::dim(); if( get_compatmode()==bruker && jdxdummy.get_typeInfo()==STD_string("string") ) d++; if(d<=0) d=1; STD_string parx_type(jdxdummy.get_parx_equiv().type); if(parx_type=="float") parx_type="double"; return get_parx_def_string(parx_type,d); } if(type==parx_passval) { if(!A::dim()) return ""; STD_string src,dst,transformation; result=""; dst=equiv.name; src=get_label(); STD_string dstpostfix,srcelement,dstelement; STD_string dstprefix(dst); if(dstprefix.find("[]")!=STD_string::npos) { dstprefix=replaceStr(dstprefix,"[]",""); result+="PARX_change_dims(\""+dstprefix+dstpostfix+"\","; for(d=0;d const char* JDXarray::get_typeInfo() const { J jdxdummy; typeInfo_cache=STD_string(jdxdummy.get_typeInfo())+"Arr"; return typeInfo_cache.c_str(); } //////////////////////////////////////////////////////////// template class JDXarray; template class JDXarray; template class JDXarray; template class JDXarray; template class JDXarray; //////////////////////////////////////////////////////////// JDXtriple::JDXtriple (float xpos,float ypos, float zpos, const STD_string& name,bool userParameter, compatMode, parameterMode parameter_mode) : JDXfloatArr(farray(3),name,userParameter,bruker,parameter_mode) { (*this)[0]=xpos; (*this)[1]=ypos; (*this)[2]=zpos; } /////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class JDXstringArrTest : public UnitTest { public: JDXstringArrTest() : UnitTest("JDXstringArr") {} private: bool check() const { Log odinlog(this,"check"); sarray sarr(3); sarr(0)="item1"; sarr(1)="item2"; sarr(2)="item3"; JDXstringArr teststrarr1(sarr,"teststrarr1",true,notBroken); JDXstringArr teststrarr2(sarr,"teststrarr2",true,bruker); // testing JDXstringArr::print STD_string expected="##$teststrarr1=( 3 )\n \n"; STD_string printed=teststrarr1.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXstringArr::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="##$teststrarr2=( 3, "+itos(_BRUKER_MODE_STRING_CAP_START_)+" )\n \n"; printed=teststrarr2.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXstringArr::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } // testing JDXstringArr::parse JcampDxBlock arrblock; arrblock.append(teststrarr1); arrblock.append(teststrarr2); int parseresult_arr=arrblock.parseblock("##TITLE=arrblock\n##$teststrarr1=(2)\n \n##$teststrarr2=(2,123)\n \n##END="); if(parseresult_arr!=2) { ODINLOG(odinlog,errorLog) << "JcampDxBlock::parseblock() failed: parseresult_arr=" << parseresult_arr << "!=" << 2 << STD_endl; return false; } if(STD_string(arrblock.get_label())!="arrblock") { ODINLOG(odinlog,errorLog) << "JcampDxBlock::get_label() failed: " << arrblock.get_label() << "!=arrblock" << STD_endl; return false; } if(STD_string(teststrarr2[1])!="str2") { ODINLOG(odinlog,errorLog) << "element 1 of JDXstringArr: " << STD_string(teststrarr1[1]) << "!=" << "str2" << STD_endl; ODINLOG(odinlog,errorLog) << "teststrarr2=" << teststrarr2.printbody() << STD_endl; return false; } teststrarr2.set_compatmode(notBroken); if(STD_vector(teststrarr1)!=STD_vector(teststrarr2)) { // cast required for vxworks ODINLOG(odinlog,errorLog) << "after arrblock.parseblock(): " << teststrarr1 << "!=" << teststrarr2 << STD_endl; return false; } return true; } }; void alloc_JDXstringArrTest() {new JDXstringArrTest();} // create test instance /////////////////////////////////////////////////////////////////// class JDXintArrTest : public UnitTest { public: JDXintArrTest() : UnitTest("JDXintArr") {} private: bool check() const { Log odinlog(this,"check"); // testing JDXintArr JDXintArr testintarr(iarray(2,2),"testintarr"); testintarr(0,0)=1; testintarr(0,1)=2; testintarr(1,0)=3; testintarr(1,1)=4; STD_string expected="##$testintarr=( 2, 2 )\n1 2 3 4\n"; STD_string printed=testintarr.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXintArr::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } JcampDxBlock intarrblock; intarrblock.append(testintarr); intarrblock.parseblock("##TITLE=intarrblock\n##$testintarr=(2,2)\n3 4 5 6\n##END="); if(testintarr.sum()!=18) { ODINLOG(odinlog,errorLog) << "after intarrblock.parseblock(): " << testintarr.sum() << "!=" << 18 << STD_endl; return false; } testintarr=testintarr*2; if(testintarr.sum()!=36) { ODINLOG(odinlog,errorLog) << "JDXintArr *= " << testintarr.sum() << "!=" << 36 << STD_endl; return false; } return true; } }; void alloc_JDXintArrTest() {new JDXintArrTest();} // create test instance /////////////////////////////////////////////////////////////////// class JDXcomplexArrTest : public UnitTest { public: JDXcomplexArrTest() : UnitTest("JDXcomplexArr") {} private: bool check() const { Log odinlog(this,"check"); // testing compression of JDXcomplexArr JDXcomplexArr testcarr(carray(100,20),"testcarr"); testcarr.set_filemode(compressed); for(unsigned int i=0; i" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } return true; } }; void alloc_JDXcomplexArrTest() {new JDXcomplexArrTest();} // create test instance #endif odin-1.8.5/odinpara/jdxbase.h0000644000175000017500000003467711363773555013025 00000000000000/*************************************************************************** jdxbase.h - description ------------------- begin : Sun Jun 6 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXBASE_H #define JDXBASE_H #include #include #include #include // some defines for Bruker-type strings #define _BRUKER_MODE_STRING_CAP_START_ 1000 #define _BRUKER_MODE_STRING_MIN_SIZE_ 256 #define _BRUKER_MODE_STRING_CAP_FACTOR_ 3 /** * @addtogroup jcampdx * @{ */ /** * * This enum performs some fine tuning with the JcampDx classes according * its value: * - bruker: Strings are treated as arrays of characters (size after '=' and contents on next line). * Used to be compatible with Brukers JCAMP-DX implementation. * - notBroken: Strings are written directly into the file (after '='). */ enum compatMode {bruker,notBroken}; /** * This enum determines whether the parameter can be seen/edited in the graphical user interface * - edit: Parameter is visible and can be edited * - noedit: Parameter is visible but cannot be edited * - hidden: Parameter is invisible */ enum parameterMode {edit,noedit,hidden}; /** * This enum determines whether the parameter will be included/compressed/excluded when reading/writing a file * - include: Parameter is included in the file * - compressed: Parameter is included in the file in compressed ASCII-format (e.g. Base64 encoding) * if its representation exceeds a certain size * - exclude: Parameter is excluded from the file */ enum fileMode {include,compressed,exclude}; /////////////////////////////////////////////////////////////////////// class JcampDxBlock; // Forward Declaration class JDXfunction; // Forward Declaration class JDXtriple; // Forward Declaration class JDXaction; // Forward Declaration class JDXenum; // Forward Declaration class JDXfileName; // Forward Declaration class JDXformula; // Forward Declaration class JDXrecoIndices; // Forward Declaration /////////////////////////////////////////////////////////////////////// /** * * Helper class for debugging the JcampDx component */ class JcampDx { public: static const char* get_compName(); }; /////////////////////////////////////////////////////////////////////// /** * Enum for plot/display scales/axes in the GUI * - displayScale: Scale for 2D/3D display * - xPlotScale: x-axis (bottom) * - yPlotScaleLeft: First y-axis (left) * - yPlotScaleRight: Second y-axis (left) */ enum scaleType {displayScale=0,xPlotScale,yPlotScaleLeft,yPlotScaleRight,n_ScaleTypes}; /** * Data structure to store info about scales of JDXarrays in GUI */ struct ArrayScale { ArrayScale() : minval(0), maxval(0) {} ArrayScale(const STD_string& scalelabel, const STD_string& scaleunit, float scalemin=0.0, float scalemax=0.0); STD_string get_label_with_unit() const; /** * Axis label */ STD_string label; /** * Axis physical unit */ STD_string unit; /** * Lower and upper bound of scale */ float minval,maxval; }; /////////////////////////////////////////////////////////////////////// /** * Data structure to store info about 2D/3D plots of JDXarrays */ struct PixmapProps { PixmapProps() : minsize(128), maxsize(1024), autoscale(true), color(false), overlay_minval(0), overlay_maxval(0), overlay_firescale(false), overlay_rectsize(0.8f) {} void get_overlay_range(float& min, float& max) const; /** * The min and max width/height in the GUI */ unsigned int minsize, maxsize; /** * Do auto-windowing/scaling of values */ bool autoscale; /** * Display values color encoded */ bool color; /** * Extra map to be overlaid on plot in color code */ farray overlay_map; /** * Range of displayed values of overlay map. If both are zero, autoscaling is applied. */ float overlay_minval, overlay_maxval; /** * Use only yellow to red from color wheel */ bool overlay_firescale; /** * The relative size (between 0 and 1) of rectangles representing overlayed voxels */ float overlay_rectsize; }; /////////////////////////////////////////////////////////////////////// /** * Data structure to store info about GUI display of JDXarrays */ struct GuiProps { GuiProps() : fixedsize(true) {} /** * The scales in 1D or 2D display */ ArrayScale scale[n_ScaleTypes]; /** * Whether the size is fixed in 1D mode. If so, it is possible to detach the widget * to display it in larger size. */ bool fixedsize; /** * Properties of the map in 2D mode */ PixmapProps pixmap; }; /////////////////////////////////////////////////////////////////////// /** * * Enum for PARX code generation: * - parx_def: Parameter definitions * - parx_passval: Parameter assignment * - parx_passval_head: Function head for parameter assignment * - parx_parclass_def: Definition of parameter class * - parx_parclass_init: Initialization of parameter class * - parx_parclass_passval: Assignment of parameter class */ enum parxCodeType {parx_def, parx_passval, parx_passval_head, parx_parclass_def, parx_parclass_init, parx_parclass_passval}; /** * Data structure to store info about the equivalent PARX(Bruker) parameter * to which this parameter will be mapped */ struct ParxEquiv { ParxEquiv() : factor(1.0), offset(0.0) {} /** * Parx name */ STD_string name; /** * Parx type */ STD_string type; /** * Scaling factor in assignment */ double factor; /** * Offset in assignment */ double offset; }; /////////////////////////////////////////////////////////////////////// /** * * This is the (virtual) base class * that carries the JcampDx specific interface, i.e. all common * functions that are specific to JcampDx. Most of the elements * show a simple default behaviour that will be overwritten by * a reasonable behaviour in the derived classes. */ class JcampDxClass : public ListItem, public virtual Labeled { public: virtual ~JcampDxClass(); /** * * This function returns the parameter in JcampDx-ASCII-format */ virtual STD_string print() const; /** * Passes the parameter in ASCII format to the ostream 'os' */ virtual STD_ostream& print2stream(STD_ostream& os) const {return os << printvalstring();} /** * Stream operator */ friend STD_ostream& operator << (STD_ostream& s,const JcampDxClass& value) { return value.print2stream(s);} /** * Parses the JCAMP-DX parameter. Except for blocks, this is done by * stripping the label (e.g. "##$MyParameter=" ) from the string and passing the * result to the function 'parsevalstring' of the underlying data type. * For blocks, a re-implemented 'parse' function is called. * Returns 'true' if the parameter was parsed successfully. */ virtual bool parse(STD_string& parstring); /** * * Loads the parameter(s) from a JCAMP-DX file. In case of calling this function * of a single paramter, the file is searched for this parameter and the value * is assigned. In case of a parameter block, all parameter values are taken * from the file. * The return value is the number of parameters which are successfully parsed. * If an error occurs, -1 is returned. */ virtual int load(const STD_string &filename); /** * * Writes the parameter(s) to a JCAMP-DX file. In case of calling this function * of a single paramter, the file will consist of only this parameter. In case * of a parameter block, all parameter values are written to the file. * If an error occurs, -1 is returned. */ virtual int write(const STD_string &filename) const; /** * * Parses and assigns the value in the given string */ virtual bool parsevalstring (const STD_string&) = 0; /** * * Returns the value of the parameter as a string */ virtual STD_string printvalstring() const = 0; /** * * Sets the compatability mode. See the documentation to 'compatMode' */ virtual JcampDxClass& set_compatmode(compatMode compat_mode) {compatmode=compat_mode; return *this;} /** * * Returns the compatability mode. See the documentation to 'compatMode' */ virtual compatMode get_compatmode() const {return compatmode;} /** * Returns a string describing the type of the parameter */ virtual const char* get_typeInfo() const = 0; /** * Returns the minimum allowed value of the parameter. * Only used when editing the parameter in a GUI */ virtual double get_minval() const {return 0.0;} /** * Returns the maximum allowed value of the parameter * Only used when editing the parameter in a GUI */ virtual double get_maxval() const {return 0.0;} /** * Returns whether the paramerer has a valid interval of allowed values. * Only used when editing the parameter in a GUI */ bool has_minmax() const {return get_maxval()>get_minval();} /** * Returns a deep copy of the parameter */ virtual JcampDxClass* create_copy() const = 0; /** * * Determines whether the parameter is user defined, see [1,2] for details. */ JcampDxClass& set_userDefParameter(bool userDef) {userDefParameter=userDef; return *this;} /** * * Returns whether the parameter is user defined, see [1,2] for details. */ bool isUserDefParameter() const {return userDefParameter;} /** * * Returns the description of the parameter, used in the text of tooltips in a GUI */ const STD_string& get_description() const {return description;} /** * * Sets the description of the parameter, used in the text of tooltips in a GUI */ JcampDxClass& set_description(const STD_string& descr) {description=descr; return *this;} /** * Returns possible alternative values of the parameter, i.e. the item strings of an enum */ virtual svector get_alternatives() const {return svector();} /** * * Returns the physical unit of the parameter */ const STD_string& get_unit() const {return unit;} /** * * Sets the physical unit of the parameter */ JcampDxClass& set_unit(const STD_string& un) {unit=un; return *this;} /** * * Returns the parameterMode */ virtual parameterMode get_parmode() const {return parmode;} /** * * Sets the parameterMode */ virtual JcampDxClass& set_parmode(parameterMode parameter_mode) {parmode=parameter_mode; return *this;} /** * * Returns the fileMode */ virtual fileMode get_filemode() const {return filemode;} /** * * Sets the fileMode */ virtual JcampDxClass& set_filemode(fileMode file_mode) {filemode=file_mode; return *this;} /** * * Returns the properties of axis display in the GUI, only useful for JDXarrays */ virtual GuiProps get_gui_props() const {return GuiProps();} /** * * Sets the properties of axis display in the GUI, only useful for JDXarrays */ virtual JcampDxClass& set_gui_props(const GuiProps&) {return *this;} /** * * Returns C code that can be used together with the PARX(Bruker) compiler. */ virtual STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv=ParxEquiv()) const; /** * * Returns the name and scaling of an equivalent parameter in PARX. Code for automatic * mapping to the PARX parameter space can be generated using the function * get_parx_code(). */ virtual ParxEquiv get_parx_equiv() const {ParxEquiv pe; pe.type=get_typeInfo(); return pe;} // virtual functions to emulate a dynamic cast virtual JcampDxBlock* cast(JcampDxBlock*) {return 0;} virtual int* cast(int*) {return 0;} virtual long* cast(long*) {return 0;} virtual float* cast(float*) {return 0;} virtual double* cast(double*) {return 0;} virtual bool* cast(bool*) {return 0;} virtual STD_complex* cast(STD_complex*) {return 0;} virtual JDXenum* cast(JDXenum*) {return 0;} virtual STD_string* cast(STD_string*) {return 0;} virtual JDXfileName* cast(JDXfileName*) {return 0;} virtual JDXformula* cast(JDXformula*) {return 0;} virtual JDXaction* cast(JDXaction*) {return 0;} virtual iarray* cast(iarray*) {return 0;} virtual darray* cast(darray*) {return 0;} virtual farray* cast(farray*) {return 0;} virtual carray* cast(carray*) {return 0;} virtual sarray* cast(sarray*) {return 0;} virtual JDXtriple* cast(JDXtriple*) {return 0;} virtual JDXfunction* cast(JDXfunction*) {return 0;} // with these functions it is possible to assign a unique id to each paramerer int set_parameter_id(int newid) {id=newid; return 0;} int get_parameter_id() const {return id;} JcampDxClass& set_cmdline_option(const STD_string& opt) {cmdline_option=opt; return *this;} STD_string get_cmdline_option() const {return cmdline_option;} protected: JcampDxClass(); JcampDxClass(const JcampDxClass& jdc); JcampDxClass& operator = (const JcampDxClass& jdc); STD_string get_parx_def_string(const STD_string type, unsigned int dim) const; private: friend class JDXwidget; friend class JcampDxBlock; virtual STD_string get_jdx_prefix() const; virtual STD_string get_jdx_postfix() const {return "\n";} compatMode compatmode; bool userDefParameter; parameterMode parmode; fileMode filemode; STD_string description; STD_string unit; int id; STD_string cmdline_option; }; /////////////////////////////////////////////////////////////// // // Some interface classes which help editing parameters in a GUI class JDXeditWidget { public: virtual void updateWidget() = 0; virtual ~JDXeditWidget() {} // to avoid compiler warnings }; class JDXeditCaller { public: virtual void parameter_relations(JDXeditWidget* editwidget) = 0; virtual ~JDXeditCaller() {} // to avoid compiler warnings }; /** @} */ #endif odin-1.8.5/odinpara/geometry.cpp0000644000175000017500000006032211725203122013531 00000000000000#include "geometry.h" #include RotMatrix::RotMatrix(const STD_string& label) { int i,j; set_label(label); for( i = 0; i < 3; i++) for( j = 0; j < 3; j++) if ( i == j) matrix[i][j] = 1; else matrix[i][j] = 0; }; RotMatrix::RotMatrix(const RotMatrix& sct) { RotMatrix::operator =(sct); }; RotMatrix& RotMatrix::operator =(const RotMatrix& sct){ set_label(sct.get_label()); int i,j; for( i = 0; i < 3; i++) for( j = 0; j < 3; j++) matrix[i][j] = sct[i][j]; // check_and_correct(); return *this; }; bool RotMatrix::operator == (const RotMatrix& srm) const{ for(int i=0; i < 3; i++) for(int j=0; j < 3; j++) if(fabs(srm[i][j]-matrix[i][j])>ODIN_GEO_CHECK_LIMIT) return false; return true; }; bool RotMatrix::operator < (const RotMatrix& srm) const{ for(int i=0; i < 3; i++) for(int j=0; j < 3; j++) if(!(srm[i][j] < matrix[i][j])) return false; return true; }; dvector RotMatrix::operator * (const dvector& vec) const { dvector result(3); result=0; for(int i=0; i < 3; i++) for(int j=0; j < 3; j++) result[i]+=matrix[i][j]*vec[j]; return result; } RotMatrix RotMatrix::operator * (const RotMatrix& matrix) const { RotMatrix result; int i,j,k; double scalprod; for(j=0; j<3; j++) { for(i=0; i<3; i++) { scalprod=0.0; for(k=0; k<3; k++) { scalprod+= matrix [k][i]*(*this)[j][k]; } result[j][i]=scalprod; } } return result; } RotMatrix::operator farray () const { farray result(3,3); for(int i=0; i < 3; i++) { for(int j=0; j < 3; j++) { result(i,j)=matrix[i][j]; } } return result; } STD_string RotMatrix::print() const { // make C-style 9-array so that it can be reused in code generator STD_string result("{"); for(int i=0; i < 3; i++) { for(int j=0; j < 3; j++) { if(fabs(matrix[i][j])>10e-5) result+=ftos(matrix[i][j]); else result+="0"; if(i!=2 || j!=2) { result+=","; if(j==2) result+=" "; } } } result+="}"; return result; } RotMatrix& RotMatrix::set_inplane_rotation(float phi) { Log odinlog(this,"set_inplane_rotation"); ODINLOG(odinlog,normalDebug) << "phi=" << phi << STD_endl; float si=sin(phi); float co=cos(phi); (*this)[0][0]=co; (*this)[0][1]=-si; (*this)[0][2]=0.0; (*this)[1][0]=si; (*this)[1][1]=co; (*this)[1][2]=0.0; (*this)[2][0]=0.0; (*this)[2][1]=0.0; (*this)[2][2]=1.0; return *this; } //////////////////////////////////////////////////////////////////////////// Geometry& Geometry::reset() { FOVread=ODIN_DEFAULT_FOV; offsetRead=0.0; FOVphase=ODIN_DEFAULT_FOV; offsetPhase=0.0; FOVslice=ODIN_DEFAULT_FOV; offsetSlice=0.0; nSlices=1; sliceThickness=5.0; sliceDistance=10.0; heightAngle=0.0; azimutAngle=0.0; inplaneAngle=0.0; reverseSlice=false; return *this; } Geometry::Geometry(const STD_string& label) : JcampDxBlock(label) { Log odinlog(this,"Geometry(const STD_string&)"); Mode.add_item("SlicePack",slicepack); Mode.add_item("Voxel/3D",voxel_3d); Mode.set_actual(slicepack); Mode.set_description("Acquisition mode, i.e. whether sequence is multi-slice- or voxel/3D-selective"); FOVread.set_unit(ODIN_SPAT_UNIT).set_description("FOV in read direction").set_cmdline_option("fr"); offsetRead.set_unit(ODIN_SPAT_UNIT).set_description("Spatial offset in read direction relative to isocenter"); FOVphase.set_unit(ODIN_SPAT_UNIT).set_description("FOV in phase direction").set_cmdline_option("fp"); offsetPhase.set_unit(ODIN_SPAT_UNIT).set_description("Spatial offset in phase direction relative to isocenter"); FOVslice.set_unit(ODIN_SPAT_UNIT).set_description("FOV in slice direction").set_cmdline_option("fs"); offsetSlice.set_unit(ODIN_SPAT_UNIT).set_description("Spatial offset in slice direction relative to isocenter"); nSlices.set_description("Number of sices"); sliceThickness.set_unit(ODIN_SPAT_UNIT).set_cmdline_option("st").set_description("Slice thickness"); sliceDistance.set_unit(ODIN_SPAT_UNIT).set_cmdline_option("sd").set_description("Inter-slice distance (from center to center)"); heightAngle.set_description("1st orientation angle"); azimutAngle.set_description("2nd orientation angle"); inplaneAngle.set_description("3rd orientation angle"); reverseSlice.set_description("Reverse direction of slice vector"); Reset.set_description("Reset to default values"); Transpose.set_description("Transpose in-plane"); reset(); // set default values FOVread.set_minmaxval(0.0,2.0*ODIN_DEFAULT_FOV); offsetRead.set_minmaxval(0.5*-ODIN_DEFAULT_FOV,0.5*ODIN_DEFAULT_FOV); FOVphase.set_minmaxval(0.0,2.0*ODIN_DEFAULT_FOV); offsetPhase.set_minmaxval(0.5*-ODIN_DEFAULT_FOV,0.5*ODIN_DEFAULT_FOV); FOVslice.set_minmaxval(0.0,2.0*ODIN_DEFAULT_FOV); offsetSlice.set_minmaxval(0.5*-ODIN_DEFAULT_FOV,0.5*ODIN_DEFAULT_FOV); nSlices.set_minmaxval(1,ODIN_MAX_NUMOF_SLICES); sliceThickness.set_minmaxval(0.0,50.0); sliceDistance.set_minmaxval(0.0,0.5*ODIN_DEFAULT_FOV); heightAngle.set_minmaxval(-180.0,180.0); azimutAngle.set_minmaxval(-180.0,180.0); inplaneAngle.set_minmaxval(-180.0,180.0); Reset.set_filemode(exclude); Transpose.set_filemode(exclude); append_all_members(); update(); } Geometry::Geometry(const Geometry& ia) { Log odinlog(this,"Geometry(const Geometry&)"); Geometry::operator = (ia); } Geometry& Geometry::operator = (const Geometry& ia) { Log odinlog(this,"Geometry::operator ="); JcampDxBlock::operator = (ia); append_all_members(); // copy only visible members of JcampDxBlock copy_ldr_vals(ia); update(); return *this; } Geometry& Geometry::set_Mode(geometryMode mode) { Log odinlog(this,"set_Mode"); Mode.set_actual(mode); ODINLOG(odinlog,normalDebug) << "Mode/mode=" << Mode.JDXenum::operator STD_string() << "/" << mode << STD_endl; update(); return *this; } Geometry& Geometry::update() { Log odinlog(this,"update"); if(Reset) reset(); if(Transpose) transpose_inplane(); FOVslice.set_parmode(edit); nSlices.set_parmode(edit); sliceThickness.set_parmode(edit); sliceDistance.set_parmode(edit); if(int(Mode)==slicepack) { FOVslice=sliceThickness+(double)(nSlices-1)*sliceDistance; FOVslice.set_parmode(hidden); } if(int(Mode)==voxel_3d) { nSlices=1; nSlices.set_parmode(hidden); sliceThickness=double(FOVslice); sliceThickness.set_parmode(hidden); sliceDistance=0.0; sliceDistance.set_parmode(hidden); } cache_up2date=false; return *this; } /* int Geometry::load(const STD_string &filename) { int stat=JcampDxBlock::load(filename); // read once to set correct mode if(stat<=0) return -1; update(); // set new mode return JcampDxBlock::load(filename); } */ Geometry& Geometry::set_FOV(direction dir,double fov) { if(dir==readDirection) FOVread=fov; if(dir==phaseDirection) FOVphase=fov; if(dir==sliceDirection) FOVslice=fov; update(); return *this; } double Geometry::get_FOV(direction dir) const { if(dir==readDirection) return FOVread; if(dir==phaseDirection) return FOVphase; if(dir==sliceDirection) return FOVslice; return 0.0; } Geometry& Geometry::set_offset(direction dir,double offset) { if(dir==readDirection) offsetRead=offset; if(dir==phaseDirection) offsetPhase=offset; if(dir==sliceDirection) offsetSlice=offset; update(); return *this; } double Geometry::get_offset(direction dir) const { if(dir==readDirection) return offsetRead; if(dir==phaseDirection) return offsetPhase; if(dir==sliceDirection) return offsetSlice; return 0.0; } Geometry& Geometry::set_nSlices(unsigned int nslices) {nSlices=nslices; update(); return *this;} Geometry& Geometry::set_sliceThickness(double thick) {sliceThickness=thick; update(); return *this;} Geometry& Geometry::set_sliceDistance(double dist) {sliceDistance=dist; update(); return *this;} dvector Geometry::get_readVector_inplane() const { Log odinlog(this,"get_readVector_inplane"); double phiplus=deg2rad(azimutAngle)+0.5*PII; ODINLOG(odinlog,normalDebug) << "azimutAngle=" << double(azimutAngle) << STD_endl; ODINLOG(odinlog,normalDebug) << "phiplus=" << phiplus << STD_endl; dvector result(3); result[xAxis]=sin(phiplus); result[yAxis]=0.0; result[zAxis]=cos(phiplus); ODINLOG(odinlog,normalDebug) << "=" << result.printbody() << STD_endl; return result; } dvector Geometry::get_phaseVector_inplane() const { Log odinlog(this,"get_phaseVector_inplane"); double tetaplus=deg2rad(heightAngle)+0.5*PII; double phi=deg2rad(azimutAngle); dvector result(3); result[xAxis]=cos(tetaplus)*sin(phi); result[yAxis]=sin(tetaplus); result[zAxis]=cos(tetaplus)*cos(phi); ODINLOG(odinlog,normalDebug) << "=" << result.printbody() << STD_endl; return result; } dvector Geometry::get_readVector() const { double cos_inplane=cos(deg2rad(inplaneAngle)); double sin_inplane=sin(deg2rad(inplaneAngle)); return cos_inplane*get_readVector_inplane()-sin_inplane*get_phaseVector_inplane(); } dvector Geometry::get_phaseVector() const { return sin(deg2rad(inplaneAngle))*get_readVector_inplane()+cos(deg2rad(inplaneAngle))*get_phaseVector_inplane(); } dvector Geometry::get_sliceVector() const { double teta=deg2rad(heightAngle); double phi=deg2rad(azimutAngle); dvector result(3); result[xAxis]=cos(teta)*sin(phi); result[yAxis]=sin(teta); result[zAxis]=cos(teta)*cos(phi); return pow(-1.0,reverseSlice)*result; } dvector Geometry::get_sliceOffsetVector() const { dvector result(nSlices); double range=(double)(nSlices-1)*sliceDistance; result.fill_linear(offsetSlice-0.5*range,offsetSlice+0.5*range); return result; } darray Geometry::get_cornerPoints(const Geometry& background, unsigned int backgrslice) const { Log odinlog(this,"get_cornerPoints"); unsigned int n_boundaries_slice=n_boundaries; if(Mode==slicepack) n_boundaries_slice=1; darray result(nSlices,n_boundaries,n_boundaries,n_boundaries_slice,n_axes); dvector sliceoffset=get_sliceOffsetVector(); ODINLOG(odinlog,normalDebug) << "sliceoffset=" << sliceoffset.printbody() << STD_endl; dvector slicevector(3); dvector readvector(3); dvector phasevector(3); dvector totalvector(3); double signread,signphase,signslice; double backgrslicedelta=background.get_sliceOffsetVector()[backgrslice]-background.get_offset(sliceDirection); ODINLOG(odinlog,normalDebug) << "backgrslicedelta[" << backgrslice << "]=" << backgrslicedelta << STD_endl; ODINLOG(odinlog,normalDebug) << background.get_label() << "=" << background.get_gradrotmatrix().print() << STD_endl; for(unsigned int j=0;j=xabs) && (yabs>=zabs)) result=coronal; if((xabs>=yabs) && (xabs>=zabs)) result=sagittal; ODINLOG(odinlog,normalDebug) << "result("<< svec.printbody() << ")=" << result << STD_endl; return result; } void Geometry::get_orientation(double& heightAng, double& azimutAng, double& inplaneAng, bool& revSlice) const { heightAng=heightAngle; azimutAng=azimutAngle; inplaneAng=inplaneAngle; revSlice=reverseSlice; } Geometry& Geometry::set_orientation(double heightAng, double azimutAng, double inplaneAng, bool revSlice) { heightAngle=heightAng; azimutAngle=azimutAng; inplaneAngle=inplaneAng; reverseSlice=revSlice; update(); return *this; } Geometry& Geometry::set_orientation_and_offset(const dvector& readvec, const dvector& phasevec, const dvector& slicevec, const dvector& centervec) { Log odinlog(this,"set_orientation_and_offset"); dvector rvec(3); dvector pvec(3); dvector svec(3); // calculate length 1 vectors double inv_length; inv_length=secureInv(norm3(readvec[0], readvec[1], readvec[2])); rvec=inv_length*readvec; inv_length=secureInv(norm3(phasevec[0],phasevec[1],phasevec[2])); pvec=inv_length*phasevec; inv_length=secureInv(norm3(slicevec[0],slicevec[1],slicevec[2])); svec=inv_length*slicevec; // check orthogonality double deviation=0.0; deviation=STD_max(deviation, fabs((rvec*pvec).sum())); deviation=STD_max(deviation, fabs((pvec*svec).sum())); deviation=STD_max(deviation, fabs((svec*rvec).sum())); if(deviation>ODIN_GEO_CHECK_LIMIT) { ODINLOG(odinlog,errorLog) << "Non-orthogonal read/phase/slice-system provided, deviation=" << deviation << STD_endl; return *this; } // calculate handness dvector rp_crossproduct(3); rp_crossproduct[0] = rvec[1]*pvec[2] - rvec[2]*pvec[1]; rp_crossproduct[1] = rvec[2]*pvec[0] - rvec[0]*pvec[2]; rp_crossproduct[2] = rvec[0]*pvec[1] - rvec[1]*pvec[0]; // check handness of coordinate system double handness_product=(svec*rp_crossproduct).sum(); ODINLOG(odinlog,normalDebug) << "handness_product=" << handness_product << STD_endl; reverseSlice=(handness_product<0.0); // calculate polar orientation angles, use rp_crossproduct which has positive handness azimutAngle=180.0/PII*atan2(rp_crossproduct[0],rp_crossproduct[2]); heightAngle=180.0/PII*asin(rp_crossproduct[1]); ODINLOG(odinlog,normalDebug) << "azimutAngle/heightAngle=" << azimutAngle << "/" << heightAngle << STD_endl; // calculate inplane rotation dvector rvec_inplane(get_readVector_inplane()); dvector pvec_inplane(get_phaseVector_inplane()); double rr_scalarproduct=(rvec*rvec_inplane).sum(); double rp_scalarproduct=(rvec*pvec_inplane).sum(); if(rr_scalarproduct>1.0) rr_scalarproduct=1.0; if(rr_scalarproduct<-1.0) rr_scalarproduct=-1.0; if(rp_scalarproduct>1.0) rp_scalarproduct=1.0; if(rp_scalarproduct<-1.0) rp_scalarproduct=-1.0; ODINLOG(odinlog,normalDebug) << "rr/rp_scalarproduct=" << rr_scalarproduct << "/" << rp_scalarproduct << STD_endl; inplaneAngle=180.0/PII*atan2(-rp_scalarproduct,rr_scalarproduct); // clock-wise angle ODINLOG(odinlog,normalDebug) << "inplaneAngle=" << inplaneAngle << STD_endl; // calculate spatial offsets offsetRead =(centervec*rvec).sum(); //scalar product offsetPhase=(centervec*pvec).sum(); //scalar product offsetSlice=(centervec*svec).sum(); //scalar product ODINLOG(odinlog,normalDebug) << "offset=" << offsetRead << "/" << offsetPhase << "/" << offsetSlice << STD_endl; update(); return *this; } dvector Geometry::get_center() const { return get_offset(readDirection) *get_readVector() + get_offset(phaseDirection)*get_phaseVector() + get_offset(sliceDirection)*get_sliceVector(); } RotMatrix Geometry::get_gradrotmatrix(bool transpose) const { Log odinlog(this,"get_gradrotmatrix"); RotMatrix result; dvector perpvector(3); // double s1,s2,s3,s4,s5,s6; unsigned int i; perpvector=get_readVector(); ODINLOG(odinlog,normalDebug) << "perpRead=" << perpvector.printbody() << STD_endl; for(i=0;i<3;i++) { if(transpose) result[0][i]=perpvector[i]; else result[i][0]=perpvector[i]; } /* s1=perpvector[0]; s2=perpvector[2]; s3=perpvector[1]; s4=perpvector[2]; s5=perpvector[1]; s6=perpvector[0]; */ perpvector=get_phaseVector(); ODINLOG(odinlog,normalDebug) << "perpPhase=" << perpvector.printbody() << STD_endl; for(i=0;i<3;i++) { if(transpose) result[1][i]=perpvector[i]; else result[i][1]=perpvector[i]; } /* s1*=perpvector[1]; s2*=perpvector[0]; s3*=perpvector[2]; s4*=perpvector[1]; s5*=perpvector[0]; s6*=perpvector[2]; */ perpvector=get_sliceVector(); ODINLOG(odinlog,normalDebug) << "perpSlice=" << perpvector.printbody() << STD_endl; for(i=0;i<3;i++) { if(transpose) result[2][i]=perpvector[i]; else result[i][2]=perpvector[i]; } /* s1*=perpvector[2]; s2*=perpvector[1]; s3*=perpvector[0]; s4*=perpvector[0]; s5*=perpvector[2]; s6*=perpvector[1]; ODINLOG(odinlog,normalDebug) << "determinante=" << s1+s2+s3-s4-s5-s6 << STD_endl; ODINLOG(odinlog,normalDebug) << "0=" << result(0,0) << " " << result(0,1) << " " << result(0,2) << STD_endl; ODINLOG(odinlog,normalDebug) << "1=" << result(1,0) << " " << result(1,1) << " " << result(1,2) << STD_endl; ODINLOG(odinlog,normalDebug) << "2=" << result(2,0) << " " << result(2,1) << " " << result(2,2) << STD_endl; */ return result; } dvector Geometry::transform(const dvector& rpsvec, bool inverse) const { Log odinlog(this,"transform"); int ichan; dvector result(3); if(rpsvec.size()!=3) { ODINLOG(odinlog,errorLog) << "Size of input vector != 3" << STD_endl; return result; } if(!cache_up2date || (inverse!=inv_trans_cache)) { for(ichan=0; ichan odinlog(this,"append_all_members"); JcampDxBlock::clear(); append_member(Mode,"Mode"); append_member(Reset,"Reset"); append_member(FOVread,"FOVread"); append_member(offsetRead,"offsetRead"); append_member(FOVphase,"FOVphase"); append_member(offsetPhase,"offsetPhase"); append_member(FOVslice,"FOVslice"); append_member(offsetSlice,"offsetSlice"); append_member(nSlices,"nSlices"); append_member(sliceThickness,"sliceThickness"); append_member(sliceDistance,"sliceDistance"); append_member(heightAngle,"heightAngle"); append_member(azimutAngle,"azimutAngle"); append_member(inplaneAngle,"inplaneAngle"); append_member(reverseSlice,"reverseSlice"); append_member(Transpose,"Transpose"); } //////////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class GeometryTest : public UnitTest { public: GeometryTest() : UnitTest("Geometry") {} private: bool check() const { Log odinlog(this,"check"); int i; Geometry ia; // testing self-consistency of orientation with some arbitrary angles and offsets ia.set_orientation(-66.7, 78.2, -124.7, true); ia.set_offset(readDirection,22.7); ia.set_offset(phaseDirection,-5.9); ia.set_offset(sliceDirection,99.9); RotMatrix matrix_ang(ia.get_gradrotmatrix()); dvector offset(3); for(i=0; i<3; i++) offset[i]=ia.get_offset(direction(i)); ////////////////////////////////////////////////////// // Self-consistency check of set_orientation_and_offset Geometry ia2; ia2.set_orientation_and_offset(ia.get_readVector(),ia.get_phaseVector(),ia.get_sliceVector(),ia.get_center()); RotMatrix matrix_vec(ia2.get_gradrotmatrix()); if(!(matrix_ang==matrix_vec)) { ODINLOG(odinlog,errorLog) << " matrix_ang=" << matrix_ang.print() << STD_endl << " matrix_vec=" << matrix_vec.print() << STD_endl; return false; } dvector offset2(3); for(i=0; i<3; i++) offset2[i]=ia2.get_offset(direction(i)); if((offset-offset2).sum()>ODIN_GEO_CHECK_LIMIT) { ODINLOG(odinlog,errorLog) << " offset =" << offset << STD_endl << " offset2=" << offset2 << STD_endl; return false; } ////////////////////////////////////////////////////// // Check othogonality of rotation matrix RotMatrix matprod=ia.get_gradrotmatrix()*ia.get_gradrotmatrix(true); RotMatrix unitmat; if(!(matprod==unitmat)) { ODINLOG(odinlog,errorLog) << " matprod=" << matprod.print() << STD_endl << " unitmat=" << unitmat.print() << STD_endl; return false; } ////////////////////////////////////////////////////// // Check whether 'transform' preserves length and perpendicularity double norm1_expected,norm2_expected; dvector origin(3); origin=0.0; dvector testvec1(3); testvec1[0]=norm1_expected=5.0; testvec1[1]=0.0; testvec1[2]=0.0; dvector testvec2(3); testvec2[0]=0.0; testvec2[1]=norm2_expected=6.0; testvec2[2]=0.0; dvector origin_tr=ia.transform(origin); dvector testvec1_tr=ia.transform(testvec1)-origin_tr; dvector testvec2_tr=ia.transform(testvec2)-origin_tr; double norm1=norm3(testvec1_tr[0],testvec1_tr[1],testvec1_tr[2]); // check length after 'transform' if(fabs(norm1-norm1_expected)>ODIN_GEO_CHECK_LIMIT) { ODINLOG(odinlog,errorLog) << " testvec1/testvec1_tr =" << testvec1.printbody() << "/" << testvec1_tr.printbody() << STD_endl << " norm_expected1/norm1=" << norm1_expected << "/" << norm1 << STD_endl; return false; } // check scalar product after 'transform' double scalprod=(testvec1_tr*testvec2_tr).sum(); if(fabs(scalprod)>ODIN_GEO_CHECK_LIMIT) { ODINLOG(odinlog,errorLog) << " scalprod =" << scalprod << STD_endl; return false; } ////////////////////////////////////////////////////// // Testing == operator Geometry geo1; Geometry geo2; if(!(geo1==geo2)) { ODINLOG(odinlog,errorLog) << "Geometry::operator == (equal) failed: geo1=" << geo1 << "geo2=" << geo2 << STD_endl; return false; } geo1.set_nSlices(3); if(geo1==geo2) { ODINLOG(odinlog,errorLog) << "Geometry::operator == (unequal) failed: geo1=" << geo1 << "geo2=" << geo2 << STD_endl; return false; } ////////////////////////////////////////////////////// // Testing copy constructor Geometry geo3(geo1); if(!(geo1==geo3)) { ODINLOG(odinlog,errorLog) << "Geometry(const Geometry&) failed: geo1=" << geo1 << "geo3=" << geo3 << STD_endl; return false; } return true; } }; void alloc_GeometryTest() {new GeometryTest();} // create test instance #endif odin-1.8.5/odinpara/sample.h0000644000175000017500000001537511363773555012660 00000000000000/*************************************************************************** sample.h - description ------------------- begin : Mon Jul 11 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SAMPLE_H #define SAMPLE_H #include #include #include #include /** * @addtogroup odinpara * @{ */ /** * Dimension inidices of the 5-dim sample grid * - frameDim: time dimension * - freqDim: frequency direction * - zDim: axial direction of the scanner coordinate system * - yDim: 2nd transversal direction of the scanner coordinate system * - xDim: 1st transversal direction of the scanner coordinate system */ enum sampleDim { frameDim=0, freqDim, zDim, yDim, xDim, n_sampleDim }; //////////////////////////////////////////////////////////////////////////////////////////////////// /** * \brief Virtual Sample for Simulation * * Class to store properties of a virtual sample which is used as input to * simulation. The arrays are 4-dimensional: one frequency dimension * and 3 spatial dimensions. Coordinates are in the laboratory frame of * reference. */ class Sample : public JcampDxBlock { public: /** * Constructs a sample consisting of single voxel with the given label and the parameters: * - uniformFOV: A uniform FOV is used in each spatial dimension * - uniformT1T2: Uniform relaxation constants T1 and T2 are used, set_T1/2map has no effect */ Sample(const STD_string& label="unnamedSample", bool uniformFOV=true, bool uniformT1T2=false); /** * Constructs a copy of 'ss' */ Sample(const Sample& ss); /** * Assignment operator that makes this Sample become a copy of 'ss' */ Sample& operator = (const Sample& ss); /** * Sets the uniform FOV of the sample */ Sample& set_FOV(float fov); /** * Sets the FOV of the sample in the given direction */ Sample& set_FOV(axis direction, float fov); /** * Returns the FOV of the sample in the given direction */ float get_FOV(axis direction) const; /** * Sets the spatial offset in the given direction */ Sample& set_spatial_offset(axis direction, float offs) {offset[direction]=offs; return *this;} /** * Returns the spatial offset in the given direction */ float get_spatial_offset(axis direction) const {return offset[direction];} /** * Sets the frequency range */ Sample& set_freqrange(float range) {freqrange=range; return *this;} /** * Returns the frequency range */ float get_freqrange() const {return freqrange;} /** * Sets the frequency offset */ Sample& set_freqoffset(float offs) {freqoffset=offs; return *this;} /** * Returns the frequency offset */ float get_freqoffset() const {return freqoffset;} /** * Sets a vector of time intervals to cycle through frames periodically. * For maps with a time dimension, the index of the current interval * will also be used to index the time dimension of the map. */ Sample& set_frame_durations(const dvector& intervals) {frameDurations=intervals; return *this;} /** * Returns the vector of time intervals of the frames. */ const dvector& get_frame_durations() const {return frameDurations;} /** * Resize the sample in the four dimensions according to the given sizes: * - framesize: Number of frames (time intervals) * - freqsize: Number of frequency intervals * - zsize: Spatial extent in the axial direction of the scanner coordinate system * - ysize: Spatial extent in the 2nd transversal direction of the scanner coordinate system * - xsize: Spatial extent in the 1st transversal direction of the scanner coordinate system */ Sample& resize(unsigned int framesize, unsigned int freqsize, unsigned int zsize, unsigned int ysize, unsigned int xsize); /** * Returns the extent vector */ const ndim& get_extent() const {return spinDensity.get_extent();} /** * Sets a uniform longitudinal relaxation time */ Sample& set_T1(float relaxation_time) {T1=relaxation_time; haveT1map=false; return *this;} /** * Sets a uniform transverse relaxation time */ Sample& set_T2(float relaxation_time) {T2=relaxation_time; haveT2map=false; return *this;} /** * Sets an array for the longitudinal relaxation time */ Sample& set_T1map(const farray& t1map); /** * Returns the array for the longitudinal relaxation time */ const farray& get_T1map() const; /** * Sets an array for the transverse relaxation time */ Sample& set_T2map(const farray& t2map); /** * Returns the array for the transverse relaxation time */ const farray& get_T2map() const; /** * Sets an array for the relative frequency offset (in ppm) */ Sample& set_ppmMap(const farray& ppmmap); /** * Returns an array for the relative frequency offset (in ppm) */ const farray& get_ppmMap() const; /** * Sets an array for the spin density of each voxel */ Sample& set_spinDensity(const farray& sd); /** * Returns an array for the spin density of each voxel */ const farray& get_spinDensity() const; /** * Sets the diffusion coefficient map */ Sample& set_DcoeffMap(const farray& dmap); /** * Returns the diffusion coefficient map */ const farray& get_DcoeffMap() const; /** * Updates all parameter relations */ Sample& update(); // overwriting virtual functions from JcampDxClass int load(const STD_string& filename); private: friend class SeqSimMagsi; int append_all_members(); bool check_and_correct(const char* mapname, const farray& srcmap, farray& dstmap); JDXfloat FOVall; JDXtriple FOV; bool uniFOV; JDXtriple offset; JDXfloat freqrange; JDXfloat freqoffset; JDXdoubleArr frameDurations; mutable JDXfloatArr spinDensity; bool uniT1T2; JDXfloat T1; JDXfloat T2; mutable JDXfloatArr T1map; mutable JDXfloatArr T2map; mutable bool haveT1map; mutable bool haveT2map; mutable JDXfloatArr ppmMap; mutable bool have_ppmMap; mutable JDXfloatArr DcoeffMap; mutable bool have_DcoeffMap; }; /** @} */ #endif odin-1.8.5/odinpara/odinpara.cpp0000644000175000017500000000020111322062341013460 00000000000000#include "odinpara.h" #include const char* Para::get_compName() {return "Para";} LOGGROUNDWORK(Para) odin-1.8.5/odinpara/jdxtypes.h0000644000175000017500000004053211322062341013215 00000000000000/*************************************************************************** jdxtypes.h - description ------------------- begin : Sun Jun 6 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXTYPES_H #define JDXTYPES_H #include /** * @addtogroup jcampdx * @{ */ ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class for representing strings */ class JDXstring : public STD_string, public virtual JcampDxClass { public: /** * Default constructor */ JDXstring () : STD_string() {} /** * Constructor with the following arguments: * - ss: Initial value for the string * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter * - parx_equivalent: Equivalent parameter in PARX to which this parameter will be assigned */ JDXstring (const STD_string& ss,const STD_string& name="",bool userParameter=true, compatMode mode=notBroken,parameterMode parameter_mode=edit, const STD_string& parx_equivalent=""); /** * Constructs a string of length i with c as their initial content */ JDXstring (int i,const char c=' ') : STD_string(i,c) {} /** * Copy constructor from a C-string */ JDXstring (const char *charptr) : STD_string(charptr) {} /** * Copy constructor */ JDXstring (const JDXstring& str) {JDXstring::operator = (str);} /** * Assigns the string ss to the parameter */ JDXstring& operator = (const STD_string& ss) {STD_string::operator = (ss); return *this;} /** * Assigns the C-string charptr to the parameter */ JDXstring& operator = (const char *charptr) {STD_string::operator = (charptr); return *this;} /** * Copy assignment */ JDXstring& operator = (const JDXstring& ss); /** * Final overrider for stream output */ friend STD_ostream& operator << (STD_ostream& s,const JDXstring& t) {return s << STD_string(t);} // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv) const; ParxEquiv get_parx_equiv() const {parx_equiv.type="char"; return parx_equiv;} const char* get_typeInfo() const {return "string";} JcampDxClass* create_copy() const {return new JDXstring(*this);} STD_string* cast(STD_string*) {return this;} private: mutable ParxEquiv parx_equiv; }; ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class for representing Boolean values */ class JDXbool : public virtual JcampDxClass { public: /** * Default constructor */ JDXbool () : val(false) {} /** * Constructor with the following arguments: * - flag: Initial value for the Boolean value * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter * - parx_equivalent: Equivalent parameter in PARX to which this parameter will be assigned */ JDXbool(bool flag, const STD_string& name="", bool userParameter=true, compatMode mode=notBroken, parameterMode parameter_mode=edit, const STD_string& parx_equivalent=""); /** * Copy constructor */ JDXbool(const JDXbool& jb) {JDXbool::operator = (jb);} /** * Assigns the value of flag to the parameter */ JDXbool& operator = (bool flag) {val=flag; return *this;} /** * Assigns the value of s to the parameter, s may contain "yes" or "true" * (upper- or lowercase) to indicate a value of true, otherwise false */ JDXbool& operator = (const STD_string& s) {parsevalstring(s); return *this;} /** * Copy assignment */ JDXbool& operator = (const JDXbool& jb); /** * type conversion operator of the current value of the parameter */ operator bool () const {return val;} // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv) const; ParxEquiv get_parx_equiv() const {parx_equiv.type="YesNo"; return parx_equiv;} const char* get_typeInfo() const {return "bool";} JcampDxClass* create_copy() const {return new JDXbool(*this);} bool* cast(bool*) {return &val;} private: bool val; mutable ParxEquiv parx_equiv; }; ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class to represent enumerations */ class JDXenum : public virtual JcampDxClass { public: /** * Default constructor */ JDXenum() {actual=entries.end();} /** * Constructor with the following arguments: * - first_entry: Initial value for the first entry of the enumeration * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter * - parx_equivalent: Equivalent parameter in PARX to which this parameter will be assigned */ JDXenum(const STD_string& first_entry, const STD_string& name="", bool userParameter=true, compatMode mode=notBroken, parameterMode parameter_mode=edit, const STD_string& parx_equivalent=""); /** * Copy constructor */ JDXenum(const JDXenum& je) {JDXenum::operator = (je);} /** * Sets the current value of the enumeration to the given item */ JDXenum& operator = (const char* item) {set_actual(STD_string(item)); return *this;} /** * Sets the current value of the enumeration to the given item */ JDXenum& operator = (const STD_string& item) {set_actual(item); return *this;} /** * Sets the current value of the enumeration to the given item */ JDXenum& operator = (int item) {set_actual(item); return *this;} /** * Assignment operator */ JDXenum& operator = (const JDXenum& je); /** * Appends an item to the the list of items in the enumeration. * If index is non-negative, the item will be inserted at the * position indicated by index. */ JDXenum& add_item(const STD_string& item, int index=-1); /** * Sets the current value of the enumeration to the given item */ JDXenum& set_actual(const STD_string& item); /** * Sets the current value of the enumeration to the given item */ JDXenum& set_actual(int index); /** * Clears the list of items in the enumeration */ JDXenum& clear(); /** * type conversion operator of the current value of the enumeration */ operator int () const; /** * type conversion operator of the current value of the enumeration */ operator STD_string () const; /** * Compares the current value with s for equality */ bool operator == (const STD_string& s) const {return (operator STD_string ())==s;} /** * Compares the current value with s for equality */ bool operator == (const char* s) const {return (operator STD_string ())==STD_string(s);} /** * Compares the current index with i for equality */ bool operator == (int i) const {return (operator int ())==i;} /** * Compares the current value with s for inequality */ bool operator != (const STD_string& s) const {return (operator STD_string ())!=s;} /** * Compares the current value with s for inequality */ bool operator != (const char* s) const {return (operator STD_string ())!=STD_string(s);} /** * Compares the current index with i for inequality */ bool operator != (int i) const {return (operator int ())!=i;} /** * Returns the number of items in the enumeration */ unsigned int n_items() const {return entries.size();} /** * Returns the item at the position 'index' in the label-index map */ const STD_string& get_item(unsigned int index) const; /** * Returns the current position in the label-index map */ unsigned int get_item_index() const; /** * Sets the current position 'index' in the label-index map */ JDXenum& set_item_index(unsigned int index); // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; svector get_alternatives() const; STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv) const; ParxEquiv get_parx_equiv() const; const char* get_typeInfo() const {return "enum";} JcampDxClass* create_copy() const {return new JDXenum(*this);} JDXenum* cast(JDXenum*) {return this;} private: STD_map entries; STD_map::const_iterator actual; mutable ParxEquiv parx_equiv; STD_string parxtype_cache; }; ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class to trigger actions from the GUI */ class JDXaction : public virtual JcampDxClass { public: /** * Default constructor */ JDXaction() : state(false) {set_filemode(exclude);} /** * Constructor with the following arguments: * - init_state: Initial value for the action * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter */ JDXaction(bool init_state, const STD_string& name="", bool userParameter=true, compatMode mode=notBroken, parameterMode parameter_mode=edit); /** * Copy constructor */ JDXaction(const JDXaction& ja) {JDXaction::operator = (ja);} /** * Copy assignment */ JDXaction& operator = (const JDXaction& ja); /** * Returns whether an action should be triggered and resets the action flag */ operator bool () const; /** * After calling this function, the next type conversion to bool will return true */ JDXaction& trigger_action() {state=true; return *this;} // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; const char* get_typeInfo() const {return "action";} JcampDxClass* create_copy() const {return new JDXaction(*this);} JDXaction* cast(JDXaction*) {return this;} private: mutable bool state; }; ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class for representing file names. Besides using JDXfileName * as a convenient way within the UI to display/retrieve/browse file names, * it can be used to analyze file paths, for example in the following way: * \verbatim STD_string myfile="/somedir/anotherdir/file.txt"; STD_string myfile_base=JDXfileName(myfile).get_basename(); STD_cout << "myfile_base=" << myfile_base << STD_endl; STD_string myfile_base_nosuffix=JDXfileName(myfile).get_basename_nosuffix(); STD_cout << "myfile_base_nosuffix=" << myfile_base_nosuffix << STD_endl; STD_string myfile_dir= JDXfileName(myfile).get_dirname(); STD_cout << "myfile_dir=" << myfile_dir << STD_endl; \endverbatim * */ class JDXfileName : public JDXstring { public: /** * Default constructor */ JDXfileName () {common_init();} /** * Constructor with the following arguments: * - filename: Initial value for the file name * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter */ JDXfileName (const STD_string& filename, const STD_string& name="", bool userParameter=true, compatMode mode=notBroken, parameterMode parameter_mode=edit); /** * Copy constructor */ JDXfileName(const JDXfileName& jf); /** * Assignment from a string */ JDXfileName& operator = (const STD_string& filename); /** * Assignment operator */ JDXfileName& operator = (const JDXfileName& jf); /** * Returns 'true' only if the file/directory exists */ bool exists() const; /** * Returns the filename without preceeding directories */ STD_string get_basename() const {return basename_cache;} /** * Returns the filename without preceeding directories and without * a previously specified suffix (file extension) */ STD_string get_basename_nosuffix() const; /** * Returns the directory of the filename */ STD_string get_dirname() const {return dirname_cache;} /** * Returns the suffix (file extension) of the filename */ STD_string get_suffix() const {return suffix_cache;} /** * Sets/overwrites the suffix (file extension) of the filename */ JDXfileName& set_suffix(const STD_string& suff) {suffix_cache=suff; return *this;} /** * Returns the default location of the filename */ STD_string get_defaultdir() const {return defaultdir;} /** * Sets the default location of the filename */ JDXfileName& set_defaultdir(const STD_string& defdir); /** * Returns whether used exclusively for directory names */ bool is_dir() const {return dir;} /** * Specifies whether used exclusively for directory names */ JDXfileName& set_dir(bool flag) {dir=flag; return *this;} // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); const char* get_typeInfo() const {return "fileName";} JcampDxClass* create_copy() const {return new JDXfileName(*this);} JDXfileName* cast(JDXfileName*) {return this;} private: static void normalize(const STD_string& fname, bool dir, STD_string& result, STD_string& result_dirname, STD_string& result_basename, STD_string& result_suffix); void common_init() {dir=false;} STD_string defaultdir; STD_string dirname_cache; STD_string basename_cache; STD_string suffix_cache; bool dir; }; ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX class for representing mathematic formulas */ class JDXformula : public JDXstring { public: /** * Default constructor */ JDXformula () : JDXstring() {} /** * Constructor with the following arguments: * - formula: Initial value for the formula * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter */ JDXformula (const STD_string& formula, const STD_string& name="", bool userParameter=true, compatMode mode=notBroken, parameterMode parameter_mode=edit); /** * Copy constructor */ JDXformula (const JDXformula& jf) {JDXformula::operator = (jf);} /** * Assignment from a formula string */ JDXformula& operator = (const STD_string& formula) {JDXstring::operator = (formula); return *this;} /** * Copy assignment */ JDXformula& operator = (const JDXformula& jf); /** * Sets a string describing the formulas syntax */ JDXformula& set_syntax(const STD_string& syn) {syntax=syn; return *this;} /** * Returns a string describing the formulas syntax */ STD_string get_syntax() const {return syntax;} // overwriting virtual functions from JcampDxClass const char* get_typeInfo() const {return "formula";} JcampDxClass* create_copy() const {return new JDXformula(*this);} JDXformula* cast(JDXformula*) {return this;} private: STD_string syntax; }; /** @} */ #endif odin-1.8.5/odinpara/protocol.h0000644000175000017500000000510311322062341013177 00000000000000/*************************************************************************** protocol.h - description ------------------- begin : Tue Jul 5 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef PROTOCOL_H #define PROTOCOL_H #include #include #include #include /** * @ingroup odinpara * * \brief Protcol proxy * * Class to hold the whole MR Protocol, that is system, geometry and seqpars */ class Protocol : public JcampDxBlock { public: /** * Create a default protocol with the given label for the sequence with label 'seqid' */ Protocol(const STD_string& label="unnamedProtocol"); /** * Copy constructor */ Protocol(const Protocol& p) {Protocol::operator = (p);} /** * Assignment operator */ Protocol& operator = (const Protocol& p); /** * Special comparison operator for Protocol which does not consider * 'AcquisitionStart' and 'offsetSlice' so that tempo-spatial data has the * 'same' protocol. This behaviour is required in FileIO::autoread. */ bool operator < (const Protocol& rhs) const; /** * Special comparison operator for Protocol which does not consider * 'AcquisitionStart' and 'offsetSlice' so that tempo-spatial data has the * 'same' protocol. This behaviour is required in FileIO::autoread. */ bool operator == (const Protocol& rhs) const {return !( ((*this) #include #include #include /** * @addtogroup odinpara * @{ */ /** * Enum to specify which boundary of a slice to take for a given direction */ enum sliceBoundary {lowerBound=0,upperBound,n_boundaries}; /** * The principal slice direction in the anatomical system of reference * - sagittal: Slice is perpendicular to left-right direction * - coronal: Slice is perpendicular to anterior-posterior direction * - axial: Slice is perpendicular to head-foot direction */ enum sliceOrientation {sagittal=0,coronal,axial,n_orientations}; /** * The geometry mode * - slicepack: A stack of equidistant parallel slices * - voxel_3d: A single 3D volume */ enum geometryMode {slicepack=0,voxel_3d,n_geometry_modes}; //////////////////////////////////////////////////////////////////////////// /** * \brief Rotation Matrix * * This class represents 3 by 3 rotation matrix */ class RotMatrix : public virtual Labeled { public: /** * default constructor for a 3 by 3 rotation matrix */ RotMatrix(const STD_string& object_label = "unnamedRotMatrix" ); /** * constructs a rotation matrix from an existing rotation matrix */ RotMatrix(const RotMatrix& sct); /** * returns a row of rotation matrix */ dvector& operator [] (unsigned int index) {return matrix[index%3];} // make sure index is lower than 3 /** * returns a row of rotation matrix */ const dvector& operator [] (unsigned int index) const {return matrix[index%3];} // make sure index is lower than 3 /** * assignment operator */ RotMatrix& operator = (const RotMatrix& sct); /** * returns true if srm is element-wise equal to this. Two elements are * considered equal if their difference does not exceed GEO_CHECK_LIMIT. * */ bool operator == (const RotMatrix& srm) const; // dummy comparison operator for lists bool operator < (const RotMatrix& srm) const; /** * returns the product this * vec */ dvector operator * (const dvector& vec) const; /** * returns the product this * matrix */ RotMatrix operator * (const RotMatrix& matrix) const; /** * Returns the matrix as a 2-dim farray */ operator farray () const; /** * Create anti-clockwise in-plane rotation matrix with angle 'phi' (in rad). */ RotMatrix& set_inplane_rotation(float phi); /** * returns a string describing the rotation matrix */ STD_string print() const; private: friend class RotMatrixVector; class rowVec : public dvector { public: rowVec() : dvector(3) {}; ~rowVec() {}; }; // bool check_and_correct(); rowVec matrix[3]; // static dvector returndummy; }; //////////////////////////////////////////////////////////////////////////// /** * \brief Geometry Settings * * Depending on the selected geometryMode, this class describes a pack * of parallel and congruent slices, or a 3D volume, .i.e. a voxel. * * The patients x,y,z coordinate system used for the gradients is as follows: * If standing in front of the magnet with the feet of the patient * pointing towards you, the axes are oriented * * - x: from right to left (in the final image left/right will then have the correct polarity) * - y: from bottom to top (floor to ceiling) * - z: pointing away from you to the patients head * * * The three orientation angles 'heightAngle', 'azimutAngle', and 'inplaneAngle' * (in degree) describe the orientation of the slicepack/voxel relative to * the x/y/z-coordinate system of the gradients. * If all these angles are zero, the read/phase/slice-system * of the slicepack/voxel is the same as the x/y/z-system of * the gradients. Otherwise, the system is rotated by the following * angles (in the given order): * * - azimutAngle: Anti-clockwise rotation around y-axis. * - heightAngle: Angle between slice vector (which is perp. to the slice) and x-z-plane * - inplaneAngle: Clockwise rotation around slice vector. * */ class Geometry : public JcampDxBlock { public: /** * Constructs a Geometry with the given label */ Geometry(const STD_string& label="unnamedGeometry"); /** * Copy constructor */ Geometry(const Geometry& ia); /** * Assignment operator */ Geometry& operator = (const Geometry& ia); /** * Sets the geometry selection mode */ Geometry& set_Mode(geometryMode mode); /** * Returns the geometry selection mode */ geometryMode get_Mode() const {return geometryMode(int(Mode));} /** * Sets the Field Of View in the specified direction */ Geometry& set_FOV(direction dir,double fov); /** * Returns the Field Of View in the specified direction */ double get_FOV(direction dir) const; /** * Sets the spatial offset in the specified direction */ Geometry& set_offset(direction dir,double offset); /** * Returns the spatial offset in the specified direction */ double get_offset(direction dir) const; /** * Sets the number of slices of the current slice pack */ Geometry& set_nSlices(unsigned int nslices); /** * Returns the number of slices of the current slice pack */ unsigned int get_nSlices() const {return nSlices;}; /** * Sets the slice thickness of the current slice pack */ Geometry& set_sliceThickness(double thick); /** * Sets the slice interslice distance */ Geometry& set_sliceDistance(double dist); /** * Returns the slice interslice distance */ double get_sliceDistance() const {return sliceDistance;} /** * Returns the normalised vector for the read direction in the laboratory system of reference */ dvector get_readVector() const; /** * Returns the normalised vector for the phase direction in the laboratory system of reference */ dvector get_phaseVector() const; /** * Returns the normalised vector for the slice direction in the laboratory system of reference */ dvector get_sliceVector() const; /** * Returns the vector of spatial offsets in slice direction for the different slices of the slicepack. */ dvector get_sliceOffsetVector() const; /** * Returns the slice thickness for the slices */ double get_sliceThickness() const {return sliceThickness;} /** * Returns a 5-dimensional array that contains the corner points of the slices/voxels where indexing is as follows: * (unsigned int slice,sliceBoundary boundary1,sliceBoundary boundary2,sliceBoundary boundary3, axis direction) with * - slice: The slice for the point * - boundary1: The boundary in the read direction * - boundary2: The boundary in the phase direction * - boundary3: The boundary in the slice direction, the size is 1 in slicepack mode * - direction: The x,y,z index * * The points are transformed to slice 'backgrslice' the coordinate system of 'background'. * */ darray get_cornerPoints(const Geometry& background, unsigned int backgrslice) const; /** * Set the angle parameters to match the specified anatomical slice orientation */ Geometry& set_orientation(sliceOrientation orientation); /** * Returns the principal anatomical slice orientation of slice normal 'svec'. */ static sliceOrientation get_slice_orientation(const dvector& svec); /** * Returns the principal anatomical slice orientation */ sliceOrientation get_orientation() const {return get_slice_orientation(get_sliceVector());} /** * Returns the orientation of the slice, i.e. the three orientation angles * 'heightAng', 'azimutAng' and 'inplaneAng'. * 'revSlice' returns whether the slice direction (handness) is reversed. */ void get_orientation(double& heightAng, double& azimutAng, double& inplaneAng, bool& revSlice) const; /** * Specifies the orientation of the slice pack by giving the three orientation angles * 'heightAng', 'azimutAng' and 'inplaneAng'. * Optionally, the slice direction can be reversed by setting 'revSlice' to true. */ Geometry& set_orientation(double heightAng, double azimutAng, double inplaneAng, bool revSlice=false); /** * Specifies the orientation of the slicepack/voxel by giving the three * vectors 'readvec', 'phasevec', and 'slicevec' which point in read, * phase, and slice direction. The vector 'offset' must contain the spatial * offset of the center of the slicepack/voxel. */ Geometry& set_orientation_and_offset(const dvector& readvec, const dvector& phasevec, const dvector& slicevec, const dvector& centervec); /** * Returns a vector pointing to the center of the slicepack/voxel. */ dvector get_center() const; /** * Returns the rotation matrix to convert the gradient strengths in the * sequence coordinate system (read,phase,slice) to the laboratory system (x,y,z). * If 'transpose' is set to true, the transposed matrix is returned. */ RotMatrix get_gradrotmatrix(bool transpose=false) const; /** * Coordinate transformation from sequence coordinate system (read,phase,slice) * of slice 'slice' to laboratory system (x,y,z), or vice versa if * 'inverse' is set to 'true'. */ dvector transform(const dvector& rpsvec, bool inverse=false) const; /** * Transpose geometry in-plane, 'reverse_read' and 'reverse_phase' * can be used to reverse read/phase direction before transposing. */ Geometry& transpose_inplane(bool reverse_read=false, bool reverse_phase=false); /** * Resets the slicepacks geometry to its inintial state */ Geometry& reset(); /** * Updates internal relations of the geometry parameters */ Geometry& update(); private: dvector get_readVector_inplane() const; dvector get_phaseVector_inplane() const; void append_all_members(); double deg2rad(double degree) const {return degree/180.0*PII;} JDXenum Mode; JDXdouble FOVread; JDXdouble offsetRead; JDXdouble FOVphase; JDXdouble offsetPhase; JDXdouble FOVslice; JDXdouble offsetSlice; JDXdouble heightAngle; JDXdouble azimutAngle; JDXdouble inplaneAngle; JDXbool reverseSlice; JDXint nSlices; JDXdouble sliceDistance; JDXdouble sliceThickness; JDXaction Reset; JDXaction Transpose; // cache to speed up repetitive calls to transform() mutable bool cache_up2date; mutable bool inv_trans_cache; mutable double rotmat_cache[3][3]; mutable double offset_cache[3]; }; /** @} */ #endif odin-1.8.5/odinpara/jdxarrays.h0000644000175000017500000001457011322062341013355 00000000000000/*************************************************************************** jdxarrays.h - description ------------------- begin : Mon Jul 5 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXARRAYS_H #define JDXARRAYS_H #include #include #include #include #define COMPRESSION_THRESHOLD_SIZE 256 /** * @addtogroup jcampdx * @{ */ /** * * JCAMP-DX template class for representing multi-dimensional arrays */ template class JDXarray : public A, public virtual JcampDxClass { public: /** * Default constructor */ JDXarray () : A() {common_init();} /** * Constructor with the following arguments: * - a: Initial value for the array base class * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter * - parx_equivalent: Equivalent parameter in PARX to which this parameter will be assigned * - parx_assign_factor: Scaling factor when assigning to the equivalent parameter in PARX * - parx_assign_offset: Offset when assigning to the equivalent parameter in PARX */ JDXarray (const A& a,const STD_string& name="",bool userParameter=true, compatMode mode=notBroken,parameterMode parameter_mode=edit, const STD_string& parx_equivalent="", float parx_assign_factor=1.0,float parx_assign_offset=0.0); /** * Assignment from scalar, i.e. fill all elements with this value */ // JDXarray (const J& jv) {common_init(); A::operator = (jv);} /** * Copy constructor */ JDXarray (const JDXarray& ja) {common_init(); JDXarray::operator = (ja);} /** * Assignment operator from an array */ JDXarray& operator = (const A& a); /** * Assignment operator from scalar, i.e. fill all elements with this value */ JDXarray& operator = (const J& jv) {A::operator = (jv); return *this;} /** * Copy assignment */ JDXarray& operator = (const JDXarray& ja); // overwriting virtual functions from JcampDxClass STD_ostream& print2stream(STD_ostream& os) const; STD_string printvalstring() const; bool parsevalstring (const STD_string& parstring); STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv) const; ParxEquiv get_parx_equiv() const {return parx_equiv;} GuiProps get_gui_props() const {return guiprops;} JcampDxClass& set_gui_props(const GuiProps& gp) {guiprops=gp; return *this;} const char* get_typeInfo() const; JcampDxClass* create_copy() const {return new JDXarray(*this);} A* cast(A*) {return this;} // final overrider friend STD_ostream& operator << (STD_ostream& s,const JDXarray& ja) { return ja.print2stream(s);} int write(const STD_string& filename) const {return JcampDxClass::write(filename);} int load(const STD_string &filename) {return JcampDxClass::load(filename);} private: void common_init(); STD_string get_dim_str() const; bool encode(STD_string* ostring, STD_ostream* ostream) const; bool use_compression() const {return (get_filemode()==compressed)&&(A::total()>COMPRESSION_THRESHOLD_SIZE);} ParxEquiv parx_equiv; GuiProps guiprops; mutable STD_string typeInfo_cache; }; ////////////////////////////////////////////////////////////////////////////////// // // Aliases: // /** * A JCAMP-DX array of strings */ typedef JDXarray JDXstringArr; /** * A JCAMP-DX array of integer numbers */ typedef JDXarray JDXintArr; /** * A JCAMP-DX array of single-precision floating point numbers */ typedef JDXarray JDXfloatArr; /** * A JCAMP-DX array of double-precision floating point numbers */ typedef JDXarray JDXdoubleArr; /** * A JCAMP-DX array of single-precision complex numbers */ typedef JDXarray JDXcomplexArr; ///////////////////////////////////////////////////////////////////////////// // Specialised array classes: /** * A JCAMP-DX vector of 3 float values which is used to store spatial positions, FOVs, etc. */ class JDXtriple : public JDXfloatArr { public: /** * Default constructor */ JDXtriple () : JDXfloatArr(farray(3)) {} /** * Constructor with the following arguments: * - xpos: Spatial position in the first dimension * - ypos: Spatial position in the second dimension * - zpos: Spatial position in the third dimension * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter */ JDXtriple (float xpos,float ypos, float zpos, const STD_string& name="",bool userParameter=true, compatMode mode=notBroken,parameterMode parameter_mode=edit); /** * Copy constructor */ JDXtriple (const JDXtriple& pos) {JDXtriple::operator = (pos);} /** * Copy assignment */ JDXtriple& operator = (const JDXtriple& pos) { JDXfloatArr::operator = (pos); return *this; } // overwriting virtual functions from JcampDxClass const char* get_typeInfo() const {return "triple";} JcampDxClass* create_copy() const {return new JDXtriple(*this);} JDXtriple* cast(JDXtriple*) {return this;} farray* cast(farray*) {return 0;} // disable casting to base class }; /** @} */ #endif odin-1.8.5/odinpara/system.cpp0000644000175000017500000003676711363773555013266 00000000000000#include "system.h" #include Nuclei::Nuclei() { // nuclist.push_back(Nucleus("1n", 183.247215)); // nuclist.push_back(Nucleus("1H", 267.522322)); nuclist.push_back(Nucleus("1H", 267.50998)); nuclist.push_back(Nucleus("1Hb",267.50998)); nuclist.push_back(Nucleus("2H", 41.066271)); nuclist.push_back(Nucleus("3H", 285.349604)); nuclist.push_back(Nucleus("3He", 203.801399)); nuclist.push_back(Nucleus("6Li", 39.371067)); nuclist.push_back(Nucleus("7Li", 103.976035)); nuclist.push_back(Nucleus("9Be", 37.599838)); nuclist.push_back(Nucleus("10B", 28.746829)); nuclist.push_back(Nucleus("11B", 85.847161)); nuclist.push_back(Nucleus("13C", 67.282862)); nuclist.push_back(Nucleus("14N", 19.337759)); nuclist.push_back(Nucleus("15N", 27.126396)); // nuclist.push_back(Nucleus("17O", 36.280369)); nuclist.push_back(Nucleus("17O",36.265437)); nuclist.push_back(Nucleus("19F", 251.814987)); nuclist.push_back(Nucleus("21Ne", 21.130981)); nuclist.push_back(Nucleus("23Na", 70.803959)); nuclist.push_back(Nucleus("25Mg", 16.388432)); nuclist.push_back(Nucleus("27Al", 69.762835)); nuclist.push_back(Nucleus("29Si", 53.190305)); // nuclist.push_back(Nucleus("31P", 108.394371)); nuclist.push_back(Nucleus("31P",108.28945)); nuclist.push_back(Nucleus("33S", 20.556697)); nuclist.push_back(Nucleus("35Cl", 26.241723)); nuclist.push_back(Nucleus("37Cl", 21.843494)); nuclist.push_back(Nucleus("37Ar", 36.561855)); nuclist.push_back(Nucleus("39Ar", 21.739821)); nuclist.push_back(Nucleus("39K", 12.499141)); nuclist.push_back(Nucleus("40K", 15.542715)); nuclist.push_back(Nucleus("41K", 6.860610)); nuclist.push_back(Nucleus("43Ca", 18.025202)); nuclist.push_back(Nucleus("45Sc", 65.088145)); nuclist.push_back(Nucleus("47Ti", 15.105406)); nuclist.push_back(Nucleus("49Ti", 15.109804)); nuclist.push_back(Nucleus("50V", 26.706679)); nuclist.push_back(Nucleus("51V", 70.455242)); nuclist.push_back(Nucleus("53Cr", 15.151901)); nuclist.push_back(Nucleus("55Mn", 66.452853)); nuclist.push_back(Nucleus("57Fe", 8.680849)); nuclist.push_back(Nucleus("59Co", 63.315658)); nuclist.push_back(Nucleus("61Ni", 23.947732)); nuclist.push_back(Nucleus("63Cu", 70.988684)); nuclist.push_back(Nucleus("65Cu", 76.045392)); nuclist.push_back(Nucleus("67Zn", 16.772335)); nuclist.push_back(Nucleus("69Ga", 64.388826)); nuclist.push_back(Nucleus("71Ga", 81.812099)); nuclist.push_back(Nucleus("73Ge", 9.360061)); nuclist.push_back(Nucleus("75As", 45.961501)); nuclist.push_back(Nucleus("77Se", 51.252571)); nuclist.push_back(Nucleus("79Br", 67.256472)); nuclist.push_back(Nucleus("81Br", 72.497905)); nuclist.push_back(Nucleus("83Kr", 10.330813)); nuclist.push_back(Nucleus("85Rb", 25.920653)); nuclist.push_back(Nucleus("87Rb", 87.845842)); nuclist.push_back(Nucleus("87Sr", 11.639601)); nuclist.push_back(Nucleus("89Y", 13.162645)); nuclist.push_back(Nucleus("91Zr", 24.974405)); nuclist.push_back(Nucleus("93Nb", 65.673738)); nuclist.push_back(Nucleus("95Mo", 17.513751)); nuclist.push_back(Nucleus("97Mo", 17.883830)); nuclist.push_back(Nucleus("99Tc", 60.503305)); nuclist.push_back(Nucleus("99Ru", 12.285512)); nuclist.push_back(Nucleus("101Ru", 13.770229)); nuclist.push_back(Nucleus("103Rh", 8.467849)); nuclist.push_back(Nucleus("105Pd", 12.296194)); nuclist.push_back(Nucleus("107Ag", 10.889388)); nuclist.push_back(Nucleus("109Ag", 12.518618)); nuclist.push_back(Nucleus("111Cd", 56.983464)); nuclist.push_back(Nucleus("113Cd", 59.609207)); nuclist.push_back(Nucleus("113In", 58.845172)); nuclist.push_back(Nucleus("115In", 58.971464)); nuclist.push_back(Nucleus("115Sn", 88.012975)); nuclist.push_back(Nucleus("117Sn", 95.887691)); nuclist.push_back(Nucleus("119Sn", 100.317337)); nuclist.push_back(Nucleus("121Sb", 64.434694)); nuclist.push_back(Nucleus("123Sb", 34.891785)); nuclist.push_back(Nucleus("123Te", 70.590959)); nuclist.push_back(Nucleus("125Te", 85.108258)); nuclist.push_back(Nucleus("127I", 53.895907)); nuclist.push_back(Nucleus("129Xe", 74.521091)); nuclist.push_back(Nucleus("131Xe", 22.091051)); nuclist.push_back(Nucleus("133Cs", 35.332864)); nuclist.push_back(Nucleus("135Ba", 26.755060)); nuclist.push_back(Nucleus("137Ba", 29.929325)); nuclist.push_back(Nucleus("138La", 35.572254)); nuclist.push_back(Nucleus("139La", 38.083643)); nuclist.push_back(Nucleus("137Ce", 30.661944)); nuclist.push_back(Nucleus("139Ce", 33.866369)); nuclist.push_back(Nucleus("141Ce", 14.891149)); nuclist.push_back(Nucleus("141Pr", 81.906975)); nuclist.push_back(Nucleus("143Nd", 14.570707)); nuclist.push_back(Nucleus("145Nd", 8.978672)); nuclist.push_back(Nucleus("143Pm", 72.822118)); nuclist.push_back(Nucleus("147Pm", 35.311501)); nuclist.push_back(Nucleus("147Sm", 11.151397)); nuclist.push_back(Nucleus("149Sm", 9.192928)); nuclist.push_back(Nucleus("151Eu", 66.511286)); nuclist.push_back(Nucleus("153Eu", 29.370750)); nuclist.push_back(Nucleus("155Gd", 8.243539)); nuclist.push_back(Nucleus("157Gd", 10.807079)); nuclist.push_back(Nucleus("159Tb", 64.276986)); nuclist.push_back(Nucleus("161Dy", 9.207380)); nuclist.push_back(Nucleus("163Dy", 12.885556)); nuclist.push_back(Nucleus("165Ho", 57.103473)); nuclist.push_back(Nucleus("167Er", 7.716380)); nuclist.push_back(Nucleus("169Tm", 22.185927)); nuclist.push_back(Nucleus("171Yb", 47.287881)); nuclist.push_back(Nucleus("173Yb", 13.025043)); nuclist.push_back(Nucleus("175Lu", 30.552617)); nuclist.push_back(Nucleus("176Lu", 21.683272)); nuclist.push_back(Nucleus("177Hf", 10.858601)); nuclist.push_back(Nucleus("179Hf", 6.821026)); nuclist.push_back(Nucleus("180Ta", 25.679378)); nuclist.push_back(Nucleus("181Ta", 32.438201)); nuclist.push_back(Nucleus("183W", 11.282716)); nuclist.push_back(Nucleus("185Re", 61.057482)); nuclist.push_back(Nucleus("187Re", 61.682030)); nuclist.push_back(Nucleus("187Os", 6.192707)); nuclist.push_back(Nucleus("189Os", 21.071290)); nuclist.push_back(Nucleus("191Ir", 4.811663)); nuclist.push_back(Nucleus("191Ir", 5.226982)); nuclist.push_back(Nucleus("195Pt", 58.384615)); nuclist.push_back(Nucleus("197Au", 4.653327)); nuclist.push_back(Nucleus("199Hg", 48.457810)); nuclist.push_back(Nucleus("201Hg", 17.887600)); nuclist.push_back(Nucleus("203Tl", 155.393226)); nuclist.push_back(Nucleus("205Tl", 156.921925)); nuclist.push_back(Nucleus("207Pb", 56.762296)); nuclist.push_back(Nucleus("209Bi", 43.749819)); nuclist.push_back(Nucleus("209Po", 73.513268)); nuclist.push_back(Nucleus("211Rn", 57.553977)); nuclist.push_back(Nucleus("223Fr", 37.384953)); nuclist.push_back(Nucleus("223Ra", 8.636867)); nuclist.push_back(Nucleus("225Ra", 70.289994)); nuclist.push_back(Nucleus("227Ac", 35.185838)); nuclist.push_back(Nucleus("229Th", 8.796459)); nuclist.push_back(Nucleus("231Pa", 64.088490)); nuclist.push_back(Nucleus("235U", 5.215044)); nuclist.push_back(Nucleus("237Np", 60.130083)); nuclist.push_back(Nucleus("239Pu", 19.415043)); nuclist.push_back(Nucleus("243Am", 28.902652)); } double Nuclei::get_gamma(const STD_string& nucName) const { NucList::const_iterator resultit=nuclist.begin(); for(NucList::const_iterator it=nuclist.begin();it!=nuclist.end();++it) { if(it->first == nucName) resultit=it; } return resultit->second; } double Nuclei::get_nuc_freq(const STD_string& nucName,float B0) const { float freq; float b0=B0; if (b0==0.0) b0=-1.0; freq= ( get_gamma(nucName) *b0) / (2.0*PII); if(freq==0.0) freq=-1.0; return freq; } JDXenum Nuclei::get_nuc_enum() const { JDXenum result; for(STD_list::const_iterator it=nuclist.begin();it!=nuclist.end();++it) { result.add_item(it->first); } return result; } ///////////////////////////////////////////////////////////////////////////// System::System(const STD_string& object_label) : JcampDxBlock(object_label) { Log odinlog(this, "System(...)"); platformstr.set_parmode(hidden).set_description("The current platform"); main_nucleus=get_nuc_enum(); main_nucleus.set_actual(0); main_nucleus.set_description("The main nucleus for transmit/receive"); delay_rastertime=0.0; delay_rastertime.set_unit(ODIN_TIME_UNIT).set_description("Delay duration must be multiple of this interval"); grad_rastertime=0.0; grad_rastertime.set_unit(ODIN_TIME_UNIT).set_description("Gradient duration must be multiple of this interval"); min_grad_rastertime=0.005; min_grad_rastertime.set_unit(ODIN_TIME_UNIT).set_description("Minimum gradient raster time possible"); rf_rastertime=0.0; rf_rastertime.set_unit(ODIN_TIME_UNIT).set_description("RF pulse duration must be multiple of this interval"); acq_rastertime=0.0; acq_rastertime.set_unit(ODIN_TIME_UNIT).set_description("Acquisition duration must be multiple of this interval"); max_rf_samples=3000; max_rf_samples.set_description("Maximum number of points in RF waveform"); max_grad_samples=-1; max_grad_samples.set_description("Maximum number of points in gradient waveform"); reference_gain=20.0; reference_gain.set_unit("dB").set_description("RF reference gain"); transmit_coil_name="Unknown"; transmit_coil_name.set_cmdline_option("tcname").set_description("Name of transmit coil"); inter_grad_delay=0.0; inter_grad_delay.set_unit(ODIN_TIME_UNIT).set_description("Minimum delay between gradient objects"); max_grad=_DEFAULT_MAX_SYSTEM_GRADIENT_; max_grad.set_unit(ODIN_GRAD_UNIT).set_description("Maximum gradient strength"); max_slew_rate=_DEFAULT_MAX_SYSTEM_SLEWRATE_; max_slew_rate.set_unit(STD_string(ODIN_GRAD_UNIT)+"/"+ODIN_TIME_UNIT).set_description("Maximum gradient slew rate"); grad_shift=0.0; grad_shift.set_unit(ODIN_TIME_UNIT).set_description("Latency difference between RF/acquistion and gradient channels"); B0=_DEFAULT_B0_; B0.set_unit(ODIN_FIELD_UNIT).set_description("Main field strength"); datatype=TypeTraits::type2label(float(0)); datatype.set_description("Digital representation of raw data"); grad_reson_center.set_filemode(exclude).set_unit(ODIN_FREQ_UNIT).set_description("Center of gradient resonance frequencies"); grad_reson_width.set_filemode(exclude).set_unit(ODIN_FREQ_UNIT).set_description("Width of gradient resonance frequencies"); min_duration.resize(endObj); min_duration=0.0; System::append_all_members(); } System& System::operator = (const System& s) { JcampDxBlock::operator = (s); System::append_all_members(); // copy only visible members of JcampDxBlock copy_ldr_vals(s); return *this; } odinPlatform System::get_platform() const { return SystemInterface::get_current_pf(); } System& System::set_main_nucleus(const STD_string& nucname) { main_nucleus.set_actual(nucname); return *this; } System& System::set_transmit_coil_name(const STD_string& tcname) { transmit_coil_name=tcname; return *this; } float System::get_grad_switch_time(float graddiff) const { return ( secureDivision(fabs(graddiff),max_slew_rate) + get_inter_grad_delay() ); } System& System::set_reference_gain(float refgain) { reference_gain=refgain; return *this; } System& System::set_B0_from_freq(double freq, const STD_string& nucName) { B0=2.0*PII*secureDivision(freq,get_gamma(nucName)); return *this; } double System::get_gamma(const STD_string& nucName) const { return nuc.get_gamma(nucName); } System& System::set_scandir(const STD_string& dir) { Log odinlog(this,"set_scandir"); #ifndef NO_FILEHANDLING if(!checkdir(dir.c_str())) ODINLOG(odinlog,errorLog) << "scan directory " << dir << " does not exist" << STD_endl; #endif scandir=dir; return *this; } STD_string System::get_scandir() const {return scandir+"/";} double System::get_nuc_freq(const STD_string& nucName) const { return nuc.get_nuc_freq(nucName,B0); } JDXenum System::get_nuc_enum() const {return nuc.get_nuc_enum();} double System::get_rastertime(objCategory cat) const { if(cat==pulsObj) return rf_rastertime; if(cat==gradObj) return grad_rastertime; if(cat==delayObj) return delay_rastertime; if(cat==acqObj) return acq_rastertime; if(cat==freqObj) return rf_rastertime; if(cat==syncObj) return grad_rastertime; return 0.0; } double System::get_rasteredtime(objCategory cat, double time) const { double rastime=get_rastertime(cat); if(rastime) { int eventtime_round=int(time/rastime+0.5); return double(eventtime_round)*rastime; } else return time; } bool System::allowed_grad_freq(double freq, double& low, double& upp) const { low=upp=freq; for(unsigned int i=0; i odinlog(this,"load"); ODINLOG(odinlog,errorLog) << "called" << STD_endl; return -1; } int System::append_all_members() { append_member(platformstr,"Platform"); append_member(main_nucleus,"MainNucleus"); append_member(max_grad,"MaximumGradientStrength"); append_member(max_slew_rate,"MaximumGradientSlewRate"); append_member(grad_shift,"GradientChannelShiftDelay"); append_member(B0,"MagneticFieldStrength"); append_member(reference_gain,"ReferenceGain"); append_member(transmit_coil_name,"TransmitCoilName"); append_member(inter_grad_delay,"InterGradientSwitchingDelay"); append_member(delay_rastertime,"DelayRasterTime"); append_member(grad_rastertime,"GradientRasterTime"); append_member(min_grad_rastertime,"MinGradientRasterTime"); append_member(rf_rastertime,"RFRasterTime"); append_member(acq_rastertime,"AcquisitionRasterTime"); append_member(max_rf_samples,"MaxNumOfSamplesPerRF"); append_member(max_grad_samples,"MaxNumOfSamplesPerGradWave"); append_member(grad_reson_center,"GradResonCenter"); append_member(grad_reson_width,"GradResonWidth"); append_member(datatype,"Datatype"); return 0; } ///////////////////////////////////////////////////////////////////////////// System* SystemInterface::get_sysinfo_ptr() { int pfint=current_pf->operator int (); return systemInfo_platform[pfint].unlocked_ptr(); } const System* SystemInterface::get_const_sysinfo_ptr() { int pfint=current_pf->operator int (); const SingletonHandler& shs=systemInfo_platform[pfint]; return shs.operator -> (); // return &(const System&)(*shs); } void SystemInterface::init_static() { current_pf.init("current_pf"); systemInfo_platform= new SingletonHandler[numof_platforms]; for(unsigned int i=0; iset_label("systemInfo"); } } void SystemInterface::destroy_static() { for(unsigned int i=0; i odinlog("SystemInterface","set_current_pf"); ODINLOG(odinlog,normalDebug) << "pf=" << pf << STD_endl; if(current_pf) current_pf->operator = (pf); else ODINLOG(odinlog,errorLog) << "current_pf not yet initialized" << STD_endl; } template class SingletonHandler; SingletonHandler SystemInterface::current_pf; template class SingletonHandler; SingletonHandler* SystemInterface::systemInfo_platform=0; EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/odinpara/jdxnumbers.cpp0000644000175000017500000001105711322062341014057 00000000000000#include "jdxnumbers.h" #include "jdxblock.h" // for UnitTest #include /////////////////////////////////////////////////////////////// template void JDXnumber::set_defaults() { val=T(0); minval=0.0; maxval=0.0; parx_equiv.type=TypeTraits::type2label(val); } template JDXnumber::JDXnumber(T v,const STD_string& name,bool userParameter, compatMode mode,parameterMode parameter_mode, const STD_string& parx_equivalent, float parx_assign_factor,float parx_assign_offset) { set_defaults(); val=v; set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); parx_equiv.name=parx_equivalent; parx_equiv.factor=parx_assign_factor; parx_equiv.offset=parx_assign_offset; JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! } template JDXnumber& JDXnumber::operator = (const JDXnumber& bi) { JcampDxClass::operator = (bi); val=bi.val; parx_equiv=bi.parx_equiv; minval=bi.minval; maxval=bi.maxval; return *this; } template STD_string JDXnumber::printvalstring() const { return TypeTraits::type2string(val); } template bool JDXnumber::parsevalstring(const STD_string& parstring) { TypeTraits::string2type(parstring,val); return true; } template STD_string JDXnumber::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN Log odinlog(this,"get_parx_code"); STD_string result=JcampDxClass::get_parx_code(type,equiv); if(type==parx_def) result=get_parx_def_string(get_typeInfo(),0); if(type==parx_passval) { STD_string transformation; if (equiv.offset) transformation+=ftos(equiv.offset)+"+"; if (equiv.factor!=1.0) transformation+=ftos(equiv.factor)+"*"; result=equiv.name+"="+transformation+get_label()+";\n"; } return result; #else return ""; #endif } /////////////////////////////////////////////////////////////////// // Instantiations template class JDXnumber; template class JDXnumber; template class JDXnumber; template class JDXnumber; /////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class JDXintTest : public UnitTest { public: JDXintTest() : UnitTest("JDXint") {} private: bool check() const { Log odinlog(this,"check"); // testing JDXint JDXint testint(23,"testint"); STD_string expected="##$testint=23\n"; STD_string printed=testint.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXint::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } JcampDxBlock builtinblock; builtinblock.append(testint); builtinblock.parseblock("##TITLE=builtinblock\n##$testint=46\n##END="); if(int(testint)!=46) { ODINLOG(odinlog,errorLog) << "after builtinblock.parseblock(): for int " << int(testint) << "!=" << 46 << STD_endl; return false; } testint*=2; if(int(testint)!=92) { ODINLOG(odinlog,errorLog) << "JDXint *= " << int(testint) << "!=" << 92 << STD_endl; return false; } return true; } }; void alloc_JDXintTest() {new JDXintTest();} // create test instance class JDXcomplexTest : public UnitTest { public: JDXcomplexTest() : UnitTest("JDXcomplex") {} private: bool check() const { Log odinlog(this,"check"); // testing JDXcomplex JDXcomplex testcplx(STD_complex(1.2,3.4),"testcplx"); STD_string expected="##$testcplx=1.20+3.40i\n"; STD_string printed=testcplx.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXcomplex::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } JcampDxBlock cplxblock; cplxblock.append(testcplx); cplxblock.parseblock("##TITLE=cplxblock\n##testcplx=5.6+7.8i\n##END="); if(STD_complex(testcplx)!=STD_complex(5.6,7.8)) { ODINLOG(odinlog,errorLog) << "after cplxblock.parseblock(): for complex " << STD_complex(testcplx) << "!=" << STD_complex(5.6,7.8) << STD_endl; return false; } testcplx/=STD_complex(2.0); if(STD_complex(testcplx)!=STD_complex(2.8,3.9)) { ODINLOG(odinlog,errorLog) << "JDXcomplex /= " << STD_complex(testcplx) << "!=" << STD_complex(2.8,3.9) << STD_endl; return false; } return true; } }; void alloc_JDXcomplexTest() {new JDXcomplexTest();} // create test instance #endif odin-1.8.5/odinpara/jdxtypes.cpp0000644000175000017500000005022411322062341013547 00000000000000#include "jdxtypes.h" #include "jdxblock.h" // for UnitTest #include JDXstring::JDXstring(const STD_string& ss,const STD_string& name,bool userParameter, compatMode mode,parameterMode parameter_mode, const STD_string& parx_equivalent) : STD_string(ss) { set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! parx_equiv.name=parx_equivalent; } JDXstring& JDXstring::operator = (const JDXstring& ss) { JcampDxClass::operator = (ss); STD_string::operator = (ss); parx_equiv=ss.parx_equiv; return *this; } STD_string JDXstring::printvalstring() const { Log odinlog(this,"printvalstring"); if(get_filemode()==exclude) return ""; STD_string result; if(get_compatmode()==bruker) { ndim nn(1); int l=length()*_BRUKER_MODE_STRING_CAP_FACTOR_; if(!l) l=_BRUKER_MODE_STRING_CAP_START_; if(l<_BRUKER_MODE_STRING_MIN_SIZE_) l=_BRUKER_MODE_STRING_MIN_SIZE_; nn[0]=l; result+=STD_string(nn)+"\n"; } if(get_compatmode()==bruker) result+="<"; result+=STD_string(*this); if(get_compatmode()==bruker) result+=">"; ODINLOG(odinlog,normalDebug) << "returning >" << result << "<" << STD_endl; return result; } bool JDXstring::parsevalstring(const STD_string& str) { Log odinlog(this,"parsevalstring"); ODINLOG(odinlog,normalDebug) << "str=>" << str << "<" << STD_endl; STD_string without_size_field; if(get_compatmode()==bruker) without_size_field=extract(str,"\n",""); else without_size_field=str; ODINLOG(odinlog,normalDebug) << "without_size_field=>" << without_size_field << "<" << STD_endl; STD_string shrinked=shrink(without_size_field); ODINLOG(odinlog,normalDebug) << "shrinked=>" << shrinked << "<" << STD_endl; if (shrinked.length()>=2 && shrinked[(unsigned int)0]=='<' && shrinked[shrinked.length()-1]=='>') (*this)=extract(without_size_field,"<",">",true); else (*this)=without_size_field; return true; } STD_string JDXstring::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN STD_string result=JcampDxClass::get_parx_code(type,equiv); if(type==parx_def) result=get_parx_def_string(get_parx_equiv().type,1); if(type==parx_passval) result="sprintf("+equiv.name+",\"%s\","+get_label()+");\n"; return result; #else return ""; #endif } #ifndef NO_UNIT_TEST class JDXstringTest : public UnitTest { public: JDXstringTest() : UnitTest("JDXstring") {} private: bool check() const { Log odinlog(this,"check"); JDXstring teststr1("value","teststr1",true,notBroken); JDXstring teststr2("value","teststr2",true,bruker); // testing JDXstring::print STD_string expected="##$teststr1=value\n"; STD_string printed=teststr1.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="##$teststr2=( "+itos(_BRUKER_MODE_STRING_MIN_SIZE_)+" )\n\n"; printed=teststr2.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } // testing JDXstring::parse JcampDxBlock block; block.append(teststr1); block.append(teststr2); int parseresult=block.parseblock("##TITLE=block\n##$teststr1=parseval\n##$teststr2=( 64 )\n\n$$ Comment\n##$dummy=dummyval\n##END="); if(parseresult!=2) { ODINLOG(odinlog,errorLog) << "JcampDxBlock::parseblock() failed: parseresult=" << parseresult << "!=" << 2 << STD_endl; return false; } if(STD_string(block.get_label())!="block") { ODINLOG(odinlog,errorLog) << "JcampDxBlock::get_label() failed: >" << block.get_label() << "< != >block<" << STD_endl; return false; } if(STD_string(teststr1)!=STD_string(teststr2)) { ODINLOG(odinlog,errorLog) << "after block.parseblock(): >" << STD_string(teststr1) << "< != >" << STD_string(teststr2) << "<" << STD_endl; return false; } return true; } }; void alloc_JDXstringTest() {new JDXstringTest();} // create test instance #endif ////////////////////////////////////////////////////////////////// JDXbool::JDXbool(bool flag, const STD_string& name,bool userParameter, compatMode mode,parameterMode parameter_mode, const STD_string& parx_equivalent) : val(flag) { set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! parx_equiv.name=parx_equivalent; } JDXbool& JDXbool::operator = (const JDXbool& jb) { JcampDxClass::operator = (jb); val=jb.val; parx_equiv=jb.parx_equiv; return *this; } bool JDXbool::parsevalstring (const STD_string& parstring) { Log odinlog(this,"parsevalstring"); STD_string yesnostr(shrink(tolowerstr(parstring))); ODINLOG(odinlog,normalDebug) << "yesnostr=" << yesnostr << STD_endl; if(yesnostr=="yes" || yesnostr=="true") val=true; else val=false; ODINLOG(odinlog,normalDebug) << "this=" << bool(*this) << STD_endl; return true; } STD_string JDXbool::printvalstring() const { if(val) return "Yes"; else return "No"; } STD_string JDXbool::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN STD_string result=JcampDxClass::get_parx_code(type,equiv); if(type==parx_def) result=get_parx_def_string(equiv.type,0); return result; #else return ""; #endif } #ifndef NO_UNIT_TEST class JDXboolTest : public UnitTest { public: JDXboolTest() : UnitTest("JDXbool") {} private: bool check() const { Log odinlog(this,"check"); JDXbool testbool(false,"testbool"); testbool=true; STD_string expected="##$testbool=Yes\n"; STD_string printed=testbool.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } JcampDxBlock boolblock; boolblock.append(testbool); boolblock.parseblock("##TITLE=boolblock\n##$testbool=No\n##END="); if(bool(testbool)!=false) { ODINLOG(odinlog,errorLog) << "after boolblock.parseblock(): for bool " << bool(testbool) << "!=" << false << STD_endl; return false; } return true; } }; void alloc_JDXboolTest() {new JDXboolTest();} // create test instance #endif /////////////////////////////////////////////////////////////// JDXenum::JDXenum(const STD_string& first_entry, const STD_string& name,bool userParameter, compatMode mode,parameterMode parameter_mode, const STD_string& parx_equivalent) { add_item(first_entry); set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! parx_equiv.name=parx_equivalent; } JDXenum& JDXenum::operator = (const JDXenum& je) { JcampDxClass::operator = (je); entries=je.entries; for(STD_map::const_iterator it=entries.begin();it!=entries.end();++it) { if ( (it->first) == (je.actual->first) ) actual=it; } parx_equiv=je.parx_equiv; return *this; } JDXenum& JDXenum::add_item(const STD_string& item, int index) { if(item=="") return *this; int n=0; if(index<0) { for(STD_map::const_iterator it=entries.begin();it!=entries.end();++it) { if ( it->first > n ) n=it->first; } if(entries.size()) n++; } else n=index; entries[n]=item; actual=entries.find(n); return *this; } JDXenum& JDXenum::set_actual(const STD_string& item) { STD_map::const_iterator it; for(it=entries.begin();it!=entries.end();++it) { if ( (it->second) == item ) actual=it; } return *this; } JDXenum& JDXenum::set_actual(int index) { STD_map::const_iterator it; for(it=entries.begin();it!=entries.end();++it) { if ( (it->first) == index ) actual=it; } return *this; } JDXenum& JDXenum::clear() { entries.clear(); actual=entries.end(); return *this; } JDXenum::operator int () const { if(actual!=entries.end()) return actual->first; else return 0; } JDXenum::operator STD_string () const { if(actual!=entries.end()) return actual->second; else return ""; } static STD_string notext("none"); const STD_string& JDXenum::get_item(unsigned int index) const { STD_map::const_iterator it=entries.begin(); for(unsigned int i=0; isecond; } unsigned int JDXenum::get_item_index() const { unsigned int result=0; for(STD_map::const_iterator it=entries.begin();it!=entries.end();++it) { if ( it==actual ) return result; result++; } return 0; } JDXenum& JDXenum::set_item_index(unsigned int index) { STD_map::const_iterator it=entries.begin(); for(unsigned int i=0; i::const_iterator it; for(it=entries.begin();it!=entries.end();++it) { if ( (it->second) == newpar ) { already_there=true; actual=it; } } if(!already_there && (entries.size()==0) ) add_item(newpar); return true; } STD_string JDXenum::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN STD_string result=JcampDxClass::get_parx_code(type,equiv); if(type==parx_def) result=get_parx_def_string(equiv.type,0); return result; #else return ""; #endif } ParxEquiv JDXenum::get_parx_equiv() const { parx_equiv.type=toupperstr(STD_string(get_label())); return parx_equiv; } svector JDXenum::get_alternatives() const { unsigned int n=n_items(); svector result; result.resize(n); for(unsigned int i=0; isecond); else return "emptyEnum"; } #ifndef NO_UNIT_TEST class JDXenumTest : public UnitTest { public: JDXenumTest() : UnitTest("JDXenum") {} private: bool check() const { Log odinlog(this,"check"); // testing JDXenum JDXenum testenum("","testenum"); testenum.add_item("item7",7); testenum.add_item("item0",0); testenum.add_item("item5",5); testenum.add_item("item1",1); testenum="item5"; STD_string expected="##$testenum=item5\n"; STD_string printed=testenum.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "testenum::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } testenum=7; expected="##$testenum=item7\n"; printed=testenum.print(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "testenum::print() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } JcampDxBlock enumblock; enumblock.append(testenum); enumblock.parseblock("##TITLE=enumblock\n##testenum=item1\n##END="); if((int)testenum!=1) { ODINLOG(odinlog,errorLog) << "after enumblock.parseblock(): for JDXenum " << (int)testenum << "!=" << 1 << STD_endl; return false; } return true; } }; void alloc_JDXenumTest() {new JDXenumTest();} // create test instance #endif /////////////////////////////////////////////////////////////// JDXaction::JDXaction(bool init_state, const STD_string& name,bool userParameter, compatMode mode,parameterMode parameter_mode) : state(init_state) { JcampDxClass::set_filemode(exclude); // Do NOT call virtual function in constructor! set_label(name); JcampDxClass::set_compatmode(mode); // Do NOT call virtual function in constructor! set_userDefParameter(userParameter); JcampDxClass::set_parmode(parameter_mode); // Do NOT call virtual function in constructor! } JDXaction& JDXaction::operator = (const JDXaction& ja) { JcampDxClass::operator = (ja); return *this; } JDXaction::operator bool () const { bool result=state; state=false; return result; } bool JDXaction::parsevalstring (const STD_string& parstring) { STD_string actionstr(shrink(tolowerstr(parstring))); if(actionstr=="busy") state=true; else state=false; return true; } STD_string JDXaction::printvalstring() const { if(state) return "CLICK_HERE"; else return "NOW"; } /////////////////////////////////////////////////////////////// JDXfileName::JDXfileName(const STD_string& filename, const STD_string& name, bool userParameter, compatMode mode, parameterMode parameter_mode) : JDXstring(filename, name, userParameter, mode, parameter_mode) { common_init(); normalize(filename, dir, *this, dirname_cache, basename_cache, suffix_cache); } JDXfileName::JDXfileName (const JDXfileName& jf) { common_init(); JDXfileName::operator = (jf); } JDXfileName& JDXfileName::operator = (const STD_string& filename) { normalize(filename, dir, *this, dirname_cache, basename_cache, suffix_cache); return *this; } JDXfileName& JDXfileName::operator = (const JDXfileName& jf) { JDXstring::operator = (jf); dir=jf.dir; normalize(jf, dir, *this, dirname_cache, basename_cache, suffix_cache); defaultdir=jf.defaultdir; return *this; } bool JDXfileName::exists() const { bool result=false; #ifndef NO_FILEHANDLING if(is_dir()) result=checkdir(c_str()); else result=(filesize(c_str())>=0); #endif return result; } STD_string JDXfileName::get_basename_nosuffix() const { STD_string result(get_basename()); if(get_suffix()!="") return replaceStr(result,"."+get_suffix(),""); return result; } JDXfileName& JDXfileName::set_defaultdir(const STD_string& defdir) { STD_string dummystr; normalize(defdir, true, defaultdir, dummystr, dummystr, dummystr); return *this; } bool JDXfileName::parsevalstring (const STD_string& parstring) { normalize(parstring, dir, *this, dirname_cache, basename_cache, suffix_cache); return true; } void JDXfileName::normalize(const STD_string& fname, bool dir, STD_string& result, STD_string& result_dirname, STD_string& result_basename, STD_string& result_suffix) { Log odinlog("JDXfileName","normalize"); STD_string tmpstr(fname); // mutable copy // remove quotes tmpstr=replaceStr(tmpstr, "\"",""); tmpstr=replaceStr(tmpstr, "\'",""); // remove preceeding blanks int beginpos=textbegin(tmpstr,0); if(beginpos<0) beginpos=0; tmpstr=tmpstr.substr(beginpos,tmpstr.length()-beginpos); // check whether we have absolute or relative path bool abspath=false; STD_string drive; #ifdef USING_WIN32 // replace slashes that are left on Windows tmpstr=replaceStr(tmpstr,"/",SEPARATOR_STR); if(tmpstr.length()>=2 && (tmpstr[1]==':') ) { drive=STD_string(1,tmpstr[0])+":"; // store tmpstr=tmpstr.substr(2,tmpstr.length()-2); // and strip off drive letter abspath=true; // accept drive-letter notation } #endif if(tmpstr.length()>=1 && (tmpstr[0]==SEPARATOR_CHAR) ) abspath=true; ODINLOG(odinlog,normalDebug) << "tmpstr/abspath=>" << tmpstr << "1) result_suffix=tolowerstr(sufftoks[sufftoks.size()-1]); } if(dir) result_suffix=""; // No suffix for dirs // set defaults result=drive; result_dirname=drive; result_basename=""; if(!abspath && (ntoks==1)) result_dirname="."; // File is in PWD // Recompose path and store dirname/basename if(ntoks) { if(abspath) { result+=SEPARATOR_STR; result_dirname+=SEPARATOR_STR; } ODINLOG(odinlog,normalDebug) << "result/result_dirname(pre loop)=>" << result << "<>" << result_dirname << "<" << STD_endl; for(int i=0; i" << result << "<>" << result_dirname << "<" << STD_endl; } } #ifndef NO_UNIT_TEST class JDXfileNameTest : public UnitTest { public: JDXfileNameTest() : UnitTest("JDXfileName") {} private: bool check() const { Log odinlog(this,"check"); JDXfileName teststr1=STD_string("image.bmp"); STD_string expected="image.bmp"; STD_string printed=teststr1; if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::STD_string failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="bmp"; printed=teststr1.get_suffix(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_suffix()[from filename] failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="cpp"; teststr1.set_suffix(expected); printed=teststr1.get_suffix(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_suffix()[when set] failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } teststr1=STD_string(".bmp"); expected="bmp"; printed=teststr1.get_suffix(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_suffix()[empty basename] failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } teststr1=STD_string("//tmp///test"); expected=STD_string(SEPARATOR_STR)+"tmp"; printed=teststr1.get_dirname(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_dirname() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } teststr1=STD_string("subdir///file"); expected="subdir"+STD_string(SEPARATOR_STR)+"file"; printed=teststr1; if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::STD_string failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="file"; printed=teststr1.get_basename(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_basename() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } expected="subdir"; printed=teststr1.get_dirname(); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName::get_dirname() failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } #ifdef USING_WIN32 teststr1=STD_string("C:"); expected="C:"; printed=STD_string(teststr1); if(printed!=expected) { ODINLOG(odinlog,errorLog) << "JDXfileName(WIN32): failed: got >" << printed << "<, but expected >" << expected << "<" << STD_endl; return false; } #endif return true; } }; void alloc_JDXfileNameTest() {new JDXfileNameTest();} // create test instance #endif /////////////////////////////////////////////////////////////// JDXformula::JDXformula(const STD_string& formula, const STD_string& name, bool userParameter, compatMode mode, parameterMode parameter_mode) : JDXstring(formula,name,userParameter,mode,parameter_mode) { } JDXformula& JDXformula::operator = (const JDXformula& jf) { JDXstring::operator = (jf); syntax = jf.syntax; return *this; } odin-1.8.5/odinpara/odinpara.h0000644000175000017500000000443111322062340013135 00000000000000/*************************************************************************** odinpara.h - description ------------------- begin : Tue Jun 28 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINPARA_H #define ODINPARA_H /** * @addtogroup odinpara * @{ */ /** * @ingroup odinpara * This enum is used to specify directions in the coordinate system * of the sequence gradients, i.e. gradient channel: * - readDirection: The first gradient channel * - phaseDirection: The second gradient channel * - sliceDirection: The third gradient channel */ enum direction { readDirection=0, phaseDirection, sliceDirection, n_directions}; static const char* directionLabel[]={"readDirection", "phaseDirection","sliceDirection"}; /** * Enum for the direction of spatial axes in the laboratory system of reference: * - xAxis: The first spatial direction * - yAxis: The second spatial direction * - zAxis: The third spatial direction */ enum axis {xAxis=0,yAxis,zAxis,n_axes}; // Units within ODIN #define ODIN_TIME_UNIT "ms" #define ODIN_FREQ_UNIT "kHz" #define ODIN_SPAT_UNIT "mm" #define ODIN_FIELD_UNIT "mT" #define ODIN_GRAD_UNIT "mT/mm" #define ODIN_ANGLE_UNIT "deg" // some common stuff for geometry and sample #define ODIN_DEFAULT_FOV 220.0 #define ODIN_MAX_NUMOF_SLICES 50 #define ODIN_GEO_CHECK_LIMIT 1e-6 // for debugging odinpara component class Para { public: static const char* get_compName(); }; /** @} */ #endif odin-1.8.5/odinpara/sample.cpp0000644000175000017500000002112411455553536013175 00000000000000#include "sample.h" Sample::Sample(const STD_string& label, bool uniformFOV, bool uniformT1T2) : JcampDxBlock(label) { uniFOV=uniformFOV; uniT1T2=uniformT1T2; resize(1,1,1,1,1); FOVall=20.0; FOVall.set_minmaxval(0.0,ODIN_DEFAULT_FOV).set_unit(ODIN_SPAT_UNIT).set_description("Uniform Field-Of-View (spatial extent) in all spatial dimensions"); FOV[xAxis]=20.0; FOV[yAxis]=20.0; FOV[zAxis]=20.0; FOV.set_unit(ODIN_SPAT_UNIT).set_description("Spatial extent"); offset.set_unit(ODIN_SPAT_UNIT).set_description("Spatial offset"); freqrange=10.0; freqrange.set_minmaxval(0.0,50.0).set_unit(ODIN_FREQ_UNIT).set_description("Extent in frequency dimension"); freqoffset=0.0; freqoffset.set_minmaxval(-100.0,100.0).set_unit(ODIN_FREQ_UNIT).set_description("Frequency offset"); frameDurations.set_parmode(hidden).set_unit(ODIN_TIME_UNIT).set_description("Time intervals to cycle through frames periodically"); T1=0.0; T1.set_minmaxval(0.0,2000.0).set_unit(ODIN_TIME_UNIT).set_description("Uniform longitudinal relaxation constant"); T2=0.0; T2.set_minmaxval(0.0,500.0).set_unit(ODIN_TIME_UNIT).set_description("Uniform transverse relaxation constant"); T1map.set_filemode(compressed).set_parmode(hidden).set_description("Longitudinal relaxation constant as a function of position, frequency and time frame"); T2map.set_filemode(compressed).set_parmode(hidden).set_description("Transverse relaxation constant as a function of position, frequency and time frame"); ppmMap.set_filemode(compressed).set_parmode(hidden).set_description("Frequency offset as a function of position, frequency and time frame"); spinDensity.set_filemode(compressed).set_parmode(hidden).set_description("Spin density as a function of position, frequency and time frame"); DcoeffMap.set_filemode(compressed).set_parmode(hidden).set_description("Diffusion coefficient as a function of position, frequency and time frame"); Sample::append_all_members(); } Sample::Sample(const Sample& ss) { Sample::operator = (ss); } Sample& Sample::operator = (const Sample& ss) { JcampDxBlock::operator = (ss); FOVall=ss.FOVall; FOV=ss.FOV; uniFOV=ss.uniFOV; offset=ss.offset; freqrange=ss.freqrange; freqoffset=ss.freqoffset; frameDurations=ss.frameDurations; uniT1T2=ss.uniT1T2; T1=ss.T1; T2=ss.T2; T1map=ss.T1map; T2map=ss.T2map; haveT1map=ss.haveT1map; haveT2map=ss.haveT2map; ppmMap=ss.ppmMap; have_ppmMap=ss.have_ppmMap; spinDensity=ss.spinDensity; DcoeffMap=ss.DcoeffMap; have_DcoeffMap=ss.have_DcoeffMap; Sample::append_all_members(); return *this; } Sample& Sample::set_FOV(float fov) { FOVall=fov; FOV.farray::operator = (fov); uniFOV=true; return *this; } Sample& Sample::set_FOV(axis direction, float fov) { FOV[direction]=fov; uniFOV=false; return *this; } float Sample::get_FOV(axis direction) const { if(uniFOV) return FOVall; return FOV[direction]; } Sample& Sample::resize(unsigned int framesize, unsigned int freqsize, unsigned int zsize, unsigned int ysize, unsigned int xsize) { Log odinlog(this,"resize"); haveT1map=false; haveT2map=false; have_ppmMap=false; have_DcoeffMap=false; ndim newsize(n_sampleDim); newsize[frameDim]=framesize; newsize[freqDim]=freqsize; newsize[zDim]=zsize; newsize[yDim]=ysize; newsize[xDim]=xsize; ODINLOG(odinlog,normalDebug) << "newsize=" << newsize << STD_endl; ODINLOG(odinlog,normalDebug) << "spinDensity.get_extent()=" << spinDensity.get_extent() << STD_endl; // leave spinDensity untouched if it has already the right size (required for load) if(newsize!=spinDensity.get_extent()) { ODINLOG(odinlog,normalDebug) << "resizing" << STD_endl; spinDensity.redim (newsize); spinDensity.farray::operator = (1.0); } ODINLOG(odinlog,normalDebug) << "extent=" << get_extent() << STD_endl; return *this; } bool Sample::check_and_correct(const char* mapname, const farray& srcmap, farray& dstmap) { Log odinlog(this,"check_and_correct"); ndim nn_map=srcmap.get_extent(); unsigned int n_sampleDim_old=n_sampleDim-1; // for backwards compatability if(nn_map.dim()!=n_sampleDim && nn_map.dim()!=n_sampleDim_old) { ODINLOG(odinlog,normalDebug) << "Map " << mapname << " has incorrect shape size=" << nn_map.dim() << STD_endl; return false; } bool reshape=false; if(nn_map.dim()==n_sampleDim_old) { ODINLOG(odinlog,warningLog) << "Reshaping map " << mapname << " for backwards compatability" << STD_endl; nn_map.add_dim(1,true); reshape=true; } ndim nn=get_extent(); nn[frameDim]=nn_map[frameDim]=1; // ignore size of frame dim if(nn!=nn_map) { ODINLOG(odinlog,errorLog) << "Map " << mapname << " has incorrect shape " << nn_map << STD_endl; return false; } dstmap=srcmap; if(reshape) dstmap.redim(nn_map); return true; } Sample& Sample::set_T1map(const farray& t1map) { if(uniT1T2) return *this; if(!check_and_correct("T1",t1map,T1map)) return *this; haveT1map=true; return *this; } const farray& Sample::get_T1map() const { if(!haveT1map) { T1map.redim(get_extent()); T1map.farray::operator = (T1); haveT1map=true; } return T1map; } Sample& Sample::set_T2map(const farray& t2map) { if(uniT1T2) return *this; if(!check_and_correct("T2",t2map,T2map)) return *this; haveT2map=true; return *this; } const farray& Sample::get_T2map() const { if(!haveT2map) { T2map.redim(get_extent()); T2map.farray::operator = (T2); haveT2map=true; } return T2map; } Sample& Sample::set_ppmMap(const farray& ppmmap) { if(!check_and_correct("ppmMap",ppmmap,ppmMap)) return *this; have_ppmMap=true; return *this; } const farray& Sample::get_ppmMap() const { Log odinlog(this,"get_ppmMap"); ODINLOG(odinlog,normalDebug) << "get_extent()=" << get_extent() << STD_endl; if(!have_ppmMap) { ODINLOG(odinlog,normalDebug) << "Creating zero ppmMap" << STD_endl; ppmMap.redim(get_extent()); ppmMap.farray::operator = (0.0); have_ppmMap=true; } ODINLOG(odinlog,normalDebug) << "ppmMap.get_extent()=" << ppmMap.get_extent() << STD_endl; return ppmMap; } Sample& Sample::set_spinDensity(const farray& sd) { if(!check_and_correct("spinDensity",sd,spinDensity)) return *this; return *this; } const farray& Sample::get_spinDensity() const { return spinDensity; } Sample& Sample::set_DcoeffMap(const farray& dmap) { if(!check_and_correct("Dcoeff",dmap,DcoeffMap)) return *this; have_DcoeffMap=true; return *this; } const farray& Sample::get_DcoeffMap() const { if(!have_DcoeffMap) { DcoeffMap.redim(get_extent()); DcoeffMap.farray::operator = (0.0); have_DcoeffMap=true; } return DcoeffMap; } Sample& Sample::update() { // outdate cache in interactive mode if(uniT1T2) { haveT1map=false; haveT2map=false; } if(T1!=0.0 || T2!=0.0) { if(T1>0.0 && T2>T1) T2=double(T1); } return *this; } int Sample::load(const STD_string& filename) { Log odinlog(this,"load"); int errval=JcampDxBlock::load(filename); ndim nn=spinDensity.get_extent(); if(nn.dim()==(n_sampleDim-1)) { ODINLOG(odinlog,normalDebug) << "Reshaping map for backwards compatability" << STD_endl; nn.add_dim(1,true); spinDensity.redim(nn); } ODINLOG(odinlog,normalDebug) << "nn=" << nn << STD_endl; ODINLOG(odinlog,normalDebug) << "spinDensity.sum()=" << spinDensity.sum() << STD_endl; if(nn.dim()!=n_sampleDim || nn.total()==0) { ODINLOG(odinlog,errorLog) << "spinDensity has invalid extent=" << STD_string(nn) << STD_endl; return -1; } uniFOV=false; uniT1T2=false; ODINLOG(odinlog,normalDebug) << "resizing to " << STD_string(nn) << STD_endl; resize(nn[frameDim],nn[freqDim],nn[zDim],nn[yDim],nn[xDim]); ODINLOG(odinlog,normalDebug) << "ppmMap.get_extent()=" << STD_string(ppmMap.get_extent()) << STD_endl; haveT1map=check_and_correct("T1",T1map,T1map); haveT2map=check_and_correct("T2",T2map,T2map); have_ppmMap=check_and_correct("ppmMap",ppmMap,ppmMap); have_DcoeffMap=check_and_correct("Dcoeff",DcoeffMap,DcoeffMap); ODINLOG(odinlog,normalDebug) << "have_ppmMap=" << have_ppmMap << STD_endl; return errval; } int Sample::append_all_members() { if(uniFOV) { append_member(FOVall,"FOVall"); } else { append_member(FOV,"FOV"); } append_member(freqrange,"FrequencyRange"); append_member(freqoffset,"FrequencyOffset"); append_member(frameDurations,"FrameDurations"); append_member(T1,"RelaxationT1"); append_member(T2,"RelaxationT2"); append_member(T1map,"T1map"); append_member(T2map,"T2map"); append_member(ppmMap,"ppmMap"); append_member(spinDensity,"spinDensity"); append_member(DcoeffMap,"DcoeffMap"); return 0; } odin-1.8.5/odinpara/study.h0000644000175000017500000000766011322062341012520 00000000000000/*************************************************************************** study.h - description ------------------- begin : Mon Mar 3 2003 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef STUDY_H #define STUDY_H #include #include #include #define ODIN_DATE_LENGTH 8 #define ODIN_DATE_FORMAT "%Y%m%d" #define ODIN_TIME_LENGTH 6 #define ODIN_TIME_FORMAT "%H%M%S" /** * @ingroup odinpara * * \brief Study information * * This class is used to hold study information */ class Study : public JcampDxBlock { public: /** * Constructs a Study object with the given label */ Study(const STD_string& label="unnamedStudy"); /** * Constructs a copy of 'sp' */ Study(const Study& s); /** * Specifies the date/time of the scan: * -date: date in DICOM format, i.e yyyymmdd * -time: date in DICOM format, i.e hhmmss */ Study& set_DateTime(const STD_string& date, const STD_string& time); /** * Returns the date/time of the scan in the reference parameters, see set_DateTime() for their description */ void get_DateTime(STD_string& date, STD_string& time) const; /** * Set date/time of the scan to the current date/time */ void set_timestamp(); /** * Specifies the patient information: * -id: The unique ID of the patient * -full_name: Patients full name * -birth_date: Patients date of birth in DICOM format, i.e yyyymmdd * -sex: Patients sex (M,F,O) * -weight: Patients weight [kg] */ Study& set_Patient(const STD_string& id, const STD_string& full_name, const STD_string& birth_date, char sex, float weight); /** * Returns the patient information in the reference parameters, see set_Patient() for their description */ void get_Patient(STD_string& id, STD_string& full_name, STD_string& birth_date, char& sex, float& weight) const; /** * Specifies the study context: * -description: Study description * -scientist: Scientists name */ Study& set_Context(const STD_string& description, const STD_string& scientist); /** * Returns the study context in the reference parameters, see set_Context() for their description */ void get_Context(STD_string& description, STD_string& scientist) const; /** * Specifies the series context: * -description: Series description * -number: Series number */ Study& set_Series(const STD_string& description, int number); /** * Returns the series context in the reference parameters, see set_Series() for their description */ void get_Series(STD_string& description, int& number) const; /** * Assignment operator */ Study& operator = (const Study& s); private: void append_all_members(); static void format_date(STD_string& result, const STD_string& date); static void format_time(STD_string& result, const STD_string& time); JDXstring ScanDate; JDXstring ScanTime; JDXstring PatientId; JDXstring PatientName; JDXstring PatientBirthDate; JDXenum PatientSex; JDXfloat PatientWeight; JDXstring Description; JDXstring ScientistName; JDXstring SeriesDescription; JDXint SeriesNumber; }; #endif odin-1.8.5/odinpara/jdxbase.cpp0000644000175000017500000000736011322062341013320 00000000000000#include "jdxbase.h" #include "jdxtypes.h" #include "jdxblock.h" #include const char* JcampDx::get_compName() {return "JDX";} LOGGROUNDWORK(JcampDx) ///////////////////////////////////////////////// ArrayScale::ArrayScale(const STD_string& scalelabel, const STD_string& scaleunit, float scalemin, float scalemax) : label(scalelabel), unit(scaleunit), minval(scalemin), maxval(scalemax) { } STD_string ArrayScale::get_label_with_unit() const { STD_string result(label); if(unit!="") result+=" ["+unit+"]"; return result; } ///////////////////////////////////////////////// void PixmapProps::get_overlay_range(float& min, float& max) const { min=overlay_minval; max=overlay_maxval; if(overlay_minval==0.0 && overlay_maxval==0.0) { min=overlay_map.minvalue(); max=overlay_map.maxvalue(); } } ///////////////////////////////////////////////// JcampDxClass::JcampDxClass () : compatmode(notBroken), userDefParameter(true), parmode(edit), filemode(include), id(-1) { } JcampDxClass::JcampDxClass(const JcampDxClass& jdc) : id(-1) { JcampDxClass::operator = (jdc); } JcampDxClass::~JcampDxClass() { // for some reason, making this virtual destructor inline on GCC4, causes a crash ... Log odinlog(this,"~JcampDxClass"); ODINLOG(odinlog,normalDebug) << "called" << STD_endl; } JcampDxClass& JcampDxClass::operator = (const JcampDxClass& jdc) { Log odinlog(this,"JcampDxClass::operator = "); ListItem::operator = (jdc); Labeled::operator = (jdc); compatmode=jdc.compatmode; userDefParameter=jdc.userDefParameter; parmode=jdc.parmode; filemode=jdc.filemode; description=jdc.description; unit=jdc.unit; cmdline_option=jdc.cmdline_option; return *this; } STD_string JcampDxClass::print() const { if(get_filemode()==exclude) return ""; return get_jdx_prefix()+printvalstring()+get_jdx_postfix(); } STD_string JcampDxClass::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN STD_string result; if(type==parx_passval) result=equiv.name+"="+get_label()+";\n"; return result; #else return ""; #endif } STD_string JcampDxClass::get_parx_def_string(const STD_string type, unsigned int dim) const { #ifdef PARAVISION_PLUGIN STD_string retstring; STD_string typelabel(type); if(typelabel.find("bit")!=STD_string::npos) typelabel="int"; retstring+=typelabel + " parameter {\n"; retstring+=" display_name \""+STD_string(get_label())+ "\";\n"; // retstring+=" relations method_relations;\n"; retstring+="} "+STD_string(get_label()); retstring+=n_times("[]",dim); retstring+=";\n\n\n"; return retstring; #else return ""; #endif } bool JcampDxClass::parse(STD_string& parstring) { Log odinlog(this,"parse"); if(parstring.find("\n##")==STD_string::npos) parstring+="\n##"; // make sure we have a trailing ## STD_string stringdummy="##"+extract(parstring,"##","\n##"); // extract string between two ## stringdummy=rmblock(stringdummy,"##","=",true,true,false,false); // remove line with label bool result=parsevalstring(stringdummy); // pass string to underlying data type parstring=rmblock(parstring,"##","##",true,false,false,false); // remove me from parstring return result; } int JcampDxClass::load(const STD_string& filename) { JcampDxBlock block; block.append(*this); return block.load(filename); } int JcampDxClass::write(const STD_string &filename) const { JcampDxClass* cc=create_copy(); JcampDxBlock block; block.append(*cc); int retval=block.write(filename); delete cc; return retval; } STD_string JcampDxClass::get_jdx_prefix() const { STD_string result("##"); if(isUserDefParameter()) result+="$"; result+=get_label(); result+="="; return result; } odin-1.8.5/odinpara/jdxblock.h0000644000175000017500000001672411322062341013151 00000000000000/*************************************************************************** jdxblock.h - description ------------------- begin : Sun Jun 6 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXBLOCK_H #define JDXBLOCK_H #include #include #include #include /** * @addtogroup jcampdx * @{ */ typedef List JDXList; // alias /** * * This class represents a block of parameters. Parameters can be * added or removed from the list of parameters within the block. * The whole block may be written to or read from a file. */ class JcampDxBlock : public virtual JcampDxClass, public JDXList, public StaticHandler { public: /** * * Constructs an empty block of parameters with the label 'title' and the specified mode */ JcampDxBlock(const STD_string& title="Parameter List",compatMode mode=notBroken); /** * * Copy constructor */ JcampDxBlock(const JcampDxBlock& block); /** * * Destructor */ ~JcampDxBlock(); /** * * Assignment operator */ JcampDxBlock& operator = (const JcampDxBlock& block); /** * * Merges all parameters found in the specified 'block' into this block */ JcampDxBlock& merge(JcampDxBlock& block, bool onlyUserPars=true); /** * * Removes all parameters found in the specified 'block' from this block */ JcampDxBlock& unmerge(JcampDxBlock& block); /** * * Print the value of the parameter that has the label 'parameterName' as a formated string */ STD_string printval(const STD_string& parameterName) const; /** * * Set the value of the parameter that has the label 'parameterName' to 'value'. * Returns 'true' if sucessful. */ bool parseval(const STD_string& parameterName, const STD_string& value); /** * * Parse values of thius block from the string 'src' in JCAMP-DX format, * returns the number of parameters sucessfully parsed. */ int parseblock(const STD_string& source); /** * * Returns the current number of parameters in the block */ unsigned int numof_pars() const; /** * Returns a pointer to parameter 'label', or zero if not found */ JcampDxClass* get_parameter(const STD_string& ldrlabel); /** * * Returns true if a parameter with the given label already exists * in the block */ bool parameter_exists(const STD_string& ldrlabel) const; /** * * Prefixes all parameters labels with the given string. If the prefix * is already at the beginning of the label, it is not added again. */ JcampDxBlock& set_prefix(const STD_string& prefix); /** * * If embedded is true, the block's widget will be displayed in a subwidget * otherwise an 'Edit' button that will open a subdialog is generated */ JcampDxBlock& set_embedded(bool embedded) {embed=embedded; return *this;} /** * * Returns whether the block's widget will be displayed in a subwidget * or an 'Edit' button that will open a subdialog is generated */ bool is_embedded() const {return embed;} /** * Returns the i'th parameter in the block */ JcampDxClass& operator [] (unsigned int i); /** * Returns the const i'th parameter in the block */ const JcampDxClass& operator [] (unsigned int i) const; /** * Returns the first parameter in the block with the given 'id' */ JcampDxClass& get_parameter_by_id(int id); /** * Makes this become a copy of 'src', including its parameters by creating temporary objects. * These temporary objects will be deleted automatically upon destruction. */ JcampDxBlock& create_copy(const JcampDxBlock& src); /** * Appends a deep copy of src (not a reference). * This copy will be deleted automatically upon destruction. */ JcampDxBlock& append_copy(const JcampDxClass& src); /** * Copy parameter values from 'src' to the equivalent parameters in this block */ JcampDxBlock& copy_ldr_vals(const JcampDxBlock& src); /** * Compares 'rhs' with 'this' with respect to whether all parameters with * the same label mutually exist in the other block * and whether these parameters have the same type, label and value. */ bool operator == (const JcampDxBlock& rhs) const {return !( ((*this)* exclude=0, double accuracy=0.0) const; #ifndef NO_CMDLINE JcampDxBlock& parse_cmdline_options(int argc, char *argv[], bool modify=true); STD_map get_cmdline_options() const; STD_string get_cmdline_usage(const STD_string& lineprefix="") const; #endif // functions for StaticHandler static void init_static(); static void destroy_static(); // overwriting virtual functions from JcampDxClass STD_string print() const; JcampDxClass& set_compatmode(compatMode compat_mode); JcampDxClass& set_parmode(parameterMode parameter_mode); JcampDxClass& set_filemode(fileMode file_mode); STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv=ParxEquiv()) const; STD_ostream& print2stream(STD_ostream& os) const; bool parsevalstring (const STD_string&) {return true;} bool parse(STD_string& parstring); STD_string printvalstring() const {return "";} JcampDxClass* create_copy() const {JcampDxBlock* result=new JcampDxBlock; result->create_copy(*this); return result;} const char* get_typeInfo() const {return "JcampDxBlock";} JcampDxBlock* cast(JcampDxBlock*) {return this;} int load(const STD_string &filename); int write(const STD_string &filename) const; STD_string get_jdx_prefix() const {return "";} STD_string get_jdx_postfix() const {return "";} protected: /** * * Use this functions to append members of derived classes */ JcampDxBlock& append_member(JcampDxClass& ldr,const STD_string ldrlabel=""); private: friend class JDXwidget; static STD_string extract_parlabel(const STD_string& parstring); STD_string print_header() const; STD_string print_tail() const; JDXList::constiter ldr_exists(const STD_string& label) const; int parse_ldr_list(STD_string& parstring); STD_list* garbage; bool embed; }; /** @} */ #endif odin-1.8.5/odinpara/study.cpp0000644000175000017500000001215011322062341013041 00000000000000#include "study.h" #include // for current date/time #ifdef HAVE_TIME_H #include #endif void Study::format_date(STD_string& result, const STD_string& date) { Log odinlog("Study","format_date"); if(date.length()!=ODIN_DATE_LENGTH) { ODINLOG(odinlog,warningLog) << "Wrong length of date string >" << date << "<" << STD_endl; return; } // Parsing date/time manually since strptime is not available on all platforms (MinGW) result=itos(atoi(date.substr(0,4).c_str()),9999) + itos(atoi(date.substr(4,2).c_str()),12) + itos(atoi(date.substr(6,2).c_str()),31); } void Study::format_time(STD_string& result, const STD_string& time) { Log odinlog("Study","format_time"); if(time.length()!=ODIN_TIME_LENGTH) { ODINLOG(odinlog,warningLog) << "Wrong length of time string >" << time << "<" << STD_endl; return; } // Parsing date/time manually since strptime is not available on all platforms (MinGW) result=itos(atoi(time.substr(0,2).c_str()),24) + itos(atoi(time.substr(2,2).c_str()),60) + itos(atoi(time.substr(4,2).c_str()),60); } Study::Study(const STD_string& label) : JcampDxBlock(label) { set_timestamp(); // set current date/time ScanDate.set_cmdline_option("date").set_unit("yyyymmdd").set_description("Date of scan"); ScanTime.set_cmdline_option("time").set_unit("hhmmss").set_description("Time of scan"); PatientId="Unknown"; PatientId.set_cmdline_option("pid").set_description("Unique patient identifier"); PatientName="Unknown"; PatientName.set_cmdline_option("pname").set_description("Full patient name"); PatientBirthDate=STD_string(ODIN_DATE_LENGTH,'0'); PatientBirthDate.set_cmdline_option("pbirth").set_unit("yyyymmdd").set_description("Patients date of birth"); PatientSex.add_item("M"); PatientSex.add_item("F"); PatientSex.add_item("O"); PatientSex.set_cmdline_option("psex").set_description("Patients sex"); PatientWeight=50.0; PatientWeight.set_cmdline_option("pweight").set_unit("kg").set_description("Patients weight"); Description="Unknown"; Description.set_cmdline_option("stud").set_description("Study Description"); ScientistName="Unknown"; ScientistName.set_cmdline_option("scient").set_description("Scientist Name"); SeriesDescription="Unknown"; SeriesDescription.set_cmdline_option("serd").set_description("Series Description"); SeriesNumber=1; SeriesNumber.set_cmdline_option("serno").set_description("Series Number"); append_all_members(); } Study::Study(const Study& s) { Study::operator = (s); } Study& Study::operator = (const Study& s) { JcampDxBlock::operator = (s); append_all_members(); // copy only visible members of JcampDxBlock copy_ldr_vals(s); return *this; } Study& Study::set_DateTime(const STD_string& date, const STD_string& time) { format_date(ScanDate,date); format_time(ScanTime,time); return *this; } void Study::get_DateTime(STD_string& date, STD_string& time) const { date=ScanDate; time=ScanTime; } void Study::set_timestamp() { ScanDate=STD_string(ODIN_DATE_LENGTH,'0'); ScanTime=STD_string(ODIN_TIME_LENGTH,'0'); #if defined(HAVE_TIME_H) && defined(HAVE_STRFTIME) time_t tt=time(NULL); char datebuff[ODIN_DATE_LENGTH+1]; if(strftime(datebuff, ODIN_DATE_LENGTH+1, ODIN_DATE_FORMAT, localtime(&tt))) ScanDate=datebuff; char timebuff[ODIN_TIME_LENGTH+1]; if(strftime(timebuff, ODIN_TIME_LENGTH+1, ODIN_TIME_FORMAT, localtime(&tt))) ScanTime=timebuff; #endif } Study& Study::set_Patient(const STD_string& id, const STD_string& full_name, const STD_string& birth_date, char sex, float weight) { PatientId=id; PatientName=full_name; format_date(PatientBirthDate,birth_date); PatientSex=STD_string(1,toupper(sex)); PatientWeight=weight; return *this; } void Study::get_Patient(STD_string& id, STD_string& full_name, STD_string& birth_date, char& sex, float& weight) const { id=PatientId; full_name=PatientName; birth_date=PatientBirthDate; sex=PatientSex.JDXenum::operator STD_string()[0]; weight=PatientWeight; } Study& Study::set_Context(const STD_string& description, const STD_string& scientist) { Description=description; ScientistName=scientist; return *this; } void Study::get_Context(STD_string& description, STD_string& scientist) const { description=Description; scientist=ScientistName; } Study& Study::set_Series(const STD_string& description, int number) { SeriesDescription=description; SeriesNumber=number; return *this; } void Study::get_Series(STD_string& description, int& number) const { description=SeriesDescription; number=SeriesNumber; } void Study::append_all_members() { JcampDxBlock::clear(); append_member(ScanDate,"ScanDate"); append_member(ScanTime,"ScanTime"); append_member(PatientId,"PatientId"); append_member(PatientName,"PatientName"); append_member(PatientBirthDate,"PatientBirthDate"); append_member(PatientSex,"PatientSex"); append_member(PatientWeight,"PatientWeight"); append_member(Description,"Description"); append_member(ScientistName,"ScientistName"); append_member(SeriesDescription,"SeriesDescription"); append_member(SeriesNumber,"SeriesNumber"); } odin-1.8.5/odinpara/Makefile.am0000644000175000017500000000162511322062341013226 00000000000000 INCLUDES = $(all_includes) lib_LTLIBRARIES = libodinpara.la libodinpara_la_LDFLAGS = -no-undefined -release $(VERSION) libodinpara_la_LIBADD = ../tjutils/libtjutils.la library_includedir=$(includedir)/odinpara library_include_HEADERS = \ jdxarrays.h \ jdxbase.h \ jdxblock.h \ jdxfilter.h \ jdxfunction.h \ jdxnumbers.h \ jdxtypes.h \ odinpara.h \ protocol.h \ geometry.h \ reco.h \ sample.h \ seqpars.h \ study.h \ system.h libodinpara_la_SOURCES = \ jdxarrays.h jdxarrays.cpp \ jdxbase.h jdxbase.cpp \ jdxblock.h jdxblock.cpp \ jdxfilter.h jdxfilter.cpp \ jdxfunction.h jdxfunction.cpp \ jdxnumbers.h jdxnumbers.cpp \ jdxtypes.h jdxtypes.cpp \ odinpara.h odinpara.cpp \ protocol.h protocol.cpp \ geometry.h geometry.cpp \ reco.h reco.cpp \ sample.h sample.cpp \ seqpars.h seqpars.cpp \ study.h study.cpp \ system.h system.cpp odin-1.8.5/odinpara/Makefile.in0000644000175000017500000004765211734622602013262 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ subdir = odinpara DIST_COMMON = $(library_include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" \ "$(DESTDIR)$(library_includedir)" LTLIBRARIES = $(lib_LTLIBRARIES) libodinpara_la_DEPENDENCIES = ../tjutils/libtjutils.la am_libodinpara_la_OBJECTS = jdxarrays.lo jdxbase.lo jdxblock.lo \ jdxfilter.lo jdxfunction.lo jdxnumbers.lo jdxtypes.lo \ odinpara.lo protocol.lo geometry.lo reco.lo sample.lo \ seqpars.lo study.lo system.lo libodinpara_la_OBJECTS = $(am_libodinpara_la_OBJECTS) libodinpara_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(libodinpara_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(libodinpara_la_SOURCES) DIST_SOURCES = $(libodinpara_la_SOURCES) HEADERS = $(library_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ INCLUDES = $(all_includes) lib_LTLIBRARIES = libodinpara.la libodinpara_la_LDFLAGS = -no-undefined -release $(VERSION) libodinpara_la_LIBADD = ../tjutils/libtjutils.la library_includedir = $(includedir)/odinpara library_include_HEADERS = \ jdxarrays.h \ jdxbase.h \ jdxblock.h \ jdxfilter.h \ jdxfunction.h \ jdxnumbers.h \ jdxtypes.h \ odinpara.h \ protocol.h \ geometry.h \ reco.h \ sample.h \ seqpars.h \ study.h \ system.h libodinpara_la_SOURCES = \ jdxarrays.h jdxarrays.cpp \ jdxbase.h jdxbase.cpp \ jdxblock.h jdxblock.cpp \ jdxfilter.h jdxfilter.cpp \ jdxfunction.h jdxfunction.cpp \ jdxnumbers.h jdxnumbers.cpp \ jdxtypes.h jdxtypes.cpp \ odinpara.h odinpara.cpp \ protocol.h protocol.cpp \ geometry.h geometry.cpp \ reco.h reco.cpp \ sample.h sample.cpp \ seqpars.h seqpars.cpp \ study.h study.cpp \ system.h system.cpp all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu odinpara/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu odinpara/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ list2=; for p in $$list; do \ if test -f $$p; then \ list2="$$list2 $$p"; \ else :; fi; \ done; \ test -z "$$list2" || { \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ for p in $$list; do \ $(am__strip_dir) \ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done libodinpara.la: $(libodinpara_la_OBJECTS) $(libodinpara_la_DEPENDENCIES) $(libodinpara_la_LINK) -rpath $(libdir) $(libodinpara_la_OBJECTS) $(libodinpara_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/geometry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxarrays.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxbase.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxblock.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxfilter.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxfunction.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxnumbers.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jdxtypes.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinpara.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/protocol.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reco.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sample.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seqpars.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/study.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/system.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-library_includeHEADERS: $(library_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(library_includedir)" || $(MKDIR_P) "$(DESTDIR)$(library_includedir)" @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; \ done | $(am__base_list) | \ while read files; do \ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(library_includedir)'"; \ $(INSTALL_HEADER) $$files "$(DESTDIR)$(library_includedir)" || exit $$?; \ done uninstall-library_includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ test -n "$$files" || exit 0; \ echo " ( cd '$(DESTDIR)$(library_includedir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(library_includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(LTLIBRARIES) $(HEADERS) installdirs: for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(library_includedir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-library_includeHEADERS install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-libLTLIBRARIES install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-data install-data-am install-dvi \ install-dvi-am install-exec install-exec-am install-html \ install-html-am install-info install-info-am \ install-libLTLIBRARIES install-library_includeHEADERS \ install-man install-pdf install-pdf-am install-ps \ install-ps-am install-strip installcheck installcheck-am \ installdirs maintainer-clean maintainer-clean-generic \ mostlyclean mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \ uninstall-am uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odinpara/protocol.cpp0000644000175000017500000000642011665172216013552 00000000000000#include "protocol.h" #include Protocol::Protocol(const STD_string& label) : JcampDxBlock(label), system(label+"_system"), geometry(label+"_geometry"), seqpars(label+"_seqpars"), methpars(label+"_methpars"), study(label+"_study") { append_all_members(); } Protocol& Protocol::operator = (const Protocol& p) { JcampDxBlock::operator = (p); system=p.system; geometry=p.geometry; seqpars=p.seqpars; methpars.create_copy(p.methpars); study=p.study; append_all_members(); return *this; } bool Protocol::operator < (const Protocol& rhs) const { STD_list exclude; exclude.push_back("AcquisitionStart"); exclude.push_back("offsetSlice"); exclude.push_back("Datatype"); // account for different TRs in gated mode if(seqpars.get_PhysioTrigger() || rhs.seqpars.get_PhysioTrigger()) { exclude.push_back("PhysioTrigger"); exclude.push_back("RepetitionTime"); exclude.push_back("ExpDuration"); } double accuracy=0.01; // This will make geometries equal which are approximately the same return JcampDxBlock::compare(rhs,&exclude,accuracy); } void Protocol::append_all_members() { JcampDxBlock::clear(); merge(study); merge(system); merge(geometry); merge(seqpars); merge(methpars); } /////////////////////////////////////////////////////////////////////// #ifndef NO_UNIT_TEST class ProtocolTest : public UnitTest { public: ProtocolTest() : UnitTest("Protocol") {} private: bool check() const { Log odinlog(this,"check"); // Testing == operator (of JcampDxBlock) Protocol p1; Protocol p2; if(!(p1==p2)) { ODINLOG(odinlog,errorLog) << "Protocol::operator == (equal) failed: p1=" << p1 << "p2=" << p2 << STD_endl; return false; } p1.seqpars.set_AcquisitionStart(123); // should still be equal if(!(p1==p2)) { ODINLOG(odinlog,errorLog) << "Protocol::operator == (AcquisitionStart) failed: p1=" << p1 << "p2=" << p2 << STD_endl; return false; } p1.seqpars.set_RepetitionTime(12345); if(p1==p2) { ODINLOG(odinlog,errorLog) << "Protocol::operator == (unequal) failed: p1=" << p1 << "p2=" << p2 << STD_endl; return false; } if(p1cast(intdummy); if( !intdummy ) { ODINLOG(odinlog,errorLog) << "Protocol::operator = methpars.testint cannot be casted" << STD_endl; return false; } if( (*intdummy)!=7 ) { ODINLOG(odinlog,errorLog) << "Protocol::operator = intdummy=" << (*intdummy) << STD_endl; return false; } return true; } }; void alloc_ProtocolTest() {new ProtocolTest();} // create test instance #endif odin-1.8.5/odinpara/reco.h0000644000175000017500000004143211455553536012315 00000000000000/*************************************************************************** reco.h - Parameters for image reconstruction ------------------- begin : Thu May 06 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECO_H #define RECO_H #include #include /** * @addtogroup odinpara * @{ */ // some limits #define MAX_NUMOF_READOUT_SHAPES 10 #define MAX_NUMOF_KSPACE_TRAJS 10 #define MAX_NUMOF_ADC_WEIGHTING_VECTORS 10 #define PROTOCOL_BLOCK_LABEL "Protocol" /** * Flags(bits) to mark ADCs: * - recoLastInChunkBit: last ADC in a collection of consecutive ADCs generated by the system, an undefined number of zeroes may follow * - recoReflectBit: ADC is reflected * - recoEpiNavPolarityBit: Indicates that first echo in EPI navigator readout is reflected */ enum recoFlags { recoLastInChunkBit =1, recoReflectBit =2, recoEpiNavPolarityBit =4, recoAllBits =255 }; /////////////////////////////////////////////////////////// /** * Dimensions of acquired data, order is reversed for easy indexing of C-style arrays * - userdef: Extra dimension which can be used by the sequence programmer * - te: Echo-time index in a multi-echo acquistion, e.g. for field-map calculation * - dti: Direction index for diffusion-tensor imaging * - average: Average index to add up ADCs * - cycle: Cycle index (spiral imaging, PROPELLER blades) * - slice: Slice index * - line3d: 3D phase encoding index * - line: 2D phase encoding index * - echo: Echo index in a multi-echo readout, e.g. an CPMG or EPI echo train * - epi: Index of EPI readout train, e.g. in a 3D sequence * - templtype: Type of template prescan * - navigator: Type of navigator scan * - freq: Frequency offset (will be used by multi-frequency reconstruction in odinreco) * - channel: Channel index of phased-array coil * - readout: Readout index * - repetition: Repetition dimension * */ enum recoDim { userdef=0, te, dti, average, cycle, slice, line3d, line, echo, epi, templtype, navigator, freq, channel, readout, repetition, n_recoDims}; static const char* recoDimLabel[]={"userdef", "te","dti","average","cycle","slice","line3d","line","echo","epi","templtype","navigator","freq","channel","readout","repetition"}; static const int n_recoIndexDims=templtype+1; // only the first dims are required for indexing of ADCs, the remaining are used only by odinreco /////////////////////////////////////////////////////////// /** * * Enum to distinguish between different types of template prescan ADCs: * - no_template: Not a template ADC * - phasecorr_template: Template ADC for 1D phase correction * - fieldmap_template: Template to calculate fieldmap, the echo dimension will index the different TEs * - grappa_template: Training data to calculate GRAPPA weights */ enum templateType {no_template=0, phasecorr_template, fieldmap_template, grappa_template, n_templateTypes}; static const char templateTypeChar[]={'N', 'P', 'F', 'G'}; /////////////////////////////////////////////////////////// /** * * Enum to distinguish between different types of navigator ADCs: * - no_navigator: Not a navigator ADC * - epi_navigator: Siemens EPI phase correction navigator */ enum navigatorType {no_navigator=0, epi_navigator, n_navigatorTypes}; static const char navigatorTypeChar[]={'n', 'e'}; /////////////////////////////////////////////////////////// /** * * This struct holds the k-space position of one ADC */ struct kSpaceCoord { kSpaceCoord() {reset2defaults();} // for STD_list bool operator == (const kSpaceCoord& ri) const; bool operator < (const kSpaceCoord& ri) const; static int string2index(const STD_string& str, recoDim dim); static STD_string index2string(int index, recoDim dim, int numof=0); STD_string printcoord(const unsigned short* numof_cache) const; // friend STD_ostream& operator << (STD_ostream& s,const kSpaceCoord& kcoord) { return s << kcoord.printcoord();} bool parsecoord(const STD_string& str); void reset2defaults(); static STD_string print_header(const unsigned short* numof_cache); mutable unsigned int number; // unique index of the ADC unsigned int reps; // number of times this ADC is repeated unsigned short adcSize; // size with oversampling unsigned char channels; // coil channels unsigned short preDiscard; // points to discard at the beginning of an ADC unsigned short postDiscard; // points to discard at the end of an ADC unsigned short concat; // number of concatenated acquisition this ADC is composed of float oversampling; // oversampling factor float relcenter; // relative position of k-space center short readoutIndex; // index of the readout shape to be used for ramp-sampling correction, -1 if none short trajIndex; // index of the used k-space trajectory, -1 if none short weightIndex; // index of the used ADC weighting vector, -1 if none short dtIndex; // index of the dwell time used unsigned short index[n_recoIndexDims]; // multi-dimensional reco index to locate ADC in k-space unsigned char flags; // recoFlags private: friend class JDXkSpaceCoords; static void assign_parsepos(const STD_string& header); static int parsepos_number; static int parsepos_reps; static int parsepos_adcSize; static int parsepos_channels; static int parsepos_preDiscard; static int parsepos_postDiscard; static int parsepos_concat; static int parsepos_oversampling; static int parsepos_relcenter; static int parsepos_readoutIndex; static int parsepos_trajIndex; static int parsepos_weightIndex; static int parsepos_dtIndex; static int parsepos_index[n_recoIndexDims]; static int parsepos_lastinchunk; static int parsepos_reflect; static int max_parsepos; }; ////////////////////////////////////////////////////////////////////// /** * * This class holds the assignment of consecutive ADCs to k-space positions */ class JDXkSpaceCoords : public JcampDxClass { enum JDXkSpaceCoords_state {coords_in_list, has_vec_cache, has_vec_alloc}; public: JDXkSpaceCoords(); ~JDXkSpaceCoords() {clear();} unsigned int size() const {create_vec_cache(); return vec_cache.size();} const kSpaceCoord& operator [] (unsigned int i) const {create_vec_cache(); return *(vec_cache[i]);} void clear(); // clear list before retrieving k-space ordering from sequence JDXkSpaceCoords& append_coord(const kSpaceCoord& coord); private: friend class RecoPars; void create_vec_cache() const; // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; STD_ostream& print2stream(STD_ostream& os) const; const char* get_typeInfo() const {return "kSpaceCoords";} JcampDxClass* create_copy() const {return new JDXkSpaceCoords(*this);} mutable STD_list coordlist; mutable JDXkSpaceCoords_state state; mutable STD_vector vec_cache; // use pointers for better performance mutable unsigned short numof_cache[n_recoIndexDims]; }; ////////////////////////////////////////////////////////////////////// /** * * Structure to return ordering of k-space data while traversing the sequence tree */ struct RecoValList : public ValList { RecoValList(const STD_string& object_label="unnamedRecoValList", unsigned int repetitions=1) : ValList(object_label,repetitions) {} }; ////////////////////////////////////////////////////////////////////// /** * * This class holds the assignment of consecutive ADCs to k-space positions */ class JDXrecoValList : public RecoValList, public JcampDxClass { public: JDXrecoValList(const STD_string& ldrlabel="unnamedJDXrecoValList"); JDXrecoValList(const JDXrecoValList& jdrvl) {JDXrecoValList::operator = (jdrvl);} JDXrecoValList& operator = (const JDXrecoValList& jdrvl); JDXrecoValList& operator = (const RecoValList& rvl); // for assignment from get_recovallist in SeqMethod // overwriting virtual functions from JcampDxClass bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; STD_ostream& print2stream(STD_ostream& os) const; const char* get_typeInfo() const {return "RecoValList";} JcampDxClass* create_copy() const {return new JDXrecoValList(*this);} }; ////////////////////////////////////////////////////////////////////// /** * This class is used to hold all information about the reconstruction */ class RecoPars : public JcampDxBlock { public: /** * Constructs a RecoPars with the given label */ RecoPars(const STD_string& label="unnamedRecoPars"); /** * Constructs a copy of 'sr' */ RecoPars(const RecoPars& sr); /** * Assignment operator */ RecoPars& operator = (const RecoPars& sr); /** * Returns the scan protocol. */ const Protocol& get_protocol() const {return prot;} /** * Returns the const assignment of ADC indices to k-space lines (for odinreco) */ const JDXkSpaceCoords& get_kSpaceCoords() const {return kSpaceCoords;} /** * Returns the data type of the acquired ADCs */ const STD_string& get_DataFormat() const {return DataFormat;} /** * Returns whether the of the acquired ADCs is little endian */ bool is_LittleEndian() const {return LittleEndian;} /** * Returns the file name of raw data */ const STD_string& get_RawFile() const {return RawFile;} /** * Returns the header size of raw data */ unsigned int get_RawHeaderSize() const {return RawHeaderSize;} /** * Returns the relative offset which should be added by the reco */ const fvector& get_RelativeOffset() const {return RelativeOffset;} /** * Extra command-line arguments for processing of final images */ const STD_string& get_ImageProc() const {return ImageProc;} /** * Returns the value vector attached to reco dimension 'dim' */ const dvector& get_DimValues(recoDim dim) const {return DimValues[dim];} /** * Returns the scaling factors for ADC channels */ fvector get_ChannelScales() const {return ChannelScaling;} /** * Returns the i'th dwell time (including oversampling) */ double get_DwellTime(unsigned int i) const; /** * Returns the number of ADC chunks, a chunk is a collection of * one or more ADCs stored by the system in one block. It can be * followed by an arbitrary number of zeroes. */ int get_NumOfAdcChunks() const; /** * Attaches a vector 'vals' of values to each step in the given dimension 'dim' */ RecoPars& set_DimValues(recoDim dim, const dvector& vals); /** * Appends a new ADC readout-gradient shape and its target grid size. Returns its index */ int append_readout_shape(const fvector& shape, unsigned int dstsize); /** * Appends a new k-space trajectory and returns its index */ int append_kspace_traj(const farray& kspace_traj); /** * Appends a new ADC weighting vector and returns its index */ int append_adc_weight_vec(const cvector& weightvec); /** * Appends a new ADC dwell time (including oversampling) and returns its index */ int append_dwell_time(double dt); /** * Returns the i'th ADC readout-gradient and its target grid size */ void get_ReadoutShape(unsigned int i, fvector& shape, unsigned int& dstsize) const; /** * Returns the number of k-space trajectories */ unsigned int numof_kSpaceTraj() const; /** * Returns the i'th k-space trajectory */ const farray& get_kSpaceTraj(unsigned int i) const; /** * Returns the i'th complex weighting vector with which the corresponding ADCs will be multiplied */ const cvector& get_AdcWeightVector(unsigned int i) const; /** * Returns the total number of ADC samples, if 'discard' is set to 'true' * only the effective ADC size is returned, i.e. without 'preDiscard' and * 'postDiscard' */ LONGEST_INT get_TotalNumOfSamples(bool discard=false) const; /** * Returns the total number of ADCs */ unsigned int numof_adcs() const {return kSpaceOrdering.size();} /** * Returns the i'th ADC of the sequence */ const kSpaceCoord& get_kSpaceCoord(unsigned int i) const; /** * Set a string describing the reconstruction pipeline (chain of steps/functors). */ RecoPars& set_Recipe(const STD_string& recipe) {Recipe=recipe; return *this;} /** * Returns a string describing the reconstruction pipeline (chain of steps/functors). */ STD_string get_Recipe() const {return Recipe;} /** * The extra chain of reconstruction steps (functors) described by 'recipe' * wil be performed after 3D reconstruction (including channel combination) but * before data is stored on disk. */ RecoPars& set_PostProc3D(const STD_string& recipe) {PostProc3D=recipe; return *this;} /** * Returns the extra chain of reconstruction steps (functors) which will be * performed after 3D reconstruction (including channel combination) but before * data is stored on disk. */ STD_string get_PostProc3D() const {return PostProc3D;} /** * The extra chain of reconstruction steps (functors) described by 'recipe' * wil be performed after 3D FFT but before channel combination. */ RecoPars& set_PreProc3D(const STD_string& recipe) {PreProc3D=recipe; return *this;} /** * Returns the extra chain of reconstruction steps (functors) described by 'recipe' * wil be performed after 3D FFT but before channel combination. */ STD_string get_PreProc3D() const {return PreProc3D;} /** * Extra command-line options for the reco. */ RecoPars& set_CmdLineOpts(const STD_string& opts) {CmdLineOpts=opts; return *this;} /** * Returns the extra chain of reconstruction steps (functors) which will be * performed after 3D reconstruction before data is stored on disk. */ STD_string get_CmdLineOpts() const {return CmdLineOpts;} private: friend class SeqAcq; friend class SeqEpiDriverParavision; friend class SeqMethod; void common_init(); void reset(); void create_cache() const; void append_all_members(); Protocol prot; JDXstring DataFormat; JDXbool LittleEndian; JDXstring RawFile; JDXint RawHeaderSize; JDXtriple RelativeOffset; JDXstring ImageProc; JDXfloatArr ChannelScaling; JDXdoubleArr DwellTime; JDXfloatArr ReadoutShape[MAX_NUMOF_READOUT_SHAPES]; JDXintArr ReadoutDstSize; JDXfloatArr kSpaceTraj[MAX_NUMOF_KSPACE_TRAJS]; JDXcomplexArr AdcWeightVector[MAX_NUMOF_ADC_WEIGHTING_VECTORS]; JDXdoubleArr DimValues[n_recoIndexDims]; JDXstring Recipe; JDXstring PreProc3D; JDXstring PostProc3D; JDXstring CmdLineOpts; JDXkSpaceCoords kSpaceCoords; JDXrecoValList kSpaceOrdering; mutable STD_vector kSpaceOrdering_cache; // fast cache of ADC indices mutable bool cache_is_up2date; }; ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /** * Class to hold complex sensitivity */ class CoilSensitivity : public JcampDxBlock { public: /** * Constructs a CoilSensitivity with the given label */ CoilSensitivity(const STD_string& label="unnamedCoilSensitivity"); /** * Constructs a copy of 'cs' */ CoilSensitivity(const CoilSensitivity& cs); /** * Assignment operator */ CoilSensitivity& operator = (const CoilSensitivity& cs); /** * Accepts a 4-dim complex array 'sens_map' with the dimensions * (coil,z,y,x) and the corresponding FOVs */ CoilSensitivity& set_sensitivity_map(const carray& sens_map, float FOVx, float FOVy, float FOVz); /** * Returns complex sensitivity value for the given channel and spatial position, * uses trilinear interpolation */ STD_complex get_sensitivity_value(unsigned int channel, float x, float y, float z) const; /** * Returns the number of channels of the coil */ unsigned int get_numof_channels() const {return SensitivityMap.get_extent()[0];} private: void append_all_members(); JDXtriple FOV; JDXcomplexArr SensitivityMap; }; ////////////////////////////////////////////////////////////////////// /** @} */ #endif odin-1.8.5/odinpara/system.h0000644000175000017500000002321711712547771012712 00000000000000/*************************************************************************** system.h - description ------------------- begin : Wed Jun 29 2005 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef SYSTEM_H #define SYSTEM_H #include #include #include #include #include // defaults for systemInfo #define _DEFAULT_B0_ 3000 // 3 Tesla #define _DEFAULT_MAX_SYSTEM_GRADIENT_ 0.04 #define _DEFAULT_MAX_SYSTEM_SLEWRATE_ 0.2 /** * @ingroup odinpara * This enum is used to specify the scanner system type */ enum odinPlatform {standalone=0, paravision, numaris_4, epic, numof_platforms}; /** * @ingroup odinpara * This enum is used to distinguish different properties of sequence objects according to * their category. Examples are minimum duration or rastertime. */ enum objCategory {unknownObj=0,delayObj,pulsObj,gradObj,loopObj,acqObj,freqObj,syncObj,endObj}; ///////////////////////////////////////////////////////////////////////// /** * @ingroup odinpara * This class is a small database which maps nuclei names to gyromagnetic ratios. */ class Nuclei { public: Nuclei(); /** * Returns the gyromagnetic ratio of the nucleus with name 'nucName' */ double get_gamma(const STD_string& nucName) const; /** * Returns the base frequency of the nucleus with name 'nucName' in a static field with the strength 'B0' */ double get_nuc_freq(const STD_string& nucName,float B0) const; /** * Returns an enum with all registered nuclei as entries */ JDXenum get_nuc_enum() const; private: typedef STD_pair Nucleus; typedef STD_list NucList; // do not use std::map since we do not want unsorted list NucList nuclist; }; ///////////////////////////////////////////////////////////////////////// /** * @ingroup odinpara * * \brief System proxy * * This class is used to hold all information/configuration of the spectrometer */ class System : public JcampDxBlock { public: /** * Constructs a System with the given label */ System(const STD_string& object_label="unnamedSystem"); /** * Copy constructor */ System(const System& s) {System::operator = (s);} /** * Assignment operator */ System& operator = (const System& s); /** * Returns the platform identifier for the scanner, works only in the context of sequence programming */ odinPlatform get_platform() const; /** * Returns a string identifying the platform */ STD_string get_platform_str() const {return platformstr;} /** * Returns a string identifying the transmit coil */ STD_string get_transmit_coil_name() const {return transmit_coil_name;} /** * Sets the transmit coil name */ System& set_transmit_coil_name(const STD_string& tcname); /** * Returns the current main nucleus of the sequence, i.e. the nucleus for which both, excitation and acquisition, will be performed */ STD_string get_main_nucleus() const {return main_nucleus;} /** * Specifies the current main nucleus of the scanner, i.e. the nucleus for which both, excitation and acquisition, will be performed */ System& set_main_nucleus(const STD_string& nucname); /** * Returns the maximum gradient strength of the scanner */ float get_max_grad() const {return max_grad;} /** * Returns the maximum slew rate */ float get_max_slew_rate() const {return max_slew_rate;} /** * Returns the time required to change the gradient strength by the specified amount */ float get_grad_switch_time(float graddiff) const; /** * Returns the minimum time gap between two gradient commands */ float get_inter_grad_delay() const {return inter_grad_delay;} /** * Sets the directory where the experimental data files of the current scans are stored */ System& set_scandir(const STD_string& dir); /** * Returns the directory where the experimental data files of the current scans are stored */ STD_string get_scandir() const; /** * Returns the time shift between RF and gradient channel */ float get_grad_shift_delay() const {return grad_shift;} /** * Returns the field strength of the static magnetic field */ double get_B0() const {return B0;} /** * Returns the field strength of the static magnetic field */ System& set_B0(double b0) {B0=b0; return *this;} /** * Specifies the field strength of the static magnetic field by giving the resonance frequency * for the specified nucleus */ System& set_B0_from_freq(double freq, const STD_string& nucName=""); /** * Returns the gyromagnetic ratio of the given nucleus, default returns the ratio of protons */ double get_gamma(const STD_string& nucName="") const; /** * Sets the reference gain in dB */ System& set_reference_gain(float refgain); /** * Returns the reference gain in dB */ float get_reference_gain() const {return reference_gain;} /** * Returns the resonance for the given nucleus */ double get_nuc_freq(const STD_string& nucName="") const; /** * Returns an enum with all registered nuclei as entries */ JDXenum get_nuc_enum() const; /** * Returns the minimum duration for the given object category */ double get_min_duration(objCategory c) const {return min_duration[c];} /** * Returns the minimum gradient raster time */ double get_min_grad_rastertime() const {return min_grad_rastertime;} /** * Returns the raster time for the given object category, if no such time exists, it returns 0 */ double get_rastertime(objCategory cat) const; /** * Returns the rastered time for the given object type and non-rastered time point/period */ double get_rasteredtime(objCategory cat, double time) const; /** * Returns the maximum number of samples per RF pulse */ int get_max_rf_samples() const {return max_rf_samples;} /** * Returns the maximum number of samples per gradient waveform */ int get_max_grad_samples() const {return max_grad_samples;} /** * Sets the data represention type of the image data */ System& set_data_type(const STD_string& type) {datatype=type; return *this;} /** * Returns the data represention type of the image data */ STD_string get_data_type() const {return datatype;} /** * Returns 'true' if gradient switching frequency 'freq' does not cause * acoustic resonance, otherwise, 'low' and 'upp' will contain the next * possible lower and upper frequencies, respectively. */ bool allowed_grad_freq(double freq, double& low, double& upp) const; private: friend class SeqMethod; friend class SeqIdea; friend class SeqParavision; friend class SeqStandAlone; friend class SeqEpic; // overwriting virtual functions from JcampDxClass int load(const STD_string &filename); int append_all_members(); Nuclei nuc; JDXstring platformstr; JDXenum main_nucleus; JDXdouble max_grad; JDXdouble max_slew_rate; JDXdouble grad_shift; JDXdouble inter_grad_delay; JDXdouble B0; JDXdouble reference_gain; JDXstring transmit_coil_name; JDXdouble delay_rastertime; JDXdouble rf_rastertime; JDXdouble grad_rastertime; JDXdouble min_grad_rastertime; JDXdouble acq_rastertime; JDXint max_rf_samples; JDXint max_grad_samples; JDXstring datatype; JDXdoubleArr grad_reson_center; JDXdoubleArr grad_reson_width; STD_string scandir; dvector min_duration; }; ////////////////////////////////////////////////////////////////////////////// /** * @ingroup odinpara * An interface class that makes the global systemInfo look like a pointer, * but requests will be delegated to the actual System object in the platform object */ class SystemInterface : public StaticHandler { public: SystemInterface() {} System& operator * () {return *get_sysinfo_ptr();} const System& operator * () const {return *get_const_sysinfo_ptr();} System* operator -> () {return get_sysinfo_ptr();} const System* operator -> () const {return get_const_sysinfo_ptr();} // functions to initialize/delete static members by the StaticHandler template class static void init_static(); static void destroy_static(); static void set_current_pf(odinPlatform pf); static odinPlatform get_current_pf() { // make it inline to speed up driver access if(current_pf) return odinPlatform(current_pf->operator int ()); // else STD_cerr << "ERROR: SystemInterface::get_current_pf: current_pf not yet initialized" << STD_endl; return odinPlatform(0); } private: // friend class System; friend class SeqIdea; friend class SeqParavision; friend class SeqStandAlone; friend class SeqEpic; // friend class SeqPlatformInstances; static System* get_sysinfo_ptr(); static const System* get_const_sysinfo_ptr(); // the actual platform static SingletonHandler current_pf; // separate systemInfo for each platform static SingletonHandler* systemInfo_platform; }; #endif odin-1.8.5/odinpara/jdxfunction.cpp0000644000175000017500000002332211322062341014227 00000000000000#include "jdxfunction.h" JDXfunctionPlugIn& JDXfunctionPlugIn::register_function(funcType type, funcMode mode) { JDXfunctionEntry entry(this,type,mode); JDXfunction dummy(type,"dummy"); // make sure that JDXfunction::init_static is called once dummy.registered_functions->push_back(entry); return *this; } kspace_coord JDXfunctionPlugIn::coord_retval; //shape_vals JDXfunctionPlugIn::shape_retval; shape_info JDXfunctionPlugIn::shape_info_retval; traj_info JDXfunctionPlugIn::traj_info_retval; //////////////////////////////////////// bool JDXfunctionEntry::operator == (const JDXfunctionEntry& jfe) const { bool result=true; if(plugin!=jfe.plugin) result=false; if(type!=jfe.type) result=false; if(mode!=jfe.mode) result=false; return result; } bool JDXfunctionEntry::operator < (const JDXfunctionEntry& jfe) const { bool result=true; if(!(plugin odinlog(jdxlabel.c_str(),"JDXfunction(funcType ...)"); set_label(jdxlabel); set_function(0); } JDXfunction::JDXfunction(const JDXfunction& jf) : allocated_function(0), type(jf.type) { Log odinlog(this,"JDXfunction(const JDXfunction&)"); JDXfunction::operator = (jf); } JDXfunction& JDXfunction::operator = (const JDXfunction& jf) { JcampDxClass::operator = (jf); Log odinlog(this,"operator = (...)"); if(jf.type!=type) { ODINLOG(odinlog,normalDebug) << "wrong functype" << STD_endl; return *this; } mode=jf.mode; if(jf.allocated_function) { JDXfunctionPlugIn* pi=jf.allocated_function->clone(); pi->copy_ldr_vals(*jf.allocated_function); new_plugin(pi); } return *this; } JDXfunction& JDXfunction::set_function_mode(funcMode newmode) { if(mode==newmode) return *this; mode=newmode; new_plugin(0); set_function(0); return *this; } svector JDXfunction::get_alternatives() const { svector result; for(STD_list::const_iterator it=registered_functions->begin(); it!=registered_functions->end(); ++it) { if( it->type==type && it->mode==mode ) result.push_back(it->plugin->get_label()); } return result; } JDXfunction& JDXfunction::set_function(const STD_string& funclabel) { Log odinlog(this,"set_function"); if( allocated_function && (funclabel==allocated_function->get_label())) { ODINLOG(odinlog,normalDebug) << "function " << funclabel << " already set" << STD_endl; return *this; } STD_list::const_iterator it; for(it=registered_functions->begin(); it!=registered_functions->end(); ++it) { JDXfunctionPlugIn* plugin_template=it->plugin; ODINLOG(odinlog,normalDebug) << "checking " << funclabel << "/" << plugin_template->get_label() << STD_endl; if( it->type==type && it->mode==mode ) { ODINLOG(odinlog,normalDebug) << "type and mode match" << STD_endl; if(funclabel==plugin_template->get_label()) { ODINLOG(odinlog,normalDebug) << "label match" << STD_endl; new_plugin(plugin_template->clone()); break; } } } return *this; } static STD_string nofunc("none"); const STD_string& JDXfunction::get_function_label(unsigned int index) const { Log odinlog(this,"get_function_label"); unsigned int i=0; for(STD_list::const_iterator it=registered_functions->begin(); it!=registered_functions->end(); ++it) { if( it->type==type && it->mode==mode ) { ODINLOG(odinlog,normalDebug) << "type and mode match" << STD_endl; if(i==index) { ODINLOG(odinlog,normalDebug) << "index match" << STD_endl; return it->plugin->get_label(); } i++; } } return nofunc; } JDXfunction& JDXfunction::set_function(unsigned int index) { Log odinlog(this,"set_function"); if( allocated_function && index==get_function_index() ) { return *this; ODINLOG(odinlog,normalDebug) << "function " << index << " already set" << STD_endl; } unsigned int i=0; for(STD_list::const_iterator it=registered_functions->begin(); it!=registered_functions->end(); ++it) { JDXfunctionPlugIn* plugin_template=it->plugin; ODINLOG(odinlog,normalDebug) << "checking " << index << "/" << plugin_template->get_label() << STD_endl; if( it->type==type && it->mode==mode ) { ODINLOG(odinlog,normalDebug) << "type and mode match" << STD_endl; if(i==index) { ODINLOG(odinlog,normalDebug) << "index match" << STD_endl; new_plugin(plugin_template->clone()); break; } i++; } } return *this; } unsigned int JDXfunction::get_function_index() const { unsigned int result=0; unsigned int i=0; if(!allocated_function) return result; STD_list::const_iterator it; for(it=registered_functions->begin(); it!=registered_functions->end(); ++it) { if( it->type==type && it->mode==mode ) { if( STD_string(allocated_function->get_label()) == it->plugin->get_label() ) {result=i; break;} i++; } } return result; } JcampDxBlock* JDXfunction::get_funcpars_block() { Log odinlog(this,"get_funcpars_block"); if(allocated_function) ODINLOG(odinlog,normalDebug) << "allocated_function=" << allocated_function->get_label() << STD_endl; else ODINLOG(odinlog,normalDebug) << "allocated_function=0" << STD_endl; return allocated_function; } JDXfunction& JDXfunction::set_funcpars(const svector& funcpars) { Log odinlog(this,"set_funcpars"); if(funcpars.size()<1) return *this; set_function(funcpars[0]); if(allocated_function) { ODINLOG(odinlog,normalDebug) << "allocated_function=" << allocated_function->get_label() << STD_endl; unsigned int n_pars=allocated_function->JcampDxBlock::numof_pars(); unsigned int n_pars_min = funcpars.size()-1; if(n_pars odinlog(this,"get_funcpars"); svector funcpars; if(allocated_function) { unsigned int n_pars=allocated_function->JcampDxBlock::numof_pars(); ODINLOG(odinlog,normalDebug) << "n_pars=" << n_pars << STD_endl; funcpars.resize(n_pars+1); funcpars[0]=allocated_function->get_label(); for(unsigned int i=0;iJcampDxBlock::parseval(parameter_label,value); return false; } STD_string JDXfunction::get_parameter(const STD_string& parameter_label) const { STD_string result; if(allocated_function) result=allocated_function->JcampDxBlock::printval(parameter_label); return result; } STD_string JDXfunction::get_function_name() const { STD_string result("noFunction"); if(allocated_function) result=allocated_function->get_label(); return result; } const STD_string& JDXfunction::get_funcdescription() const { if(allocated_function) return allocated_function->get_description(); return JcampDxClass::get_description(); } bool JDXfunction::parsevalstring (const STD_string& parstring) { Log odinlog(this,"parsevalstring"); svector funcpars; STD_string argstring=extract(parstring,"(",")",true); if(argstring!="") { ODINLOG(odinlog,normalDebug) << "argstring=" << argstring << STD_endl; funcpars.push_back(extract(parstring,"","(")); argstring=shrink(argstring); svector args=tokens(argstring,',','(',')'); for(unsigned int i=0;i; } void JDXfunction::destroy_static() { // plugin might be used for different modes so we will make sure that delete is only called once for each pointer STD_list tobedeleted; for(STD_list::iterator it=registered_functions->begin(); it!=registered_functions->end(); ++it) { tobedeleted.push_back(it->plugin); } tobedeleted.sort(); tobedeleted.unique(); for(STD_list::iterator delit=tobedeleted.begin(); delit!=tobedeleted.end(); ++delit) { delete (*delit); } delete registered_functions; } void JDXfunction::new_plugin(JDXfunctionPlugIn* pi) { Log odinlog(this,"new_plugin"); if(allocated_function) delete allocated_function; if(pi) ODINLOG(odinlog,normalDebug) << "plugin=" << pi->get_label() << STD_endl; allocated_function=pi; } EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; STD_list* JDXfunction::registered_functions=0; odin-1.8.5/odinpara/seqpars.cpp0000644000175000017500000001246111725203122013355 00000000000000#include "seqpars.h" SeqPars::SeqPars(const STD_string& label) : JcampDxBlock(label) { ExpDuration.set_parmode(noedit); ExpDuration.set_description("The overall duration of the sequence"); ExpDuration.set_unit("min"); Sequence="Unknown"; Sequence.set_parmode(hidden); Sequence.set_description("The MR sequence used"); AcquisitionStart.set_filemode(exclude).set_parmode(hidden); AcquisitionStart.set_description("Starting time point of the sequence"); MatrixSizeRead=128; MatrixSizeRead.set_cmdline_option("nx").set_description("Number of points in read direction"); MatrixSizePhase=128; MatrixSizePhase.set_cmdline_option("ny").set_description("Number of points in phase direction"); MatrixSizeSlice=1; MatrixSizeSlice.set_cmdline_option("nz").set_description("Number of points in slice direction"); RepetitionTime=1000.0; RepetitionTime.set_unit(ODIN_TIME_UNIT).set_cmdline_option("tr").set_description("Time between consecutive excitations"); NumOfRepetitions=1; NumOfRepetitions.set_cmdline_option("nr").set_description("Number of consecutive measurements"); EchoTime=80.0; EchoTime.set_unit(ODIN_TIME_UNIT).set_cmdline_option("te").set_description("Time-to-echo of the sequence"); // AcqSweepWidth=25.6; // fails as default on Siemens AcqSweepWidth=25.0; AcqSweepWidth.set_unit(ODIN_FREQ_UNIT).set_description("Receiver bandwidth"); FlipAngle=90.0; FlipAngle.set_unit(ODIN_ANGLE_UNIT).set_description("Excitation flipangle"); ReductionFactor=1; ReductionFactor.set_description("Reduction factor for parallel imaging"); PartialFourier=0.0; PartialFourier.set_description("Partial Fourier acquisition in phase encoding direction (0.0 = full k-space, 1.0 = half k-space)"); RFSpoiling=true; RFSpoiling.set_description("RF Spoiling by phase cycling"); GradientIntro=true; GradientIntro.set_description("Gradient intro which will be played out prior to sequence"); PhysioTrigger=false; PhysioTrigger.set_description("Pysiological triggering"); append_all_members(); } SeqPars& SeqPars::set_MatrixSize(direction dir,unsigned int size,parameterMode parmode) { Log odinlog(this,"set_MatrixSize"); switch(dir){ case readDirection: MatrixSizeRead=size; MatrixSizeRead.set_parmode(parmode);break; case phaseDirection: MatrixSizePhase=size; MatrixSizePhase.set_parmode(parmode);break; case sliceDirection: MatrixSizeSlice=size; MatrixSizeSlice.set_parmode(parmode);break; default: ODINLOG(odinlog,errorLog) << "Direction " << dir << " is not available." << STD_endl; } return *this; } unsigned int SeqPars::get_MatrixSize(direction dir) const { unsigned int result=0; if(dir==readDirection) result=MatrixSizeRead; if(dir==phaseDirection) result=MatrixSizePhase; if(dir==sliceDirection) result=MatrixSizeSlice; return result; } SeqPars& SeqPars::set_RepetitionTime(double time,parameterMode parmode) { RepetitionTime=time; RepetitionTime.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_NumOfRepetitions(unsigned int times,parameterMode parmode) { NumOfRepetitions=times; NumOfRepetitions.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_EchoTime(double time,parameterMode parmode) { EchoTime=time; EchoTime.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_AcqSweepWidth(double sw,parameterMode parmode) { AcqSweepWidth=sw; AcqSweepWidth.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_FlipAngle(double fa,parameterMode parmode) { FlipAngle=fa; FlipAngle.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_ReductionFactor(unsigned int factor, parameterMode parmode) { ReductionFactor=factor; ReductionFactor.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_PartialFourier(float factor, parameterMode parmode) { PartialFourier=factor; PartialFourier.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_RFSpoiling(bool flag, parameterMode parmode) { RFSpoiling=flag; RFSpoiling.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_GradientIntro(bool flag, parameterMode parmode) { GradientIntro=flag; GradientIntro.set_parmode(parmode); return *this; } SeqPars& SeqPars::set_PhysioTrigger(bool flag, parameterMode parmode) { PhysioTrigger=flag; PhysioTrigger.set_parmode(parmode); return *this; } SeqPars& SeqPars::operator = (const SeqPars& pars2) { JcampDxBlock::operator = (pars2); append_all_members(); // copy only visible members of JcampDxBlock copy_ldr_vals(pars2); return *this; } void SeqPars::append_all_members() { JcampDxBlock::clear(); append_member(ExpDuration,"ExpDuration"); append_member(Sequence,"Sequence"); append_member(AcquisitionStart,"AcquisitionStart"); append_member(MatrixSizeRead,"MatrixSizeRead"); append_member(MatrixSizePhase,"MatrixSizePhase"); append_member(MatrixSizeSlice,"MatrixSizeSlice"); append_member(RepetitionTime,"RepetitionTime"); append_member(NumOfRepetitions,"NumOfRepetitions"); append_member(EchoTime,"EchoTime"); append_member(AcqSweepWidth,"AcqSweepWidth"); append_member(FlipAngle,"FlipAngle"); append_member(ReductionFactor,"ReductionFactor"); append_member(PartialFourier,"PartialFourier"); append_member(RFSpoiling,"RFSpoiling"); append_member(GradientIntro,"GradientIntro"); append_member(PhysioTrigger,"PhysioTrigger"); } odin-1.8.5/odinpara/jdxfunction.h0000644000175000017500000001666311322062340013705 00000000000000/*************************************************************************** jdxfunction.h - description ------------------- begin : Mon Jun 24 2002 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXFUNCTION_H #define JDXFUNCTION_H #include /** * @addtogroup jcampdx * @{ */ enum funcType {shapeFunc=0, trajFunc, filterFunc}; /** * * Dimension Mode Enum: * * - zeroDeeMode : Only RF waveform will be calculated * - oneDeeMode : RF and gradient shape will be calculated according * to the selected shape/trajectory for 1D pulses * - twoDeeMode : RF and gradient shape will be calculated according * to the selected shape/trajectory for 2D pulses */ enum funcMode {zeroDeeMode=0,oneDeeMode,twoDeeMode,n_dimModes}; /////////////////////////////////////////// class OdinPulse; // forward declaration /////////////////////////////////////////// /** * * Structure to return k-space coordinates, gradient strengts and sampling density * compensations of trajectories. */ struct kspace_coord { kspace_coord() : index(-1), traj_s(0.0), kx(0), ky(0), kz(0), Gx(0), Gy(0), Gz(0), denscomp(1.0) {} /** * The current index in the array */ mutable int index; /** * The dimension-less time parameter which will be used for the shape and filter, ranging from 0 to 1 */ float traj_s; /** * The dimension-less x-coordinate in k-space, ranging from -1 to 1 */ float kx; /** * The dimension-less y-coordinate in k-space, ranging from -1 to 1 */ float ky; /** * The dimension-less z-coordinate in k-space, ranging from -1 to 1 */ float kz; /** * The dimension-less x-gradient, i.e. the derivative of kx by s (the dimension-less time parameter) */ float Gx; /** * The dimension-less y-gradient, i.e. the derivative of kx by s (the dimension-less time parameter) */ float Gy; /** * The dimension-less z-gradient, i.e. the derivative of kx by s (the dimension-less time parameter) */ float Gz; /** * Compensation for differing sampling density, RF shape or RF signal will be multiplied by this function */ float denscomp; }; /////////////////////////////////////////// struct shape_info { shape_info() : ref_x_pos(0), ref_y_pos(0), ref_z_pos(0), adiabatic(false), fixed_size(-1), spatial_extent(0.0) {} float ref_x_pos; // Reference position to adjust flip angle float ref_y_pos; float ref_z_pos; bool adiabatic; // Whether pulse is adiabatic int fixed_size; // Pulse has fixed size (for imported pulses) float spatial_extent; }; /////////////////////////////////////////// struct traj_info { traj_info() : rel_center(0), max_kspace_step(0) {} float rel_center; float max_kspace_step; }; /////////////////////////////////////////// class JDXfunctionPlugIn : public JcampDxBlock { public: JDXfunctionPlugIn(const STD_string& funclabel) : JcampDxBlock(funclabel) {} JDXfunctionPlugIn(const JDXfunctionPlugIn& jfp) : JcampDxBlock(jfp) {} virtual ~JDXfunctionPlugIn() {} JDXfunctionPlugIn& operator = (const JDXfunctionPlugIn& jfp) {JcampDxBlock::operator = (jfp); return *this;} JDXfunctionPlugIn& register_function(funcType type, funcMode mode); // virtual functions for pulse shapes virtual void init_shape() {} virtual STD_complex calculate_shape(const kspace_coord& coord ) const {return STD_complex(0.0);} virtual STD_complex calculate_shape(float s, float Tp) const {return STD_complex(0.0);} virtual const shape_info& get_shape_properties() const {return shape_info_retval;} // virtual functions for pulse trajectories virtual void init_trajectory(OdinPulse* pls) {} virtual const kspace_coord& calculate_traj(float s) const {return coord_retval;} virtual const traj_info& get_traj_properties() const {return traj_info_retval;} // virtual functions for filters virtual float calculate_filter(float rel_kradius) const {return 0;} // virtual constructor virtual JDXfunctionPlugIn* clone() const = 0; // local statics do not work on IDEA static kspace_coord coord_retval; // static shape_vals shape_retval; static shape_info shape_info_retval; static traj_info traj_info_retval; }; /////////////////////////////////////////// // Wrapper to bundle JDXfunctionPlugIn and funcType/funcMode together so it can be inserted into lists // multiple times with different funcTypes and funcModes struct JDXfunctionEntry { JDXfunctionEntry(JDXfunctionPlugIn* func_plugin, funcType func_type, funcMode func_mode) : plugin(func_plugin), type(func_type), mode(func_mode) {} JDXfunctionPlugIn* plugin; const funcType type; const funcMode mode; bool operator == (const JDXfunctionEntry& jfe) const; bool operator < (const JDXfunctionEntry& jfe) const; }; /////////////////////////////////////////// class JDXfunction : public JcampDxClass, public StaticHandler { public: ~JDXfunction() {new_plugin(0);} JDXfunction& set_function_mode(funcMode newmode); funcMode get_function_mode() const {return mode;} const STD_string& get_function_label(unsigned int index) const; JDXfunction& set_function(const STD_string& funclabel); JDXfunction& set_function(unsigned int index); unsigned int get_function_index() const; JcampDxBlock* get_funcpars_block(); JDXfunction& set_funcpars(const svector& funcpars); JDXfunction& set_funcpars(const STD_string& funcpars) {STD_string tt(funcpars); parsevalstring(tt); return *this;} svector get_funcpars() const; bool set_parameter(const STD_string& parameter_label, const STD_string& value); STD_string get_parameter(const STD_string& parameter_label) const; STD_string get_function_name() const; const STD_string& get_funcdescription() const; // overwriting virtual functions from JcampDxClass JDXfunction* cast(JDXfunction*) {return this;} bool parsevalstring (const STD_string& parstring); STD_string printvalstring() const; svector get_alternatives() const; const char* get_typeInfo() const {return "function";} JcampDxClass* create_copy() const {return new JDXfunction(*this);} // stuff for StaticHandler static void init_static(); static void destroy_static(); protected: // Make it impossible to create/use instance of JDXfunction directly JDXfunction(funcType function_type, const STD_string& jdxlabel); JDXfunction(const JDXfunction& jf); JDXfunction& operator = (const JDXfunction& jf); funcMode mode; JDXfunctionPlugIn* allocated_function; private: friend class JDXfunctionPlugIn; void new_plugin(JDXfunctionPlugIn* pi); const funcType type; static STD_list* registered_functions; }; /** @} */ #endif odin-1.8.5/odinpara/jdxfilter.cpp0000644000175000017500000001304211363773555013712 00000000000000#include "jdxfilter.h" #include "jdxnumbers.h" class Gauss : public JDXfunctionPlugIn { JDXdouble filterwidth; public: Gauss() : JDXfunctionPlugIn("Gauss") { filterwidth=0.36169; filterwidth.set_minmaxval(0.1,1.0); append_member(filterwidth,"FilterWidth"); } private: float calculate_filter (float rel_kradius) const { float factor = (-1) * log (0.5) * secureInv( (filterwidth * filterwidth)) ; if(rel_kradius<0.0) rel_kradius=0.0; return exp(-(rel_kradius*rel_kradius)*factor); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Gauss;} }; /////////////////////////////////////////////////////////// class NoFilter : public JDXfunctionPlugIn { public: NoFilter() : JDXfunctionPlugIn("NoFilter") {} float calculate_filter (float rel_kradius) const { if(rel_kradius>1.0) return 0.0; return 1.0; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new NoFilter;} }; /////////////////////////////////////////////////////////// class Triangle : public JDXfunctionPlugIn { public: Triangle() : JDXfunctionPlugIn("Triangle") { } float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; return 1.0-rel_kradius; } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Triangle;} }; /////////////////////////////////////////////////////////// class Hann : public JDXfunctionPlugIn { public: Hann() : JDXfunctionPlugIn("Hann") { } float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; return 0.5*(1.0+cos(rel_kradius*PII)); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Hann;} }; /////////////////////////////////////////////////////////// class Hamming : public JDXfunctionPlugIn { public: Hamming() : JDXfunctionPlugIn("Hamming") { } float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; return (0.53836+0.46164*cos(rel_kradius*PII)); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Hamming;} }; /////////////////////////////////////////////////////////// class CosSq : public JDXfunctionPlugIn { public: CosSq() : JDXfunctionPlugIn("CosSq") { } private: float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; double value=pow(cos(rel_kradius*PII/2.0),2.0); return (value); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new CosSq;} }; /////////////////////////////////////////////////////////// class Blackman : public JDXfunctionPlugIn { public: Blackman() : JDXfunctionPlugIn("Blackman") { } float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; return 0.42+0.5*cos(rel_kradius*PII)+0.08*cos(2.0*rel_kradius*PII); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Blackman;} }; /////////////////////////////////////////////////////////// class BlackmanNuttall : public JDXfunctionPlugIn { public: BlackmanNuttall() : JDXfunctionPlugIn("BlackmanNuttall") { } private: float calculate_filter (float rel_kradius) const { if(rel_kradius<0.0) rel_kradius=0.0; if(rel_kradius>1.0) rel_kradius=1.0; float step = PII*0.5*rel_kradius; float a0 = 0.3635819; float a1 = 0.4891775; float a2 = 0.1365995; float a3 = 0.0106411; double value=a0+a1*cos(2.0*step)+a2*cos(4.0*step)+a3*cos(6.0*step); return (value); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new BlackmanNuttall;} }; /////////////////////////////////////////////////////////// class Exp : public JDXfunctionPlugIn { JDXdouble filterwidth; public: Exp() : JDXfunctionPlugIn("Exp") { } private: float calculate_filter (float rel_kradius) const { return exp(-rel_kradius); } // implementing virtual function of JDXfunctionPlugIn JDXfunctionPlugIn* clone() const {return new Exp;} }; /////////////////////////////////////////////////////////// /* class Fermi : public JDXfunctionTemplate { public: Fermi() : JDXfunctionTemplate("Fermi") { } float calculate (float knorm, float kernel) const { float dummy=(knorm*kernel*2.0-8.0); return 1.0/(exp(dummy)+1.0); } }; */ /////////////////////////////////////////////////////////// void JDXfilter::init_static() { (new Gauss)->register_function(filterFunc, funcMode(0)); (new NoFilter)->register_function(filterFunc, funcMode(0)); (new Triangle)->register_function(filterFunc, funcMode(0)); (new Hann)->register_function(filterFunc, funcMode(0)); (new Hamming)->register_function(filterFunc, funcMode(0)); (new CosSq)->register_function(filterFunc, funcMode(0)); (new Blackman)->register_function(filterFunc, funcMode(0)); (new BlackmanNuttall)->register_function(filterFunc, funcMode(0)); (new Exp)->register_function(filterFunc, funcMode(0)); // (new Fermi)->register_function(filterFunc, funcMode(0)); } void JDXfilter::destroy_static() { // pulgins will be deleted by JDXfunction } EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; odin-1.8.5/odinpara/jdxfilter.h0000644000175000017500000000335611322062340013340 00000000000000/*************************************************************************** jdxfilter.h - description ------------------- begin : Thu Jul 6 2006 copyright : (C) 2002 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXFILTER_H #define JDXFILTER_H #include /** * @addtogroup jcampdx * @{ */ /** * * Wrapper class for pulse shape functions. */ class JDXfilter : public JDXfunction, public StaticHandler { public: JDXfilter(const STD_string& jdxlabel="unnamedJDXfilter") : JDXfunction(filterFunc,jdxlabel) {} JDXfilter(const JDXfilter& jf) : JDXfunction(jf) {} JDXfilter& operator = (const JDXfilter& jf) {JDXfunction::operator = (jf); return *this;} float calculate (float rel_kradius) const { if(allocated_function) return allocated_function->calculate_filter(rel_kradius); else return 0.0; } static void init_static(); static void destroy_static(); }; /** @} */ #endif odin-1.8.5/odinpara/reco.cpp0000644000175000017500000006136411455553536012656 00000000000000#include "reco.h" #include #include static const char* recoFlagTrue="X"; static const char* recoFlagFalse="-"; void kSpaceCoord::reset2defaults() { number=0; reps=1; adcSize=0; channels=1; preDiscard=0; postDiscard=0; concat=1; oversampling=1.0; relcenter=0.5; readoutIndex=-1; trajIndex=-1; weightIndex=-1; dtIndex=0; for(int i=0; i1) result+=STD_string(recoDimLabel[i])+","; } result+="lastinchunk,"; result+="reflect"; return result; } STD_string kSpaceCoord::printcoord(const unsigned short* numof_cache) const { STD_string result; STD_string tab(","); result+=itos(number)+tab; result+=itos(reps)+tab; result+=itos(adcSize)+tab; result+=itos(channels)+tab; result+=itos(preDiscard)+tab; result+=itos(postDiscard)+tab; result+=itos(concat)+tab; result+=ftos(oversampling)+tab; result+=ftos(relcenter)+tab; result+=itos(readoutIndex)+tab; result+=itos(trajIndex)+tab; result+=itos(weightIndex)+tab; result+=itos(dtIndex)+tab; for(int i=0; i1) result+=index2string(index[i], recoDim(i))+tab; } if(flags&recoLastInChunkBit) result+=recoFlagTrue+tab; else result+=recoFlagFalse+tab; if(flags&recoReflectBit) result+=recoFlagTrue; else result+=recoFlagFalse; return result; } int kSpaceCoord::string2index(const STD_string& str, recoDim dim) { int result=0; bool numeric_encoding=true; // Fallback: Convert string to int // Special treatment of template dimension which has characters to index different template types (for extensibility) if(dim==templtype) { if(str.size()) { char templchar=str[0]; if(templchar>='A' && templchar<='Z') { for(int itempl=0; itempl='a' && navchar<='z') { for(int inav=0; inav=0 && index=0 && index odinlog("kSpaceCoord","parsecoord"); reset2defaults(); svector toks(tokens(str,',')); int ntoks=toks.size(); if(ntoks=0) number=atoi(toks[parsepos_number].c_str()); if(parsepos_reps>=0) reps=atoi(toks[parsepos_reps].c_str()); if(parsepos_adcSize>=0) adcSize=atoi(toks[parsepos_adcSize].c_str()); if(parsepos_channels>=0) channels=atoi(toks[parsepos_channels].c_str()); if(parsepos_preDiscard>=0) preDiscard=atoi(toks[parsepos_preDiscard].c_str()); if(parsepos_postDiscard>=0) postDiscard=atoi(toks[parsepos_postDiscard].c_str()); if(parsepos_concat>=0) concat=atoi(toks[parsepos_concat].c_str()); if(parsepos_oversampling>=0) oversampling=atof(toks[parsepos_oversampling].c_str()); if(parsepos_relcenter>=0) relcenter=atof(toks[parsepos_relcenter].c_str()); if(parsepos_readoutIndex>=0) readoutIndex=atoi(toks[parsepos_readoutIndex].c_str()); if(parsepos_trajIndex>=0) trajIndex=atoi(toks[parsepos_trajIndex].c_str()); if(parsepos_weightIndex>=0) weightIndex=atoi(toks[parsepos_weightIndex].c_str()); if(parsepos_dtIndex>=0) dtIndex=atoi(toks[parsepos_dtIndex].c_str()); for(int i=0; i=0) { STD_string indexstr(toks[parsepos_index[i]]); index[i]=string2index(indexstr, recoDim(i)); } } if(parsepos_lastinchunk>=0) if(toks[parsepos_lastinchunk]==recoFlagFalse) flags=flags&(recoLastInChunkBit^recoAllBits); if(parsepos_reflect>=0) if(toks[parsepos_reflect] ==recoFlagTrue) flags=flags|recoReflectBit; return true; } int findval(const svector& strvec, const STD_string& val) { for(unsigned int i=0;i odinlog("kSpaceCoord","assign_parsepos"); svector toks(tokens(header,',')); max_parsepos=STD_max(max_parsepos,parsepos_number=findval(toks,"number")); max_parsepos=STD_max(max_parsepos,parsepos_reps=findval(toks,"reps")); max_parsepos=STD_max(max_parsepos,parsepos_adcSize=findval(toks,"adcSize")); max_parsepos=STD_max(max_parsepos,parsepos_channels=findval(toks,"channels")); max_parsepos=STD_max(max_parsepos,parsepos_preDiscard=findval(toks,"preDiscard")); max_parsepos=STD_max(max_parsepos,parsepos_postDiscard=findval(toks,"postDiscard")); max_parsepos=STD_max(max_parsepos,parsepos_concat=findval(toks,"concat")); max_parsepos=STD_max(max_parsepos,parsepos_oversampling=findval(toks,"oversampling")); max_parsepos=STD_max(max_parsepos,parsepos_relcenter=findval(toks,"relcenter")); max_parsepos=STD_max(max_parsepos,parsepos_readoutIndex=findval(toks,"readoutIndex")); max_parsepos=STD_max(max_parsepos,parsepos_trajIndex=findval(toks,"trajIndex")); max_parsepos=STD_max(max_parsepos,parsepos_weightIndex=findval(toks,"weightIndex")); max_parsepos=STD_max(max_parsepos,parsepos_dtIndex=findval(toks,"dtIndex")); for(int i=0; i odinlog(this,"clear"); if(state==has_vec_alloc) { for(unsigned int i=0; i::iterator it=coordlist.begin(); it!=coordlist.end(); ++it) { kSpaceCoord& coord=(*it); vec_cache[counter]=&coord; for(int j=0; j odinlog(this,"parsevalstring"); ODINLOG(odinlog,normalDebug) << "tokenizing ..." << STD_endl; svector toks(tokens(parstring)); ODINLOG(odinlog,normalDebug) << "toks.size()=" << toks.size() << STD_endl; if(!toks.size()) return true; kSpaceCoord::assign_parsepos(toks[0]); unsigned int n_lines=toks.size()-1; ODINLOG(odinlog,normalDebug) << "parsing " << n_lines << " lines" << STD_endl; clear(); vec_cache.resize(n_lines); bool result=true; ODINLOG(odinlog,normalDebug) << "parsing sinle tokens ..." << STD_endl; for(unsigned int i=0; iparsecoord(toks[i+1])) result=false; for(int j=0; jindex[j]+1)); } state=has_vec_alloc; ODINLOG(odinlog,normalDebug) << "size()=" << size() << STD_endl; return result; } STD_string JDXkSpaceCoords::printvalstring() const { create_vec_cache(); STD_string result(kSpaceCoord::print_header(numof_cache)+"\n"); for(unsigned int i=0; i odinlog(ldrlabel.c_str(), "JDXrecoValList(label)"); set_label(ldrlabel); } JDXrecoValList& JDXrecoValList::operator = (const JDXrecoValList& jdrvl) { RecoValList::operator = (jdrvl); JcampDxClass::operator = (jdrvl); return *this; } JDXrecoValList& JDXrecoValList::operator = (const RecoValList& rvl) { STD_string label_backup(get_label()); RecoValList::operator = (rvl); set_label(label_backup); return *this; } bool JDXrecoValList::parsevalstring (const STD_string& parstring) { Log odinlog(this,"parsevalstring"); STD_string sting4vallist(rmblock(parstring,"(",")",true,true)); return ValList::parsevallist(sting4vallist); } STD_string JDXrecoValList::printvalstring() const { return "("+itos(size())+")\n"+tokenstring(tokens(ValList::printvallist())); // nice formatting } STD_ostream& JDXrecoValList::print2stream(STD_ostream& os) const { os << "(" << itos(size()) << ")\n"; ValList::print2stream(os); return os; } ////////////////////////////////////////////////////////////////// void RecoPars::common_init() { Log odinlog(this,"common_init"); cache_is_up2date=false; ReadoutDstSize.resize(MAX_NUMOF_READOUT_SHAPES); } RecoPars::RecoPars(const STD_string& label) : JcampDxBlock(label) { Log odinlog(this,"RecoPars(label)"); common_init(); if(little_endian_byte_order()) LittleEndian=true; else LittleEndian=false; ODINLOG(odinlog,normalDebug) << "LittleEndian=" << bool(LittleEndian) << STD_endl; append_all_members(); } RecoPars::RecoPars(const RecoPars& sr) { common_init(); RecoPars::operator = (sr); } RecoPars& RecoPars::operator = (const RecoPars& sr) { JcampDxBlock::operator = (sr); append_all_members(); // copy only visible members of JcampDxBlock copy_ldr_vals(sr); return (*this); } RecoPars& RecoPars::set_DimValues(recoDim dim, const dvector& vals) { Log odinlog(this,"set_DimValues"); if(dim odinlog(this,"append_all_members"); int i; clear(); append_member(prot,PROTOCOL_BLOCK_LABEL); append_member(DataFormat,"DataFormat"); append_member(LittleEndian,"LittleEndian"); append_member(RawFile,"RawFile"); append_member(RawHeaderSize,"RawHeaderSize"); append_member(RelativeOffset,"RelativeOffset"); append_member(ImageProc,"ImageProc"); append_member(ChannelScaling,"ChannelScaling"); append_member(DwellTime,"DwellTime"); for(i=0; i odinlog(this,"get_sensitivity_value"); STD_complex result(0); ndim nn=SensitivityMap.get_extent(); int nx=nn[3]; int ny=nn[2]; int nz=nn[1]; int nchans=nn[0]; if(int(channel) >= nchans) return result; float xDelta=secureDivision(FOV[0],nx); float yDelta=secureDivision(FOV[1],ny); float zDelta=secureDivision(FOV[2],nz); // indices of the grid square which contain the desired point float fx=(x+0.5*FOV[0])/xDelta; float fy=(y+0.5*FOV[1])/yDelta; float fz=(z+0.5*FOV[2])/zDelta; int ixlow=int(floor(fx-0.5)); int ixupp=int(floor(fx+0.5)); int iylow=int(floor(fy-0.5)); int iyupp=int(floor(fy+0.5)); int izlow=int(floor(fz-0.5)); int izupp=int(floor(fz+0.5)); if(nx<=1) ixlow=ixupp=0; if(ny<=1) iylow=iyupp=0; if(nz<=1) izlow=izupp=0; if(ixlow==-1) ixlow=0; if(iylow==-1) iylow=0; if(izlow==-1) izlow=0; if(ixupp==nx) ixupp=nx-1; if(iyupp==ny) iyupp=ny-1; if(izupp==nz) izupp=nz-1; if(ixlow<0) return result; if(iylow<0) return result; if(izlow<0) return result; if(ixupp>=nx) return result; if(iyupp>=ny) return result; if(izupp>=nz) return result; ODINLOG(odinlog,normalDebug) << "ixlow/iylow/izlow(" << x << "," << y << "," << z << ")=" << ixlow << "/" << iylow << "/" << izlow << STD_endl; ODINLOG(odinlog,normalDebug) << "ixupp/iyupp/izupp(" << x << "," << y << "," << z << ")=" << ixupp << "/" << iyupp << "/" << izupp << STD_endl; float xlow=-0.5*FOV[0]+(float(ixlow)+0.5)*xDelta; float ylow=-0.5*FOV[1]+(float(iylow)+0.5)*yDelta; float zlow=-0.5*FOV[2]+(float(izlow)+0.5)*zDelta; // relative positions within the grid square float sx=(x-xlow)/xDelta; if(sx<0.0) sx=0.0; if(sx>1.0) sx=1.0; float sy=(y-ylow)/yDelta; if(sy<0.0) sy=0.0; if(sy>1.0) sy=1.0; float sz=(z-zlow)/zDelta; if(sz<0.0) sz=0.0; if(sz>1.0) sz=1.0; ODINLOG(odinlog,normalDebug) << "sx/sy/sz(" << x << "," << y << "," << z << ")=" << sx << "/" << sy << "/" << sz << STD_endl; result=STD_complex((1.0-sz)*(1.0-sy)*(1.0-sx))*SensitivityMap(channel,izlow,iylow,ixlow) +STD_complex((1.0-sz)*(1.0-sy)*( sx))*SensitivityMap(channel,izlow,iylow,ixupp) +STD_complex((1.0-sz)*( sy)*(1.0-sx))*SensitivityMap(channel,izlow,iyupp,ixlow) +STD_complex((1.0-sz)*( sy)*( sx))*SensitivityMap(channel,izlow,iyupp,ixupp) +STD_complex(( sz)*(1.0-sy)*(1.0-sx))*SensitivityMap(channel,izupp,iylow,ixlow) +STD_complex(( sz)*(1.0-sy)*( sx))*SensitivityMap(channel,izupp,iylow,ixupp) +STD_complex(( sz)*( sy)*(1.0-sx))*SensitivityMap(channel,izupp,iyupp,ixlow) +STD_complex(( sz)*( sy)*( sx))*SensitivityMap(channel,izupp,iyupp,ixupp); return result; } void CoilSensitivity::append_all_members() { clear(); SensitivityMap.redim(1,1,1,1); SensitivityMap.set_filemode(compressed); append_member(FOV,"FOV"); append_member(SensitivityMap,"SensitivityMap"); } //////////////////////////////////////////////// #ifndef NO_UNIT_TEST class CoilSensitivityTest : public UnitTest { public: CoilSensitivityTest() : UnitTest("CoilSensitivity") {} private: bool check() const { Log odinlog(this,"check"); unsigned int i; int testsize=10; float testfov=200.0; CoilSensitivity sens; carray testmap(1,1,testsize,testsize); ndim nn=testmap.get_extent(); ndim ii; float center=0.5*float(testsize-1); for(i=0; i1.0) { ODINLOG(odinlog,errorLog) << "mean1=" << mean1 << STD_endl; ODINLOG(odinlog,errorLog) << "mean2=" << mean2 << STD_endl; return false; } return true; } }; void alloc_CoilSensitivityTest() {new CoilSensitivityTest();} // create test instance #endif odin-1.8.5/odinpara/jdxnumbers.h0000644000175000017500000001075711322062341013532 00000000000000/*************************************************************************** jdxnumbers.h - description ------------------- begin : Mon Jul 12 2004 copyright : (C) 2001 by Thies H. Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef JDXNUMBERS_H #define JDXNUMBERS_H #include #include /** * @addtogroup jcampdx * @{ */ ////////////////////////////////////////////////////////////////// /** * * JCAMP-DX template class for representing built-in numbers */ template class JDXnumber : public virtual JcampDxClass { public: /** * Default constructor */ JDXnumber() {set_defaults();} /** * Constructor with the following arguments: * - v: Initial value for the number * - name: The label of the JCAMP-DX parameter * - userParameter: Whether this is a user defined JCAMP-DX parameter * - mode: Mode for ASCII representation of strings or arrays of strings * - parameter_mode: Mode for GUI accesibility of the parameter * - parx_equivalent: Equivalent parameter in PARX to which this parameter will be assigned * - parx_assign_factor: Scaling factor when assigning to the equivalent parameter in PARX * - parx_assign_offset: Offset when assigning to the equivalent parameter in PARX */ JDXnumber(T v, const STD_string& name="",bool userParameter=true, compatMode mode=notBroken,parameterMode parameter_mode=edit, const STD_string& parx_equivalent="", float parx_assign_factor=1.0,float parx_assign_offset=0.0); /** * Copy constructor */ JDXnumber(const JDXnumber& bi) {JDXnumber::operator = (bi);} /** * Assignment operator from a built-in number */ JDXnumber& operator = (T v) {val=v; return *this;} /** * Copy assignment */ JDXnumber& operator = (const JDXnumber& bi); // code to make the number appear like a built-in number operator T () const {return val;} T operator += (T rhsval) {val+=rhsval; return *this;} T operator -= (T rhsval) {val-=rhsval; return *this;} T operator *= (T rhsval) {val*=rhsval; return *this;} T operator /= (T rhsval) {val/=rhsval; return *this;} T operator ++ () {val=val+(T)1; return val;} // prefix T operator ++ (int) {T tmp=val; val=val+(T)1; return tmp;} // postfix T operator -- () {val=val-(T)1; return val;} // prefix T operator -- (int) {T tmp=val; val=val-(T)1; return tmp;} // postfix /** * Specifies the minimum and maximum allowed value for this number. * Only useful when editing the parameter in a GUI */ JDXnumber& set_minmaxval(double min,double max) {minval=min; maxval=max; return *this;} // overwriting virtual functions from JcampDxClass STD_string printvalstring() const; bool parsevalstring (const STD_string& parstring); STD_string get_parx_code(parxCodeType type, const ParxEquiv& equiv) const; ParxEquiv get_parx_equiv() const {return parx_equiv;} double get_minval() const {return minval;} double get_maxval() const {return maxval;} const char* get_typeInfo() const {return TypeTraits::type2label(val);} JcampDxClass* create_copy() const {return new JDXnumber(*this);} T* cast(T*) {return &val;} private: void set_defaults(); T val; mutable ParxEquiv parx_equiv; double minval,maxval; }; ///////////////////////////////////////////////////////////////////////////// // // Aliases: /** * An integer number */ typedef JDXnumber JDXint; /** * An single-precision floating point number */ typedef JDXnumber JDXfloat; /** * An double-precision floating point number */ typedef JDXnumber JDXdouble; /** * Complex number */ typedef JDXnumber JDXcomplex; /** @} */ #endif odin-1.8.5/odinpara/jdxblock.cpp0000644000175000017500000004617611363773555013535 00000000000000#include "jdxblock.h" #include #ifdef HAVE_LOCALE_H #include #endif void set_c_locale() { Log odinlog("JcampDxBlock","set_c_locale"); #ifdef HAVE_LOCALE_H // set locale to default before reading/writing blocks // to get decimal point on all platforms const char* retval=setlocale(LC_NUMERIC, "C"); ODINLOG(odinlog,normalDebug) << "LC_NUMERIC=" << retval << STD_endl; #endif } JcampDxBlock::JcampDxBlock(const STD_string& title,compatMode mode) : garbage(0), embed(true) { Log odinlog(title.c_str(),"JcampDxBlock(title)"); set_label(title); JcampDxBlock::set_compatmode(mode); // Do NOT call virtual function in constructor! } JcampDxBlock::JcampDxBlock(const JcampDxBlock& block) : garbage(0) { JcampDxBlock::operator = (block); } JcampDxBlock::~JcampDxBlock() { Log odinlog(this,"~JcampDxBlock"); if(garbage) { ODINLOG(odinlog,normalDebug) << "Removing " << JDXList::size() << " parameters from block" << STD_endl; JDXList::clear(); // remove before deleting ODINLOG(odinlog,normalDebug) << "Deleting " << garbage->size() << " parameters in garbage" << STD_endl; for(STD_list::iterator it=garbage->begin(); it!=garbage->end(); ++it) { ODINLOG(odinlog,normalDebug) << "Deleting >" << (*it)->get_label() << "<" << STD_endl; delete (*it); } delete garbage; } } JcampDxBlock& JcampDxBlock::operator = (const JcampDxBlock& block) { Log odinlog(this,"JcampDxBlock::operator = "); JcampDxClass::operator = (block); // JDXList::operator = (block); // Unneccessary since the copied list would be cleared in the next line JDXList::clear(); // start with empty block so that members are copied by value and not by pointer (as done in List) embed=block.embed; return *this; } JDXList::constiter JcampDxBlock::ldr_exists(const STD_string& label) const { Log odinlog(this,"ldr_exists"); for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { ODINLOG(odinlog,normalDebug) << "comparing LDR >" << label << "< and >" << (*it)->get_label() << "<" << STD_endl; if( (*it)->get_label()==label ) { ODINLOG(odinlog,normalDebug) << "LDR found" << STD_endl; return it; } } ODINLOG(odinlog,normalDebug) << "LDR not found" << STD_endl; return get_const_end(); } STD_string JcampDxBlock::extract_parlabel(const STD_string& parstring) { STD_string parlabel(extract(parstring,"##","=")); if (parlabel[0]=='$') { parlabel+="="; parlabel=extract(parlabel,"$","="); } if(parlabel=="TITLE") { parlabel=extract(parstring,"##TITLE=","\n"); } return parlabel; } int JcampDxBlock::parse_ldr_list(STD_string& parstring) { Log odinlog(this,"parse_ldr_list"); parstring+="##"; // set mark at end so rmblock(parstring,"##","##",... always works ODINLOG(odinlog,normalDebug) << "parstring=>" << parstring << "<" << STD_endl; // get 1st parameter before starting while loop STD_string parlabel(extract_parlabel(parstring)); constiter ldr_it=get_const_begin(); int n_parsed=0; while(parlabel!="") { if( (ldr_it=ldr_exists(parlabel) )!=get_const_end() ) { if(!(*ldr_it)->parse(parstring)) { ODINLOG(odinlog,normalDebug) << "parsing of >" << parlabel << "< failed" << STD_endl; return -1; } else { ODINLOG(odinlog,normalDebug) << "parsing of >" << parlabel << "< successful" << STD_endl; n_parsed++; } } else { parstring=rmblock(parstring,"##","##",true,false,false,false); } // get next parameter parlabel=extract_parlabel(parstring); } return n_parsed; } bool JcampDxBlock::parse(STD_string& parstring) { Log odinlog(this,"parse"); if(parseblock(parstring)<0) return false; ODINLOG(odinlog,normalDebug) << "parstring(pre)=>" << parstring << "<" << STD_endl; // eat up my part from parstring parstring+="##END="; // make sure we have an end tag which might got lost STD_string blockbody(extract(parstring,"##TITLE=","##END=",true)); parstring=replaceStr(parstring,"##TITLE="+blockbody+"##END=",""); ODINLOG(odinlog,normalDebug) << "parstring(post)=>" << parstring << "<" << STD_endl; return true; } STD_string JcampDxBlock::print_header() const { STD_string result="##TITLE="+get_label()+"\n"; result+="##JCAMPDX=4.24\n"; result+="##DATATYPE=Parameter Values\n"; return result; } STD_string JcampDxBlock::print_tail() const { return "##END=\n"; } STD_string JcampDxBlock::print() const { Log odinlog(this,"print"); STD_string retstring(print_header()); ODINLOG(odinlog,normalDebug) << "printing " << numof_pars() << " parameters" << STD_endl; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { retstring+=(*it)->print(); } retstring+=print_tail(); return retstring; } STD_ostream& JcampDxBlock::print2stream(STD_ostream& os) const { os << print_header(); for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->get_filemode()!=exclude) { os << (*it)->get_jdx_prefix(); (*it)->print2stream(os); os << (*it)->get_jdx_postfix(); } } return os << print_tail(); } STD_string JcampDxBlock::printval(const STD_string& parameterName) const { Log odinlog(this,"printval"); STD_string retstring; constiter it=ldr_exists(parameterName); if(it!=get_const_end()) { retstring=(*it)->printvalstring(); } return retstring; } bool JcampDxBlock::parseval(const STD_string& parameterName, const STD_string& value) { Log odinlog(this,"parseval"); bool result=false; constiter it=ldr_exists(parameterName); if(it!=get_const_end()) { STD_string valdummy=value; result=(*it)->parsevalstring(valdummy); } return result; } STD_string JcampDxBlock::get_parx_code(parxCodeType type, const ParxEquiv& equiv) const { #ifdef PARAVISION_PLUGIN STD_string result=JcampDxClass::get_parx_code(type,equiv); if(type==parx_def) { for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter()) result+=(*it)->get_parx_code(parx_def,(*it)->get_parx_equiv()); } } if(type==parx_parclass_def) { result="parclass {\n"; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter()) result+=STD_string((*it)->get_label())+";\n"; } result+="} "+STD_string(get_label())+";\n"; } if(type==parx_parclass_init) { STD_string visabilityString; result="PARX_hide_class (NOT_HIDDEN, \""+STD_string(get_label())+"\");\n"; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter()) { if( (*it)->get_parmode() == hidden) visabilityString="HIDDEN"; else visabilityString="NOT_HIDDEN"; result+="PARX_hide_pars ("+visabilityString+", \""+(*it)->get_label()+"\");\n"; result+="PARX_hide_pars (HIDE_IN_FILE, \""+STD_string((*it)->get_label())+"\");\n"; if( (*it)->get_parmode() == noedit) { result+="PARX_noedit (TRUE, \""+STD_string((*it)->get_label())+"\");\n"; } } } } if(type==parx_parclass_passval) { for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter() && (*it)->get_parx_equiv().name!="" ) { result+=(*it)->get_parx_code(parx_passval_head,(*it)->get_parx_equiv()); } } // result+="PARX_read_file(\""+STD_string(get_label())+"\",\""+equiv.name+"\");\n"; result+="ParxRelsReadClass(\""+STD_string(get_label())+"\","+equiv.name+");\n"; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter() && (*it)->get_parx_equiv().name!="" ) { result+=(*it)->get_parx_code(parx_passval,(*it)->get_parx_equiv()); } } } return result; #else return ""; #endif } int JcampDxBlock::load(const STD_string &filename) { Log odinlog(this,"load"); set_c_locale(); // Make sure we have right locale STD_string blockstr; int retval=::load(blockstr,filename); ODINLOG(odinlog,normalDebug) << "retval(" << filename << ")=" << retval << STD_endl; if(retval) return -1; return parseblock(dos2unix(blockstr)); } int JcampDxBlock::parseblock(const STD_string& source) { Log odinlog(this,"parseblock"); STD_string blocklabel; int result=-1; STD_string parlabel=extract(source,"##","="); if(parlabel=="TITLE") { STD_string source_without_comments=rmblock(source, "\n$$", "\n", true, false); // Remove single-line comments source_without_comments=rmblock(source_without_comments, "$$", "\n", true, false); // Remove remaining end-line comments blocklabel=extract(source_without_comments,"##TITLE=","\n"); set_label(blocklabel); STD_string blockbody(extract(source_without_comments,"##TITLE=","##END=",true)); // Extract body of parameter block, regarding nested structure (blocks within blocks) // blockbody=replaceStr(blockbody,blocklabel+"\n",""); // This seems to be unecessary result=parse_ldr_list(blockbody); } return result; } int JcampDxBlock::write(const STD_string &filename) const { Log odinlog(this,"write"); set_c_locale(); // Make sure we have right locale STD_ofstream outfile(filename.c_str()); JcampDxBlock::print2stream(outfile); outfile.close(); return 0; } unsigned int JcampDxBlock::numof_pars() const { Log odinlog(this,"numof_pars"); unsigned int n=0; ODINLOG(odinlog,normalDebug) << "size()=" << size() << STD_endl; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { ODINLOG(odinlog,normalDebug) << "trying to count parameter ..." << STD_endl; if((*it)->isUserDefParameter()) n++; ODINLOG(odinlog,normalDebug) << "counted parameter >" << (*it)->get_label() << "<" << STD_endl; } return n; } JcampDxBlock& JcampDxBlock::merge(JcampDxBlock& block, bool onlyUserPars) { Log odinlog(this,"merge"); for(iter it=block.get_begin(); it!=block.get_end(); ++it) { if( onlyUserPars ) { if( (*it)->isUserDefParameter() ) append(**it); } else append(**it); } return *this; } JcampDxBlock& JcampDxBlock::unmerge(JcampDxBlock& block) { Log odinlog(this,"unmerge"); for(iter it=block.get_begin(); it!=block.get_end(); ++it) { remove(**it); } return *this; } JcampDxClass* JcampDxBlock::get_parameter(const STD_string& ldrlabel) { Log odinlog(this,"get_parameter"); for(iter it=get_begin(); it!=get_end(); ++it) { if( (*it)->get_label()==ldrlabel ) { return (*it); } } return 0; } bool JcampDxBlock::parameter_exists(const STD_string& ldrlabel) const { Log odinlog(this,"parameter_exists"); bool result=false; if(ldr_exists(ldrlabel)!=get_const_end()) result=true; return result; } JcampDxBlock& JcampDxBlock::set_prefix(const STD_string& prefix) { Log odinlog(this,"set_prefix"); if( STD_string(get_label()).find(prefix) == STD_string::npos ) set_label(prefix+"_"+get_label()); for(iter it=get_begin(); it!=get_end(); ++it) { if((*it)->isUserDefParameter()) { if( STD_string((*it)->get_label()).find(prefix) != 0 ) (*it)->set_label(prefix+"_"+(*it)->get_label()); } } return *this; } JcampDxClass& JcampDxBlock::set_compatmode(compatMode compat_mode) { JcampDxClass::set_compatmode(compat_mode); for(iter it=get_begin(); it!=get_end(); ++it) (*it)->set_compatmode(compat_mode); return *this; } JcampDxClass& JcampDxBlock::set_parmode(parameterMode parameter_mode) { JcampDxClass::set_parmode(parameter_mode); for(iter it=get_begin(); it!=get_end(); ++it) (*it)->set_parmode(parameter_mode); return *this; } JcampDxClass& JcampDxBlock::set_filemode(fileMode file_mode) { JcampDxClass::set_filemode(file_mode); for(iter it=get_begin(); it!=get_end(); ++it) (*it)->set_filemode(file_mode); return *this; } JcampDxClass& JcampDxBlock::operator [] (unsigned int i) { Log odinlog(this,"operator []"); unsigned int n=numof_pars(); if(i>=n) return *this; unsigned int j=0; for(iter it=get_begin(); it!=get_end(); ++it) { if((*it)->isUserDefParameter()) { if(j==i) return *(*it); j++; } } return *this; } const JcampDxClass& JcampDxBlock::operator [] (unsigned int i) const { Log odinlog(this,"operator [] const"); unsigned int n=numof_pars(); if(i>=n) return *this; unsigned int j=0; for(constiter it=get_const_begin(); it!=get_const_end(); ++it) { if((*it)->isUserDefParameter()) { if(j==i) return *(*it); j++; } } return *this; } JcampDxClass& JcampDxBlock::get_parameter_by_id(int id) { for(iter it=get_begin(); it!=get_end(); ++it) { if((*it)->get_parameter_id()==id) return *(*it); } return *this; } JcampDxBlock& JcampDxBlock::append_copy(const JcampDxClass& src) { if(!garbage) garbage=new STD_list; JcampDxClass* ldrcopy=src.create_copy(); garbage->push_back(ldrcopy); append(*ldrcopy); return *this; } JcampDxBlock& JcampDxBlock::create_copy(const JcampDxBlock& src) { JcampDxBlock::operator = (src); if(!garbage) garbage=new STD_list; for(constiter ldr_it=src.get_const_begin(); ldr_it!=src.get_const_end(); ++ldr_it) { if((*ldr_it)->isUserDefParameter()) append_copy(**ldr_it); } return *this; } JcampDxBlock& JcampDxBlock::copy_ldr_vals(const JcampDxBlock& src) { Log odinlog(this,"copy_ldr_vals"); for(constiter ldr_it=src.get_const_begin(); ldr_it!=src.get_const_end(); ++ldr_it) { ODINLOG(odinlog,normalDebug) << "copying " << (*ldr_it)->get_label() << STD_endl; constiter it; if( (it=ldr_exists((*ldr_it)->get_label()))!=get_const_end() ) { STD_string valstring((*ldr_it)->printvalstring()); ODINLOG(odinlog,normalDebug) << "valstring=" << valstring << STD_endl; (*it)->parsevalstring(valstring); } } return *this; } bool JcampDxBlock::compare(const JcampDxBlock& rhs, const STD_list* exclude, double accuracy) const { Log odinlog(this,"compare"); unsigned int mynpars=numof_pars(); unsigned int rhnpars=rhs.numof_pars(); ODINLOG(odinlog,normalDebug) << "mynpars/rhnpars=" << mynpars << "/" << rhnpars << STD_endl; if(mynpars!=rhnpars) return mynpars::const_iterator exclude_begin,exclude_end; if(exclude) { exclude_begin=exclude->begin(); exclude_end=exclude->end(); } for(constiter rh_it=rhs.get_const_begin(); rh_it!=rhs.get_const_end(); ++rh_it) { STD_string parlabel((*rh_it)->get_label()); my_it=ldr_exists(parlabel); if( exclude && (STD_find(exclude_begin, exclude_end, parlabel) != exclude_end ) ) { ODINLOG(odinlog,normalDebug) << "Excluding " << parlabel << " from comparison" << STD_endl; } else { if(my_it==get_const_end()) return true; // 'this' does not include all pars of 'rhs' -> it is 'smaller' // check for type STD_string mytype=(*my_it)->get_typeInfo(); STD_string rhtype=(*rh_it)->get_typeInfo(); ODINLOG(odinlog,normalDebug) << "mytype/rhtype(" << parlabel << ")=" << mytype << "/" << rhtype << STD_endl; if( mytype!=rhtype ) return mytypecast(dumfloat)) ) {myfloat=(*dumfloat); my_is_float=true;} if( (dumdouble=(*my_it)->cast(dumdouble)) ) {myfloat=(*dumdouble); my_is_float=true;} if( (dumfloat=(*rh_it)->cast(dumfloat)) ) {rhfloat=(*dumfloat); rh_is_float=true;} if( (dumdouble=(*rh_it)->cast(dumdouble)) ) {rhfloat=(*dumdouble); rh_is_float=true;} ODINLOG(odinlog,normalDebug) << "my_is_float/rh_is_float(" << parlabel << ")=" << my_is_float << "/" << rh_is_float << STD_endl; if(my_is_float && rh_is_float) { ODINLOG(odinlog,normalDebug) << "myfloat/rhfloat(" << parlabel << ")=" << myfloat << "/" << rhfloat << STD_endl; if(fabs(myfloat-rhfloat)>accuracy) { // Otherwise, values are considered equal ODINLOG(odinlog,normalDebug) << "Unequal myfloat/rhfloat(" << parlabel << ")=" << myfloat << "/" << rhfloat << STD_endl; return myfloatprintvalstring(); STD_string rhval=(*rh_it)->printvalstring(); ODINLOG(odinlog,normalDebug) << "myval/rhval(" << parlabel << ")=" << myval << "/" << rhval << STD_endl; if( myval!=rhval) { ODINLOG(odinlog,normalDebug) << "Unequal myval/rhval(" << parlabel << ")=" << myval << "/" << rhval << STD_endl; return myval odinlog(this,"append_member"); if(ldrlabel!=STD_string("")) ldr.set_label(ldrlabel); append(ldr); return *this; } #ifndef NO_CMDLINE JcampDxBlock& JcampDxBlock::parse_cmdline_options(int argc, char *argv[], bool modify) { char optval[ODIN_MAXCHAR]; for(constiter ldr_it=get_const_begin(); ldr_it!=get_const_end(); ++ldr_it) { STD_string opt((*ldr_it)->get_cmdline_option()); if(opt!="") { STD_string optstr("-"+opt); bool* booldummy=(*ldr_it)->cast(booldummy=NULL); if(booldummy) { if(isCommandlineOption(argc,argv,optstr.c_str())) (*booldummy)=true; } else { if(getCommandlineOption(argc,argv,optstr.c_str(),optval,ODIN_MAXCHAR,modify)) (*ldr_it)->parsevalstring(optval); } } } return *this; } STD_map JcampDxBlock::get_cmdline_options() const { STD_map result; for(constiter ldr_it=get_const_begin(); ldr_it!=get_const_end(); ++ldr_it) { STD_string opt((*ldr_it)->get_cmdline_option()); if(opt!="") { STD_string descr=(*ldr_it)->get_description(); STD_string unit=(*ldr_it)->get_unit(); if(unit!="") descr+=" ["+unit+"]"; // Exclude default value for Boolean types STD_string defval; bool* booldummy=(*ldr_it)->cast(booldummy=0); if(!booldummy) defval=(*ldr_it)->printvalstring(); svector alt=(*ldr_it)->get_alternatives(); if(defval!="" || alt.size()) { descr+=" ("; if(alt.size()) descr+="options="+tokenstring(alt,0)+", "; if(defval!="") descr+="default="+defval+unit; descr+=")"; } result[opt]=descr; } } return result; } STD_string JcampDxBlock::get_cmdline_usage(const STD_string& lineprefix) const { STD_string result; STD_map optmap=get_cmdline_options(); for(STD_map::const_iterator it=optmap.begin(); it!=optmap.end(); ++it) { result += lineprefix+"-"+it->first+": "+it->second+"\n"; } return result; } #endif void JcampDxBlock::init_static() { Log odinlog("JcampDxBlock","init_static"); set_c_locale(); } void JcampDxBlock::destroy_static() { Log odinlog("JcampDxBlock","destroy_static"); } EMPTY_TEMPL_LIST bool StaticHandler::staticdone=false; // Template instantiations template class ListItem; template class List; odin-1.8.5/odinreco/0000755000175000017500000000000011735135552011270 500000000000000odin-1.8.5/odinreco/refgain.cpp0000644000175000017500000001316311322062351013317 00000000000000#include "refgain.h" #include "data.h" #include "controller.h" #include #define _BRIM_POW_ 10 struct RefgainFunction : public ModelFunction { fitpar gain0; double A,C; double start_gain,brim_gain_delta; float evaluate_f(float x) const { return A * ( fabs( sin( C * pow( 10.0, -(x-gain0.val)/20.0 ) ) ) + pow((gain0.val-start_gain)/brim_gain_delta,_BRIM_POW_) ); } fvector evaluate_df(float x) const { fvector result(numof_fitpars()); double power=pow( 10.0, -(x-gain0.val)/20.0 ); double sinus=sin( C * power ); double cosinus=cos( C * power ); result[0] = A *( C*log(10.0)/(20.0) * power * cosinus * sinus + 1.0/(_BRIM_POW_*brim_gain_delta) * pow((gain0.val-start_gain)/brim_gain_delta,_BRIM_POW_-1) )/fabs(sinus); return result; } unsigned int numof_fitpars() const {return 1;} fitpar& get_fitpar(unsigned int i) { if(i==0) return gain0; return dummy_fitpar; } }; /////////////////////////////////////////////////////////////////////////// int first_max_index(const Array& vec, float thresh) { int n=vec.numElements(); if(n==0) return 0; float max=vec(0); int maxindex=n-1; bool maxfound=false; int i; for(i=1;i<(n-1);i++) { if(vec(i)>max && vec(i+1)thresh) { maxfound=true; break; } } if(maxfound) maxindex=i; else maxindex=n-1; return maxindex; } /////////////////////////////////////////////////////////////////////////// int first_min_index(const Array& vec, float thresh) { int n=vec.numElements(); if(n==0) return 0; float min=vec(0); int minindex=n-1; bool minfound=false; int i; for(i=1;i<(n-1);i++) { if(vec(i)vec(i) && vec(i)>thresh) { minfound=true; break; } } if(minfound) minindex=i; else minindex=n-1; return minindex; } /////////////////////////////////////////////////////////////////////////// void RecoRefGain::init() { pulsedur=0.0; pulsedur.set_description("Pulse duration"); append_arg(pulsedur,"pulsedur"); pulsegain=0.0; pulsegain.set_description("Pulse gain"); append_arg(pulsegain,"pulsegain"); } #define NOISELEVEL_FIRSTMAX 0.2 #define BRIM_REFGAIN 3.0 #define MIN_REFGAIN -1000.0 #define MAX_REFGAIN 1000.0 #define _REFERENCE_GAIN_BP_PARAVISION_ 0.9 bool RecoRefGain::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); Data magn(cabs(indata)); TinyVector inshape=indata.shape(); float noiselevel=0.2*max(magn); int nrefg=inshape(0); int nline3d=inshape(1); int nline=inshape(2); int nread=inshape(3); ODINLOG(odinlog,normalDebug) << "nrefg/nline3d/nline/nread=" << nrefg << "/" << nline3d << "/" << nline << "/" << nread << STD_endl; RefgainFunction refgf; FunctionFit refgfit(refgf,nrefg,10000,0.001); refgf.C=pulsedur*0.5*PII; int anglecounter; double refgain; double absval; double weightsum=0.0; double refgsum=0.0; dvector attenuations=controller.dim_values(userdef); if(int(attenuations.size())!=nrefg) { ODINLOG(odinlog,errorLog) << "attenuations.size()=" << attenuations.size() << " does not match nrefg=" << nrefg << STD_endl; return false; } Data pixel(nrefg); Data yvals(nrefg); Data xvals(nrefg); for(int i=0; i refgmap(nline3d,nline,nread); for(int iline3d=0; iline3d noiselevel ) { pixel=magn(all,iline3d,j,i); int minmaxindex=0; int prevminmaxindex=0; int firstmaxindex=0; anglecounter=0; // find the first maximum above the noise threshhold float threshhold=NOISELEVEL_FIRSTMAX*max(pixel); minmaxindex=first_max_index(pixel,threshhold); xvals(anglecounter)=pow(10.0,-attenuations[minmaxindex]/20.0); yvals(anglecounter)=(double)(anglecounter+1); anglecounter++; prevminmaxindex=minmaxindex; firstmaxindex=minmaxindex; // if only one max is found, calculate refgain according to a 90deg pulse refgain=0.0; if(anglecounter==1) { refgain=attenuations[firstmaxindex]+20.0*log10(secureInv(pulsedur))-pulsegain; } // non-linear fit refgf.A=pixel(firstmaxindex); refgf.start_gain=refgain+pulsegain; refgf.brim_gain_delta=BRIM_REFGAIN; refgf.gain0.val=refgain+pulsegain; refgfit.fit(pixel,Array(0),xvals); refgain=refgf.gain0.val-pulsegain; if(refgainMAX_REFGAIN) refgain=0.0; if(refgain!=0.0) { double fitweight=secureInv(refgf.gain0.err); refgsum+=refgain*fitweight; weightsum+=fitweight; } refgmap(iline3d,j,i)=refgain+_REFERENCE_GAIN_BP_PARAVISION_; } else { refgmap(iline3d,j,i)=0.0; } } } } double avrefgain=secureDivision(refgsum,weightsum); ODINLOG(odinlog,infoLog) << "average refgain=" << avrefgain << STD_endl; STD_string valfile=STD_string(secure_getenv("HOME"))+"/.odin/opdir/odin_refgain"; ::write(ftos(avrefgain),valfile); system(("chmod 666 "+valfile).c_str()); ComplexData<3>& outdata=rd.data(Rank<3>()); outdata.resize(nline3d,nline,nread); outdata=float2real(refgmap); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/fieldmap.cpp0000644000175000017500000002722011713467630013501 00000000000000#include "fieldmap.h" #include "data.h" #include "controller.h" #include #include bool RecoFieldMap::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); ODINLOG(odinlog,normalDebug) << "inshape/outshape=" << inshape << "/" << outshape << STD_endl; dvector tes=controller.dim_values(te); ODINLOG(odinlog,normalDebug) << "tes=" << tes.printbody() << STD_endl; if(int(tes.size())!=inshape(0)) { ODINLOG(odinlog,errorLog) << "TE size mismatch: " << tes.size() << "!=" << inshape(0) << STD_endl; return false; } if(inshape(0)<2) { ODINLOG(odinlog,errorLog) << "too few number of TEs: " << inshape(0) << STD_endl; return false; } bool oddeven=(inshape(0)>2); // Assume odd and even echoes (EPI-type readtout) for more than 2 TEs int npol=1; if(oddeven) npol=2; int ntes[npol]; if(oddeven) { ntes[0]=ntes[1]=inshape(0)/2; if(inshape(0)%2) ntes[0]++; } else { ntes[0]=inshape(0); } ODINLOG(odinlog,normalDebug) << "oddeven/inshape(0)/npol/ntes[0]/ntes[1]=" << oddeven << "/" << inshape(0) << "/" << npol << "/" << ntes[0] << "/" << ntes[1] << STD_endl; // regroup odd and even data ComplexData<4> tedata[2]; Data pixel[2]; Data magn[2]; ComplexData<1> pixel_complex[2]; Data sigma[2]; Data tevals[2]; for(int ipol=0; ipol(cabs(tedata[ipol])).autowrite("cabs_"+idstr+".nii"); Data(phase(tedata[ipol])).autowrite("phase_"+idstr+".nii"); } */ Data reliability(outshape); reliability(all,all,all)=cabs(indata(0,all,all,all)); // Take 1st echo for reliability based on image magnitude float noiselevel=0.6*mean(reliability); indata.free(); Data fieldmap(outshape); fieldmap=0.0; // ComplexData<3> cplxphase(outshape); cplxphase=STD_complex(0.0); LinearFunction linf; for(int ipol=0; ipol srcshape=it->second.shape(); if(srcshape!=dstshape) { ODINLOG(odinlog,errorLog) << "shape mismatch: srcshape" << srcshape << "!=dstshape" << dstshape << STD_endl; return false; } fieldmap.reference(it->second.copy()); // Deep copy for multi-threaded access calc_fmap=false; } fmapmutex.unlock(); if(calc_fmap) { if(!controller.data_announced(posted_fmap_str)) { ODINLOG(odinlog,errorLog) << "fieldmap not available" << STD_endl; return false; } RecoData rdfieldmap(fmapcoord); rdfieldmap.coord().index[cycle] = 0; // reset to 0 to only get initial (not rotated) field map if(!controller.inquire_data(posted_fmap_str, rdfieldmap)) return false; float os_fmap = rdfieldmap.coord().overSamplingFactor; float os_user = fmapcoord.overSamplingFactor; // float osFactor = secureDivision(os_user, os_fmap); ODINLOG(odinlog,normalDebug) << "os_fmap/os_user=" << os_fmap << "/" << os_user << STD_endl; Data fmreal(creal(rdfieldmap.data(Rank<3>()))); TinyVector fmshape(fmreal.shape()); ODINLOG(odinlog,normalDebug) << "fmshape/dstshape=" << fmshape << "/" << dstshape << STD_endl; // spatial shifting TinyVector reloffset=controller.reloffset(); reloffset(0) = 0; // set zero to only shift in phase and readout direction, shifting in slice direction is not necessary because no rotation is done in slice direction reloffset(2)/=os_fmap; bool do_shift=false; if(max(abs(reloffset))>0.0) do_shift=true; // create mask for weighting Data mask(fmshape); mask=where(Array(fmreal)!=0.0, float(1.0), float(0.0)); // mask.autowrite("mask_"+rdfieldmap.coord().print(RecoIndex::filename)+".nii"); // prepare shapes and vars for gridder STD_vector > src_coords(product(fmshape)); TinyVector image_center = 0.5 * (fmshape-1); // index of center in image space TinyVector srcfov; srcfov = 0.0; TinyVector dstfov; dstfov = 0.0; if (fmshape(0) > 1) srcfov(0) = controller.protocol().geometry.get_FOV(sliceDirection); if (dstshape(0) > 1) dstfov(0) = controller.protocol().geometry.get_FOV(sliceDirection); // Only regridding in line3d direction if dimension > 1 srcfov(1) = dstfov(1) = controller.protocol().geometry.get_FOV(phaseDirection); srcfov(2) = os_fmap*controller.protocol().geometry.get_FOV(readDirection); dstfov(2) = os_user*controller.protocol().geometry.get_FOV(readDirection); ODINLOG(odinlog,normalDebug) << "srcfov=" << srcfov << STD_endl; ODINLOG(odinlog,normalDebug) << "dstfov=" << dstfov << STD_endl; bool hasBlades = (fmapcoord.index[cycle].get_numof() > 1); int iblade = fmapcoord.index[cycle]; dvector angles; if (hasBlades) { angles = controller.dim_values(cycle); ODINLOG(odinlog,normalDebug) << "angles=" << angles.printbody() << STD_endl; hasBlades = (angles.length() == fmapcoord.index[cycle].get_numof()); // check for spiral or propeller } ODINLOG(odinlog,normalDebug) << "hasBlades=" << hasBlades << STD_endl; int isrc = 0; TinyVector coord; for (int islice = 0; islice < fmshape(0); islice++) { for (int iphase = 0; iphase < fmshape(1); iphase++) { for (int iread = 0; iread < fmshape(2); iread++) { TinyVector index3d(islice, iphase, iread); coord = (index3d - image_center) / fmshape * srcfov; double angle_rad = 0.0; if(hasBlades) angle_rad = angles[iblade]; // not reversed rotation... GriddingPoint<3>& src_point=src_coords[isrc]; src_point.coord = coord; src_point.weight = mask(islice,iphase,iread); if(angle_rad) { TinyVector coord_min = -image_center / fmshape * srcfov; TinyVector coord_max = image_center / fmshape * srcfov; if (do_shift) { // Shift to center src_point.coord -= reloffset * srcfov; if (src_point.coord(1) < coord_min(1)) src_point.coord(1) = coord_max(1) - (coord_min(1) - src_point.coord(1)); if (src_point.coord(2) < coord_min(2)) src_point.coord(2) = coord_max(2) - (coord_min(2) - src_point.coord(2)); if (src_point.coord(1) >= coord_max(1)) src_point.coord(1) = coord_min(1) + (src_point.coord(1) - coord_max(1)); if (src_point.coord(2) >= coord_max(2)) src_point.coord(2) = coord_min(2) + (src_point.coord(2) - coord_max(2)); } // Rotation float si=sin(angle_rad); float co=cos(angle_rad); TinyVector coord_temp = src_point.coord; src_point.coord(0)=coord_temp(0); src_point.coord(1)=co*coord_temp(1)-si*coord_temp(2); src_point.coord(2)=si*coord_temp(1)+co*coord_temp(2); if (do_shift) { // Shift back TinyVector reloffset_rot; reloffset_rot(0)=reloffset(0); reloffset_rot(1)=co*reloffset(1)-si*reloffset(2); reloffset_rot(2)=si*reloffset(1)+co*reloffset(2); src_point.coord += reloffset_rot * srcfov; if (src_point.coord(1) < coord_min(1)) src_point.coord(1) = coord_max(1) - (coord_min(1) - src_point.coord(1)); if (src_point.coord(2) < coord_min(2)) src_point.coord(2) = coord_max(2) - (coord_min(2) - src_point.coord(2)); if (src_point.coord(1) >= coord_max(1)) src_point.coord(1) = coord_min(1) + (src_point.coord(1) - coord_max(1)); if (src_point.coord(2) >= coord_max(2)) src_point.coord(2) = coord_min(2) + (src_point.coord(2) - coord_max(2)); } } isrc++; } } } JDXfilter gridkernel; gridkernel.set_function("Gauss"); float kwidth = 1.5*max(dstfov/dstshape); ODINLOG(odinlog,normalDebug) << "kwidth=" << kwidth << STD_endl; Gridding gridder; gridder.init(dstshape, dstfov, src_coords, gridkernel, kwidth); fieldmap.reference(gridder(fmreal)); fmapmutex.lock(); fmap[fmapcoord].reference(fieldmap); fmapmutex.unlock(); } return true; } void RecoFieldMapUser::modify4fieldmap(RecoCoord& coord) { for(int idim=0; idim& adc); const STD_vector& get_coords() const; dvector dim_values(recoDim dim) const {return recoInfo.get_DimValues(dim);} const TinyVector& reloffset() const {return reloffset_cache;} STD_string image_proc() const {return image_proc_cache;} const TinyVector& image_size() const {return size_cache;} const Protocol& protocol() const {return prot_cache;} STD_string seqrecipe() const {return recoInfo.get_Recipe();} STD_string postProc3D() const {return recoInfo.get_PostProc3D();} STD_string preProc3D() const {return recoInfo.get_PreProc3D();} STD_string cmdline_opts() const {return recoInfo.get_CmdLineOpts();} void kcoord2coord(const kSpaceCoord& kcoord, RecoCoord& coord) const; static bool concat_data(STD_string& rawfile, const STD_string& scandir, const STD_string& fnameprefix); template bool read_block(T2 dummy, ComplexData<2>& block); JDXstring fifoFile; JDXbool padZero; // read only in fetch() unsigned int nadc; int zeroesPerChunk; unsigned int rawtypesize; // cached values unsigned int nChannels_cache; TinyVector reloffset_cache; STD_string image_proc_cache; TinyVector size_cache; Protocol prot_cache; ReadoutShape readoutShape_cache[MAX_NUMOF_READOUT_SHAPES]; KspaceTraj kspaceTraj_cache[MAX_NUMOF_KSPACE_TRAJS]; ComplexData<1> weightVec_cache[MAX_NUMOF_ADC_WEIGHTING_VECTORS]; Data channelFactors; // data used during reco RecoPars recoInfo; STD_string dataformat; ComplexData<2> rawdata; // cache rawdata because all channels are loaded at once STD_string rawdata_filename; FILE* rawdata_fileptr; unsigned int index; // counter for indexing ADCs (each channel increments this counter) unsigned int ri_index; // index for ADCs in recoInfo kSpaceCoord kcoord_cache; // cache num of channels and crop size of current ADC unsigned int chancount; // counter for channels mutable STD_vector coord_vec_cache; }; /** @} */ #endif odin-1.8.5/odinreco/bladegrid.h0000644000175000017500000000310611363773557013310 00000000000000/*************************************************************************** bladegrid.h - description ------------------- begin : Fri Jan 07 2009 copyright : (C) 2009 by Martin Krämer email : MartinKraemer@gmx.net ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef BLADEGRID_H #define BLADEGRID_H #include #include #include "odinreco.h" class BladeGrid { public: bool init(const TinyVector& inshape, const TinyVector fov, const TinyVector image_size, const float os_factor, const JDXfilter& filterkernel); ComplexData<4> operator () (const ComplexData<4>& src, const dvector& angles) const; private: Data filtermask_center; TinyVector dstextent; TinyVector dstshape; TinyVector kmax; }; #endif odin-1.8.5/odinreco/fmri.cpp0000644000175000017500000000500211322062351012632 00000000000000#include "fmri.h" #include "data.h" #include "controller.h" #include void RecoFMRI::init() { stimsize=0; stimsize.set_description("Number of repetitions during stimulation"); append_arg(stimsize,"stimsize"); restsize=0; restsize.set_description("Number of repetitions during rest"); append_arg(restsize,"restsize"); } bool RecoFMRI::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); if(!stimsize || !restsize) { ODINLOG(odinlog,errorLog) << "stimsize/restsize=" << stimsize << "/" << restsize << STD_endl; return false; } ComplexData<4>& indata=rd.data(Rank<4>()); Data magn(cabs(indata)); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); int nrep=inshape(0); int blocksize=stimsize+restsize; Data design(nrep); design=0.0; for(int irep=0; irep overlay(outshape); for(int iphase3d=0; iphase3d tcourse(nrep); for(int iphase3d=0; iphase3d()).free(); rd.data(Rank<3>()).resize(outshape); rd.data(Rank<3>())=float2real(overlay); rd.coord().index[repetition]=0; return execute_next_step(rd,controller); } odin-1.8.5/odinreco/phasecourse.cpp0000644000175000017500000000307411734622163014237 00000000000000#include "phasecourse.h" #include "data.h" #include bool RecoPhaseCourse::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<5>& indata=rd.data(Rank<5>()); TinyVector inshape=indata.shape(); int nchan=inshape(0); int nrep=inshape(1); int nline3d=inshape(2); int nphase=inshape(3); int nread =inshape(4); TinyVector outshape(nrep, nline3d, nphase, nread); ODINLOG(odinlog,normalDebug) << "outshape=" << outshape << STD_endl; Data outdata(outshape); Data unwrapped(nrep); ComplexData<1> cplx1d(nrep); ComplexData<1> cplxsum(nrep); LinearFunction linf; for(int iline3d=0; iline3d()).reference(float2real(outdata)); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/phasecourse.h0000644000175000017500000000324311322062351013670 00000000000000/*************************************************************************** phasecourse.h - description ------------------- begin : Thu May 28 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOPHASECOURSE_H #define RECOPHASECOURSE_H #include "step.h" class RecoPhaseCourse : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "phasecourse";} STD_string description() const {return "Combine phase timecourse from multi-channel data";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,channel,repetition,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single,channel);} RecoStep* allocate() const {return new RecoPhaseCourse;} void init() {} }; #endif odin-1.8.5/odinreco/b1fit.h0000644000175000017500000000333711322062351012360 00000000000000/*************************************************************************** b1fit.h - description ------------------- begin : Tue Oct 16 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOB1FIT_H #define RECOB1FIT_H #include "step.h" class RecoB1Fit : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "b1fit";} STD_string description() const {return "B1-mapping method based on: Fast, Accurate, and Precise Mapping of the RF Field In Vivo Using the 180 Signal Null. Dowell et al., Magn Reson Med 58 (2007).";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,userdef,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single,userdef);} RecoStep* allocate() const {return new RecoB1Fit;} void init() {} }; #endif odin-1.8.5/odinreco/conjphase.h0000644000175000017500000000330611322062351013321 00000000000000/*************************************************************************** conjphase.h - description ------------------- begin : Wed Jun 6 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOCONJPHASE_H #define RECOCONJPHASE_H #include "fieldmap.h" class RecoConjPhaseFT : public RecoFieldMapUser { // implementing virtual functions of RecoStep STD_string label() const {return "conjphase";} STD_string description() const {return "Discrete Fourier transform with conjugate-phase correction according to field map";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::collected, line3d, line);} RecoStep* allocate() const {return new RecoConjPhaseFT;} void init() {} Mutex trajmutex; }; #endif odin-1.8.5/odinreco/messer.h0000644000175000017500000000315511322062351012647 00000000000000/*************************************************************************** messer.h - description ------------------- begin : Thu Apr 9 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOMESSER_H #define RECOMESSER_H #include "step.h" class RecoMesser : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "messer";} STD_string description() const {return "Postprocessing for MESSER sequence";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,userdef,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::separate,userdef);} RecoStep* allocate() const {return new RecoMesser;} void init() {} }; #endif odin-1.8.5/odinreco/measindex.cpp0000644000175000017500000000003011322062351013646 00000000000000#include "measindex.h" odin-1.8.5/odinreco/switch.cpp0000644000175000017500000001404611322062351013206 00000000000000#include "switch.h" #include "controller.h" #include "data.h" void RecoSwitch::init() { brancharg.set_description("A semicolon-separated list of entries in the form 'dim=value {sub-pipeline}' where 'dim' can \ be any of the dimensions in recoDim, 'value' is an integer number (or character from templateTypeChar) \ and 'sub-pipeline' is a pipeline to be executed when the index of the input in dimension 'dim' matches 'value'. \ If the 'dim=value' is omitted, the pipeline will be executed for each incoming data."); append_arg(brancharg,"brancharg"); } bool RecoSwitch::pipeline_init(const RecoController& controller, const RecoCoord& input_coord) { Log odinlog(c_label(),"pipeline_init"); svector branchstr(tokens(brancharg,';','{','}')); for(unsigned int ibranch=0; ibranch > class RecoMeasIndex { public: /** * Initialize with coordinate 'coord' in this branch of the pipeline using 'controller'. */ bool init(const RecoCoord& coord, const RecoController& controller) { Log odinlog("RecoMeasIndex","init"); RecoCoord coord4count(coord); prep_coord(coord4count); coord4count.set_mode(RecoIndex::separate, dim); const CoordCountMap* countmap=controller.create_count_map(coord4count); if(!countmap) return false; init_countmap=(*countmap); // create deep copy because countmap may be deleted by controller after prep return create_measmap(init_countmap); } /** * Update cache of measured/interpolated coords by adding 'extra' to the initial coordinates. */ bool update(const CoordCountMap& extra) { Log odinlog("RecoMeasIndex","update"); if(!extra.size()) return true; CoordCountMap countmap_copy(init_countmap); ODINLOG(odinlog,normalDebug) << "countmap_copy/extra.size()=" << countmap_copy.size() << "/" << extra.size() << STD_endl; for(CoordCountMap::const_iterator it=extra.begin(); it!=extra.end(); ++it) countmap_copy[it->first]+=it->second; return create_measmap(countmap_copy); } /** * Returns the list of indices for coordinate 'coord'. */ ivector get_indices(const RecoCoord& coord) const { Log odinlog("RecoMeasIndex","get_indices"); ivector result; RecoCoord coord4meas(coord); prep_coord(coord4meas); coord4meas.set_mode(RecoIndex::ignore,dim); MeasMap::const_iterator it=measmap.find(coord4meas); if(it==measmap.end()) { ODINLOG(odinlog,normalDebug) << "<" << recoDimLabel[dim] << ">: No indices for coordinate " << coord4meas.print() << STD_endl; } else { result=it->second; ODINLOG(odinlog,normalDebug) << "coord4meas/it=" << coord4meas.print() << "/" << it->first.print() << STD_endl; ODINLOG(odinlog,normalDebug) << "result=" << result.printbody() << STD_endl; } return result; } private: static void prep_coord(RecoCoord& coord) { Ignore::modify(RecoIndex::ignore, coord); Separate::modify(RecoIndex::separate, coord); } bool create_measmap(const CoordCountMap& countmap) { Log odinlog("RecoMeasIndex","create_measmap"); STD_map > indexlist; for(CoordCountMap::const_iterator it=countmap.begin(); it!=countmap.end(); ++it) { RecoCoord coord4indexlist(it->first); coord4indexlist.set_mode(RecoIndex::ignore, dim); // collapse index, indices will be stored in the index vectors of measmap indexlist[coord4indexlist].push_back(it->first.index[dim]); } for(STD_map >::iterator lstit=indexlist.begin(); lstit!=indexlist.end(); ++lstit) { STD_list& lstref=lstit->second; lstref.sort(); lstref.unique(); measmap[lstit->first]=list2vector(lstref); } for(MeasMap::const_iterator mapit=measmap.begin(); mapit!=measmap.end(); ++mapit) { ODINLOG(odinlog,normalDebug) << "measmap[" << mapit->first.print() << "]=" << mapit->second.printbody() << STD_endl; } return true; } CoordCountMap init_countmap; typedef STD_map MeasMap; MeasMap measmap; // will be initialized during init }; #endif odin-1.8.5/odinreco/data.cpp0000644000175000017500000000167311734622163012632 00000000000000#include "data.h" #include RecoData::~RecoData() { if (prof) delete prof; } RecoData& RecoData::copy_meta(const RecoData& rd) { kcoord=rd.kcoord; override_protocol=rd.override_protocol; mode=rd.mode; interpolated=rd.interpolated; return *this; } RecoData& RecoData::free(int dim) { if(dim==1) data1.free(); if(dim==2) data2.free(); if(dim==3) data3.free(); if(dim==4) data4.free(); if(dim==5) data5.free(); if(dim==6) data6.free(); return *this; } RecoData& RecoData::operator = (const RecoData& rd) { data1.reference(rd.data1.copy()); data2.reference(rd.data2.copy()); data3.reference(rd.data3.copy()); data4.reference(rd.data4.copy()); data5.reference(rd.data5.copy()); data6.reference(rd.data6.copy()); return copy_meta(rd); } void RecoData::new_profiler(const STD_string& steplabel) { #ifdef ODIN_DEBUG if(prof) delete prof; prof=new Profiler("RecoStep->"+steplabel); #endif } odin-1.8.5/odinreco/qualitycontrol.h0000644000175000017500000000342311725203123014441 00000000000000/*************************************************************************** qualitycontrol.h - description ------------------- begin : Tue Feb 28 2011 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef QUALITYCONTROL_H #define QUALITYCONTROL_H #include "step.h" class RecoQualityControlSpike : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "qcspike";} STD_string description() const {return "Check for spikes in data";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoQualityControlSpike;} void init() {} STD_map spikecount; // separately for each channel Mutex spikemutex; LONGEST_INT total_acqpts; Mutex totalmutex; }; #endif odin-1.8.5/odinreco/circmask.h0000644000175000017500000000310311322062351013136 00000000000000/*************************************************************************** circmask.h - description ------------------- begin : Thu Sep 3 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOCIRCMASK_H #define RECOCIRCMASK_H #include "step.h" class RecoCircMask : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "circmask";} STD_string description() const {return "Cut out central circular region.";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoCircMask;} void init() {} }; #endif odin-1.8.5/odinreco/adc.h0000644000175000017500000000760711455553545012127 00000000000000/*************************************************************************** adc.h - description ------------------- begin : Mon Jan 22 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOADC_H #define RECOADC_H #include "step.h" class RecoAdcReflect : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "adc_reflect";} STD_string description() const {return "Reflect ADC if recoReflectBit is set";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoAdcReflect;} void init() {} }; //////////////////////////////////////////////////////// class RecoAdcGridPrep : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "adc_gridprep";} STD_string description() const {return "Prepare ADC for gridding (ramp sampling)";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoAdcGridPrep;} void init() {} KspaceTraj traj; // caching trajectory Mutex trajmutex; }; //////////////////////////////////////////////////////// class RecoAdcWeight : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "adc_weight";} STD_string description() const {return "Weight ADC using weightVec";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoAdcWeight;} void init() {} Mutex weightMutex; // to protect global Blitz array which contains weightVec }; //////////////////////////////////////////////////////// class RecoAdcBaseline : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "adc_baseline";} STD_string description() const {return "Baseline correction of ADCs";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoAdcBaseline;} void init() {} }; ///////////////////////////////////////////////////////////////// class RecoAdcPad : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "adc_pad";} STD_string description() const {return "Pad missing points by zeroes";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoAdcPad;} void init() {} }; #endif odin-1.8.5/odinreco/dti.h0000644000175000017500000000302711322062351012127 00000000000000/*************************************************************************** dti.h - description ------------------- begin : Thu Oct 29 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECODTI_H #define RECODTI_H #include "step.h" class RecoDTI : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "dti";} STD_string description() const {return "DTI preprocessing";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoDTI;} void init() {} }; #endif odin-1.8.5/odinreco/fft.h0000644000175000017500000000305511322062351012127 00000000000000/*************************************************************************** fft.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOFFT_H #define RECOFFT_H #include "step.h" class RecoFFT : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "fft";} STD_string description() const {return "Fast Fourier Transform";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoFFT;} void init(); JDXbool forward; }; #endif odin-1.8.5/odinreco/mip.h0000644000175000017500000000311011322062351012125 00000000000000/*************************************************************************** mip.h - description ------------------- begin : Tue Dec 4 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOMIP_H #define RECOMIP_H #include "step.h" class RecoMip : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "mip";} STD_string description() const {return "Maximum intensity projection in slice direction";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoMip;} void init(); JDXint neighbors; }; #endif odin-1.8.5/odinreco/grappa.h0000644000175000017500000001044511363773557012651 00000000000000/*************************************************************************** grappa.h - description ------------------- begin : Fri Feb 2 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOGRAPPA_H #define RECOGRAPPA_H #include "step.h" #include "measindex.h" /////////////////////////////////////////////////////////////////////////////////////////////////////////// // NOTE: Dimensions of the weights are: dstchannel * reduction index * srcchannel * phase * read template > class RecoGrappaWeights : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const { STD_string result="grappaweights"; if(Ignore::dim()>0) result+="templ"; if(interpolDim==line3d) result+="3d"; return result; } STD_string description() const {return "Calculate GRAPPA weights in dimension '"+STD_string(recoDimLabel[interpolDim])+"' and post them on the blackboard with the label 'grappaweights_"+recoDimLabel[interpolDim]+"'.";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,channel,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoGrappaWeights;} void init(); JDXint reduction_factor; JDXint neighbours_read; JDXint neighbours_phase; JDXfloat svd_trunc; JDXfloat discard_level; // helper functions ivector acl_lines(const RecoCoord& coord, int numof_neighb, int ired) const; bool calc_weights(ComplexData<5>& weights, const RecoCoord& trainingcoord, const ComplexData<4>& trainingdata); // Instance of RecoMeasIndex to get k-space sampling pattern, // i.e. hase-encoding lines actually measured, // by assuming the same for channel, freq, repetition and separate // schemes for the orthogonal phase-encoding direction RecoMeasIndex, RecoDim<1,orthoDim> > measlines; }; /////////////////////////////////////////////////////////////////////////////////////////////////////////// template class RecoGrappa : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {if(interpolDim==line3d) return "grappa3d"; else return "grappa";} STD_string description() const {return "Perform GRAPPA interpolation in dimension '"+STD_string(recoDimLabel[interpolDim])+"'";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,channel,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoGrappa;} void init(); JDXint reduction_factor; JDXbool keep_shape; // helper functions int reduction_index(const ivector& indexvec, int sizePhase, int iphase) const; bool correct_shape(RecoData& rdkspace, const RecoController& controller) const; // Instance of RecoMeasIndex to get k-space sampling pattern, // i.e. hase-encoding lines actually measured, // by assuming the same for channel, freq, repetition and separate // schemes for the orthogonal phase-encoding direction RecoMeasIndex, RecoDim<1,orthoDim> > measlines; }; #endif odin-1.8.5/odinreco/sum.h0000644000175000017500000000460111322062351012152 00000000000000/*************************************************************************** sum.h - description ------------------- begin : Thu Mar 8 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSUM_H #define RECOSUM_H #include "step.h" /* * Template class to sum up data in one or more dimensions. * The rank of the unmodified collected data dimensions is is given by 'Nunmod'. * The particular unmodified dimension are given in 'Unmod' by a specialization of 'RecoDim'. * The numer of dimensions to sum up is given in 'Nsum' and specified in 'Sum' by * a specialization of 'RecoDim'. * The dimensions to sum up are expected leftmost in the input data array. * The optional parameter 'Magn' specifies whether only the magnitude will * be accumulated instead of the complex values. */ template class RecoSum : public RecoStep, public Labeled { public: RecoSum(const STD_string& sum_label) : Labeled(sum_label) {} private: // implementing virtual functions of RecoStep STD_string label() const {return get_label();} STD_string description() const {return "Sum up data in one or more dimensions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {RecoCoord result=Unmod::preset_coord(RecoIndex::collected); Sum::modify(RecoIndex::collected,result); return result;} void modify_coord(RecoCoord& coord) const {Sum::modify(RecoIndex::single,coord);} RecoStep* allocate() const {return new RecoSum(get_label());} void init() {} }; #endif odin-1.8.5/odinreco/swi.h0000644000175000017500000000304711322062351012153 00000000000000/*************************************************************************** swi.h - description ------------------- begin : Fri Sep 14 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSWI_H #define RECOSWI_H #include "step.h" class RecoSwi : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "swi";} STD_string description() const {return "Susceptibility weighted imaging";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoSwi;} void init() {} }; #endif odin-1.8.5/odinreco/messer.cpp0000644000175000017500000001154711363773557013234 00000000000000#include "messer.h" #include "data.h" #include "controller.h" #include #define NOISELEVEL 0.3 #define MAXT2 1000.0 bool RecoMesser::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); Protocol prot(controller.protocol()); // Local copy of protocol, used for override_protocol float TEse=prot.seqpars.get_EchoTime(); dvector tes=controller.dim_values(userdef); ODINLOG(odinlog,normalDebug) << "tes=" << tes.printbody() << STD_endl; int ntes=inshape(0); if(ntes!=int(tes.size())) { ODINLOG(odinlog,errorLog) << "ntes=" << ntes << " does not match tes.size()=" << tes.size() << STD_endl; return false; } int nfid=0; int nser=0; for(int ite=0; ite fidlog(nfid); Data fidsigma(nfid); Data fidte(nfid); Data serlog(nser); Data sersigma(nser); Data serte(nser); int ite=0; for(int i=0; i pixel(ntes); Data T2(outshape); T2=0.0; Data T2star(outshape); T2star=0.0; Data S0(outshape); S0=0.0; Data SE(outshape); SE=0.0; for(int iphase3d=0; iphase3dnoiselevel) { ite=0; float R2star=0.0; float R2minus=0.0; float s0=0.0; float se=0.0; // signal at Spin-Echo // fit FID part if(nfid) { for(int i=0; i(t2, 0.0, MAXT2); check_range(t2star, 0.0, MAXT2); T2star(iphase3d,iphase,iread)=t2star; T2(iphase3d,iphase,iread)=t2; S0(iphase3d,iphase,iread)=s0; SE(iphase3d,iphase,iread)=se; } } } } // modify coordinate rd.coord().index[userdef].set_numof(ntes+4); int iuserdef=0; rd.override_protocol=&prot; STD_string series; int number; prot.study.get_Series(series, number); // feed echoes separately into rest of pipeline for(ite=0; ite()).resize(outshape); rdecho.data(Rank<3>())=indata(ite,all,all,all); rdecho.coord().index[userdef]=iuserdef; prot.study.set_Series(series+"_TE"+ftos(tes[ite]),number); if(!execute_next_step(rdecho,controller)) return false; iuserdef++; } // feed T2star into rest of pipeline RecoData rdT2star(rd); rdT2star.data(Rank<3>()).resize(outshape); rdT2star.data(Rank<3>())=float2real(T2star); rdT2star.coord().index[userdef]=iuserdef; prot.study.set_Series(series+"_T2star",number); if(!execute_next_step(rdT2star,controller)) return false; iuserdef++; // feed T2 into rest of pipeline RecoData rdT2(rd); rdT2.data(Rank<3>()).resize(outshape); rdT2.data(Rank<3>())=float2real(T2); rdT2.coord().index[userdef]=iuserdef; prot.study.set_Series(series+"_T2",number); if(!execute_next_step(rdT2,controller)) return false; iuserdef++; // feed S0 into rest of pipeline RecoData rdS0(rd); rdS0.data(Rank<3>()).resize(outshape); rdS0.data(Rank<3>())=float2real(S0); rdS0.coord().index[userdef]=iuserdef; prot.study.set_Series(series+"_S0",number); if(!execute_next_step(rdS0,controller)) return false; iuserdef++; // feed SE into rest of pipeline RecoData rdSE(rd); rdSE.data(Rank<3>()).resize(outshape); rdSE.data(Rank<3>())=float2real(SE); rdSE.coord().index[userdef]=iuserdef; prot.study.set_Series(series+"_SE",number); if(!execute_next_step(rdSE,controller)) return false; iuserdef++; return true; } odin-1.8.5/odinreco/splitter_code.h0000644000175000017500000000445311322062351014213 00000000000000#include "splitter.h" #include "data.h" template bool RecoSplitter::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); // create new view of input data ComplexData& indata=rd.data(Rank()); TinyVector splitshape; for(int i=0; i outshape; for(int i=0; i outshape_padded=1; for(unsigned int i=0; i lowin=0; TinyVector uppin=outshape_padded-1; TinyVector lowout=0; TinyVector uppout=outshape_padded-1; // output domain, the same for each dataset RectDomain outdomain(lowout,uppout); ComplexData outdata_padded(outshape_padded); ComplexData outdata(outshape); for(int isplit=0; isplit splitindex=index2extent(splitshape, isplit); // set input inidices for(unsigned int i=0; i indomain(lowin,uppin); outdata_padded(outdomain)=indata(indomain); outdata_padded.convert_to(outdata); // bring to output shape // set data and index and feed data into rest of pipeline RecoData rdout; // separate data object since indata is just a reference rdout.copy_meta(rd); // Use all meta data from indata Split::modify(RecoIndex::separate, rdout.coord()); Split::set_index(splitindex, rdout.coord()); rdout.data(Rank()).reference(outdata); if(!execute_next_step(rdout,controller)) return false; } return true; } odin-1.8.5/odinreco/fieldmap.h0000644000175000017500000000411011322062351013122 00000000000000/*************************************************************************** fieldmap.h - description ------------------- begin : Mon Feb 25 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOFIELDMAP_H #define RECOFIELDMAP_H #include "step.h" static const char* posted_fmap_str="fieldmap"; class RecoFieldMap : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "fieldmap";} STD_string description() const {return "Calculate fieldmap";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,te,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single, te);} RecoStep* allocate() const {return new RecoFieldMap;} void init() {} }; ////////////////////////////////////////////////////////////// class RecoFieldMapUser : public RecoStep { public: bool get_fmap(Data& fieldmap, const TinyVector& dstshape, const RecoCoord& fmapcoord, RecoController& controller); static void modify4fieldmap(RecoCoord& coord); private: // cache interpolated fieldmaps typedef STD_map > FieldMap; FieldMap fmap; Mutex fmapmutex; }; #endif odin-1.8.5/odinreco/phasecorr.h0000644000175000017500000000542011322062351013334 00000000000000/*************************************************************************** phasecorr.h - description ------------------- begin : Mon Jan 24 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOPHASECORR_H #define RECOPHASECORR_H #include "step.h" class RecoPhaseMap : public RecoStep { public: static void modify(RecoCoord& coord) { // to be used in query() coord.set_mode(RecoIndex::ignore, line, line3d); // dimensions irrelevant to phase correction coord.set_mode(RecoIndex::separate, echo); // override collected mode } static void modify4blackboard(RecoCoord& coord) { // index for blackboard modify(coord); coord.set_mode(RecoIndex::separate, epi); // no longer ignore EPI index coord.set_mode(RecoIndex::ignore, repetition, dti, line3d, templtype, freq); // re-use phasemap for all repetitions, etc. } private: // implementing virtual functions of RecoStep STD_string label() const {return "phasemap";} STD_string description() const {return "Calculate and post phasemap for echo-by-echo phase correction";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,echo,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoPhaseMap;} void init() {} bool odd_even_echoes; }; ////////////////////////////////////////////////////////////// class RecoPhaseCorr : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "phasecorr";} STD_string description() const {return "Apply echo-by-echo phase correction";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoPhaseCorr;} void init() {} }; #endif odin-1.8.5/odinreco/b1fit.cpp0000644000175000017500000000631611322062351012713 00000000000000#include "b1fit.h" #include "data.h" #include "controller.h" #include bool RecoB1Fit::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); ComplexData<3>& outdata=rd.data(Rank<3>()); outdata.resize(outshape); outdata=STD_complex(0.0); dvector flips=controller.dim_values(userdef); ODINLOG(odinlog,normalDebug) << "flips=" << flips.printbody() << STD_endl; int nflips=flips.size(); if(nflips!=inshape(0)) { ODINLOG(odinlog,errorLog) << "size mismatch" << STD_endl; return false; } Data magn(cabs(indata)); float masklevel=0.2; float noiselevel=masklevel*mean(magn(0,all,all,all)); LinearFunction linf; Data pixel4fit(nflips); Data flipwinkel(nflips); for ( int icount = 0; icount < nflips; icount++ ) { flipwinkel(icount)=flips[icount]; } Data pixel4fitcalc(nflips-2); Data ysigmacalc(nflips-2); ysigmacalc=1.0; Data flipwinkelcalc(nflips-2); for(int iphase3d=0; iphase3dnoiselevel) { pixel4fit=magn(all,iphase3d,iphase,iread); int checkmin = minIndex(pixel4fit)(0); if ( (checkmin == 0) || (checkmin == 1) ) { flipwinkelcalc(0) = flipwinkel(0); flipwinkelcalc(1) = flipwinkel(1); flipwinkelcalc(2) = flipwinkel(2); pixel4fitcalc(0) = pixel4fit(0); pixel4fitcalc(1) = pixel4fit(1); pixel4fitcalc(2) = pixel4fit(2); } if ( checkmin == 2 ) { flipwinkelcalc(0) = flipwinkel(1); flipwinkelcalc(1) = flipwinkel(2); flipwinkelcalc(2) = flipwinkel(3); pixel4fitcalc(0) = pixel4fit(1); pixel4fitcalc(1) = pixel4fit(2); pixel4fitcalc(2) = pixel4fit(3); } if ( (checkmin == 3) || (checkmin == 4) ) { flipwinkelcalc(0) = flipwinkel(2); flipwinkelcalc(1) = flipwinkel(3); flipwinkelcalc(2) = flipwinkel(4); pixel4fitcalc(0) = pixel4fit(2); pixel4fitcalc(1) = pixel4fit(3); pixel4fitcalc(2) = pixel4fit(4); } linf.fit(pixel4fitcalc,ysigmacalc,flipwinkelcalc); float error_ppp = linf.m.err; float m_ppp = linf.m.val; float c_ppp = linf.c.val; pixel4fitcalc(2) = -pixel4fitcalc(2); linf.fit(pixel4fitcalc,ysigmacalc,flipwinkelcalc); float error_ppm = linf.m.err; float m_ppm = linf.m.val; float c_ppm = linf.c.val; pixel4fitcalc(1) = -pixel4fitcalc(1); linf.fit(pixel4fitcalc,ysigmacalc,flipwinkelcalc); float error_pmm = linf.m.err; float m_pmm = linf.m.val; float c_pmm = linf.c.val; float B1; if ( error_ppp < error_ppm && error_ppp < error_pmm ) { B1 = fabs(secureDivision(m_ppp*180.0,c_ppp)); } else if ( error_ppm < error_pmm ) { B1 = fabs(secureDivision(m_ppm*180.0,c_ppm)); } else { B1 = fabs(secureDivision(m_pmm*180.0,c_pmm)); } if ( B1 > 1.8 ) { B1 = 0; } check_range(B1, 0.4, 1.6); outdata(iphase3d,iphase,iread)=B1; } } } } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/reader_custom.h0000644000175000017500000000453411322062351014207 00000000000000/*************************************************************************** reader_custom.h - description ------------------- begin : Thu Oct 18 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOREADERCUSTOM_H #define RECOREADERCUSTOM_H #include "reader.h" /** * @addtogroup odinreco * @{ */ /** * Raw-data reader template to implement custom readers. */ class RecoReaderCustom : public virtual RecoReaderInterface { public: RecoReaderCustom(JcampDxBlock&) {} private: // Implementing virtual functions of RecoReaderInterface bool init(const STD_string& input_filename); bool fetch(RecoCoord& coord, ComplexData<1>& adc); const STD_vector& get_coords() const {return coord_vec_cache;} dvector dim_values(recoDim dim) const; const TinyVector& reloffset() const {return reloffset_cache;} STD_string image_proc() const {return "";} const TinyVector& image_size() const {return size_cache;} const Protocol& protocol() const {return prot_cache;} STD_string seqrecipe() const {return "";} // Let controller generate recipe automatically STD_string postProc3D() const {return "";} STD_string preProc3D() const {return "";} STD_string cmdline_opts() const; // Cached values TinyVector reloffset_cache; TinyVector size_cache; Protocol prot_cache; ComplexData<2> rawdata; // synthetic raw data mutable STD_vector coord_vec_cache; // Vector to hold reco coordinates (indices) unsigned int count; // counter for ADCs }; /** @} */ #endif odin-1.8.5/odinreco/conjphase.cpp0000644000175000017500000000660311322062351013657 00000000000000#include "conjphase.h" #include "data.h" #include "controller.h" bool RecoConjPhaseFT::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<1>& indata=rd.data(Rank<1>()); ComplexData<3>& outdata=rd.data(Rank<3>()); int nsample=indata.size(); int ncycle=rd.coord().numof(cycle); ODINLOG(odinlog,normalDebug) << "nsample/ncycle=" << nsample << "/" << ncycle << STD_endl; TinyVector outsize=controller.image_size(); outdata.resize(outsize); outdata=STD_complex(0.0); ODINLOG(odinlog,normalDebug) << "outsize=" << outsize << STD_endl; // local fast cache of trajectories and weight TinyVector ktraj[nsample]; float kweight[nsample]; trajmutex.lock(); const KspaceTraj* traj=rd.coord().kspaceTraj; // access is protected by mutex if(!traj) { ODINLOG(odinlog,errorLog) << "Trajectory missing" << STD_endl; trajmutex.unlock(); return false; } int nseg=traj->extent(0); int npts=traj->extent(1); if(nseg!=ncycle) { ODINLOG(odinlog,errorLog) << "Size mismatch: nseg(" << nseg << ")!=ncycle(" << ncycle << ")" << STD_endl; trajmutex.unlock(); return false; } if(npts!=nsample) { ODINLOG(odinlog,errorLog) << "Size mismatch: npts(" << npts << ")!=nsample(" << nsample << ")" << STD_endl; trajmutex.unlock(); return false; } int icycle=rd.coord().index[cycle]; for(int isample=0; isample& gp=(*traj)(icycle,isample); ktraj[isample]=gp.coord; kweight[isample]=gp.weight; } trajmutex.unlock(); // local fast cache of indata STD_complex signal[nsample]; for(int isample=0; isample fieldmap; bool has_fieldmap=false; if(controller.data_announced(posted_fmap_str)) { RecoCoord fmapcoord=rd.coord(); RecoFieldMapUser::modify4fieldmap(fmapcoord); if(!get_fmap(fieldmap, outsize, fmapcoord, controller)) return false; has_fieldmap=true; } double dt=rd.coord().dwellTime; ODINLOG(odinlog,normalDebug) << "dt=" << dt << STD_endl; Protocol prot(controller.protocol()); // get FOV TinyVector fov; fov(0)=0.0; //prot.geometry.get_FOV(sliceDirection); only 2D FT yet fov(1)=prot.geometry.get_FOV(phaseDirection); fov(2)=prot.geometry.get_FOV(readDirection); ODINLOG(odinlog,normalDebug) << "fov=" << fov << STD_endl; TinyVector extent; extent=outsize; ODINLOG(odinlog,normalDebug) << "extent=" << extent << STD_endl; TinyVector reloffset=controller.reloffset(); for(int i=0; i index=outdata.create_index(i); bool reconstruct_voxel=true; float deltaOmega_dt=0.0; if(has_fieldmap) { deltaOmega_dt=dt*fieldmap(index); if(!deltaOmega_dt) reconstruct_voxel=false; } TinyVector spatcoord= fov * (index/extent - 0.5 + reloffset); STD_complex voxel(0.0); if(reconstruct_voxel) { for(int isample=0; isample; template class RecoGrid<2>; template class RecoDeapodize<1>; template class RecoDeapodize<2>; odin-1.8.5/odinreco/offset.h0000644000175000017500000000313211322062351012632 00000000000000/*************************************************************************** offset.h - description ------------------- begin : Wed Feb 7 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOOFFSET_H #define RECOOFFSET_H #include "step.h" class RecoOffset : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "offset";} STD_string description() const {return "Create phase gradient in k-space so that image is shifted after FFT";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoOffset;} void init() {} }; #endif odin-1.8.5/odinreco/dti.cpp0000644000175000017500000000131711322062351012462 00000000000000#include "dti.h" #include "controller.h" bool RecoDTI::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Protocol prot(controller.protocol()); // Local copy of protocol, used for override_protocol rd.override_protocol=&prot; STD_string series; int number; prot.study.get_Series(series, number); int idti=rd.coord().index[dti]; dvector bvals=controller.dim_values(dti); JDXtriple bvector(bvals[3*idti], bvals[3*idti+1], bvals[3*idti+2], "Diffusion_bVector"); bvector*=1000.0; // in s/mm^2 prot.study.set_Series("b"+replaceStr(bvector.printbody()," ","_"),number); prot.methpars.append_copy(bvector); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/switch.h0000644000175000017500000000440711322062351012653 00000000000000/*************************************************************************** switch.h - description ------------------- begin : Mon Jan 22 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSWITCH_H #define RECOSWITCH_H #include "step.h" class RecoSwitch : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "switch";} STD_string description() const {return "Branch off different flows through reconstruction pipeline";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::any();} void modify_coord(RecoCoord& coord) const {} // irrelevant since pipeline ends here RecoStep* allocate() const {return new RecoSwitch;} bool pipeline_init(const RecoController& controller, const RecoCoord& input_coord); bool query(RecoQueryContext& context); void init(); JDXstring brancharg; struct BranchKey { // BranchKey(recoDim branchdim, unsigned int branchindex) : dim(branchdim), val(branchindex) {} // does not work with GCC 3.5 recoDim dim; unsigned short val; bool operator < (const BranchKey& bs) const { if(dim!=bs.dim) return (dim BranchMap; BranchMap branches; STD_list unconditional; }; #endif odin-1.8.5/odinreco/oversampling.cpp0000644000175000017500000000200111322062351014377 00000000000000#include "oversampling.h" #include "data.h" bool RecoOversampling::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); float os_factor=rd.coord().overSamplingFactor; if(os_factor>1.0) { Range all=Range::all(); ComplexData<3>& indata=rd.data(Rank<3>()); TinyVector inshape=indata.shape(); TinyVector outshape=inshape; int insize=inshape(2); int outsize=int(float(insize)/os_factor+0.5); outshape(2)=outsize; int offset=insize/2-outsize/2; // Make zero-frequency column is zero-frequency column after cropping ODINLOG(odinlog,normalDebug) << "insize/outsize/offset=" << insize << "/" << outsize << "/" << offset << STD_endl; ComplexData<3> outdata(outshape); outdata(all,all,all)=indata(all,all,Range( offset, offset+outsize-1 )); rd.data(Rank<3>()).reference(outdata); } rd.coord().overSamplingFactor=1.0; // inidicate that oversampling has been removed return execute_next_step(rd,controller); } odin-1.8.5/odinreco/channel.h0000644000175000017500000000330511665172216012772 00000000000000/*************************************************************************** channel.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOCHANNEL_H #define RECOCHANNEL_H #include "step.h" class RecoChannelSum : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "chansum";} STD_string description() const {return "Combine images from different channels";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,channel,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single, channel);} // reduce all channles to one RecoStep* allocate() const {return new RecoChannelSum;} void init(); JDXbool phasecomb; JDXfloat magnexp; }; #endif odin-1.8.5/odinreco/homodyne.cpp0000644000175000017500000000032511455553545013543 00000000000000#include "homodyne.h" #include "homodyne_code.h" // Instantiations used in step.cpp template class RecoHomodyne; template class RecoHomodyne; template class RecoHomodyne; odin-1.8.5/odinreco/slidingwindow.h0000644000175000017500000000305111322062351014225 00000000000000/*************************************************************************** slidingwindow.h - description ------------------- begin : Tue Sep 8 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSLIDINGWINDOW_H #define RECOSLIDINGWINDOW_H #include "step.h" class RecoSlidingWindow : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "slidingwindow";} STD_string description() const {return "Generate sliding window data";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::any();} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoSlidingWindow;} void init() {} }; #endif odin-1.8.5/odinreco/sum_code.h0000644000175000017500000000434311322062351013147 00000000000000#include "sum.h" #include "data.h" template bool RecoSum::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); // create new view of input data ComplexData& indata=rd.data(Rank()); TinyVector inshape(indata.shape()); TinyVector sumshape; for(int i=0; i outshape; for(int i=0; i outshape_padded=1; for(unsigned int i=0; i lowin=0; TinyVector uppin=outshape_padded-1; TinyVector lowout=0; TinyVector uppout=outshape_padded-1; // output domain, the same for each dataset RectDomain outdomain(lowout,uppout); ComplexData outdata_padded(outshape_padded); outdata_padded=STD_complex(0.0); for(int isum=0; isum sumindex=index2extent(sumshape, isum); // set input inidices for(unsigned int i=0; i indomain(lowin,uppin); if(Magn) outdata_padded(outdomain)+=float2real(cabs(indata(indomain))); else outdata_padded(outdomain)+=indata(indomain); } ComplexData outdata(outshape); outdata_padded.convert_to(outdata); // bring to output shape rd.data(Rank()).reference(outdata); ODINLOG(odinlog,normalDebug) << " outshape=" << outshape << STD_endl; modify_coord(rd.coord()); if(Magn) rd.mode=RecoData::real_data; if(!execute_next_step(rd,controller)) return false; return true; } odin-1.8.5/odinreco/zerofill.h0000644000175000017500000000322511322062351013175 00000000000000/*************************************************************************** zerofill.h - description ------------------- begin : Wed Oct 10 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOZEROFILL_H #define RECOZEROFILL_H #include "step.h" class RecoZeroFill : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "zerofill";} STD_string description() const {return "Fill k-space with zeroes to match matrix size of protocol";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoZeroFill;} void init(); JDXint minread; JDXint minphase; JDXint minslice; }; #endif odin-1.8.5/odinreco/grappa_code.h0000644000175000017500000005105411455553545013637 00000000000000#include "grappa.h" #include "data.h" #include "controller.h" #include STD_string grappa_postlabel(recoDim dim) { return STD_string("grappaweights_")+recoDimLabel[dim]; } /////////////////////////////////////////////////////// ivector next_neighbours_offset(unsigned int reductionFactor, int numof_neighb, int ired) { Log odinlog("","next_neighbours_offset"); ivector result(numof_neighb); int negfirst=(ired<(reductionFactor/2)); // determine initial direction for(int i=0; i void RecoGrappaWeights::init() { reduction_factor=0; reduction_factor.set_description("Reduction factor"); append_arg(reduction_factor,"reduction_factor"); neighbours_read=5; neighbours_read.set_cmdline_option("gr").set_description("Number of neigbours in read direction used for GRAPPA interpolation"); append_arg(neighbours_read,"neighbours_read"); neighbours_phase=2; neighbours_phase.set_cmdline_option("gp").set_description("Number of neigbouring measured k-space lines used for GRAPPA interpolation"); append_arg(neighbours_phase,"neighbours_phase"); svd_trunc=0.001; svd_trunc.set_cmdline_option("gs").set_description("Truncation value of SVD (i.e. regularization) when calculating GRAPPA weights"); append_arg(svd_trunc,"svd_trunc"); discard_level=0.01; discard_level.set_cmdline_option("gd").set_description("Fraction of k-psace points to discard in auto-calibration lines because of high residuals"); append_arg(discard_level,"discard_level"); } /////////////////////////////////////////////////////// template bool RecoGrappaWeights::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); RecoCoord coordcopy(rd.coord()); // local copy to modify coord according to ignored dims Ignore::modify(RecoIndex::ignore, coordcopy); RecoData rdweights(coordcopy); if(!calc_weights(rdweights.data(Rank<5>()), coordcopy, rd.data(Rank<4>()))) return false; controller.post_data(grappa_postlabel(interpolDim), rdweights); ODINLOG(odinlog,normalDebug) << "Posted rdweights=" << rdweights.coord().print() << STD_endl; return execute_next_step(rd,controller); } /////////////////////////////////////////////////////// template bool RecoGrappaWeights::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { context.controller.announce_data(grappa_postlabel(interpolDim)); RecoCoord coordcopy(context.coord); Ignore::modify(RecoIndex::ignore, coordcopy); if(!measlines.init(coordcopy, context.controller)) return false; } return RecoStep::query(context); } /////////////////////////////////////////////////////// template bool RecoGrappaWeights::calc_weights(ComplexData<5>& weights, const RecoCoord& trainingcoord, const ComplexData<4>& trainingdata) { Log odinlog(c_label(),"calc_weights"); Range all=Range::all(); ODINLOG(odinlog,normalDebug) << "neighbours_read/neighbours_phase=" << neighbours_read << "/" << neighbours_phase << STD_endl; TinyVector inshape=trainingdata.shape(); int nChannels=inshape(0); int sizeOrtho=inshape(1+orthoIndex); int sizeInterpol=inshape(1+interpolIndex); int sizeRead=inshape(3); ODINLOG(odinlog,normalDebug) << "nChannels/sizeOrtho/sizeInterpol/sizeRead/reduction_factor=" << nChannels << "/" << sizeOrtho << "/" << sizeInterpol << "/" << sizeRead << "/" << reduction_factor << STD_endl; // Shape for 3D volumes TinyVector shape3d(inshape(1),inshape(2),inshape(3)); // shape to calculate index vector within interpolation net TinyVector netshape(nChannels, neighbours_phase, neighbours_read); int ncols=product(netshape); // Size of the interpolation net ComplexData<1> weights_net_vec(ncols); // Interpolation net around a particular root node weights.resize(nChannels, reduction_factor-1, nChannels, neighbours_phase, neighbours_read); // the result weights=STD_complex(0.0); for(int ired=0; ired<(reduction_factor-1); ired++) { // loop over (R-1) missing lines // Mask for the root nodes available to calculate the weights Data acl_mask(inshape); acl_mask=0; RecoCoord aclcoord(trainingcoord); for(int iortho=0; iorthonrows) { ODINLOG(odinlog,errorLog) << "Not enough auto-calibration data for " << netshape << " interpolation net" << STD_endl; return false; } // fill acl_signal_vec with signal values from ACLs ComplexData<1> acl_signal_vec(nrows); // Will hold root node data of a particular channel Array,1> maskindex(nrows); // cache for coordinates of signal values contributing to SVD int irow=0; for(int i=0; i rowindex=index2extent(acl_signal_shape, i); TinyVector aclindex(ichan_dst, rowindex(0), rowindex(1), rowindex(2)); if(acl_mask(aclindex)) { maskindex(irow)=rowindex; STD_complex aclval=trainingdata(aclindex); if(cabs(aclval)==0.0) { ODINLOG(odinlog,warningLog) << "Zero acl at " << aclindex << STD_endl; } acl_signal_vec(irow)=aclval; irow++; } } // fill Matrix for SVD ComplexData<2> Matrix(nrows,ncols); for(int irow=0; irow aclindex=maskindex(irow); for(int icol=0; icol windex=index2extent(netshape,icol); int ichan_src=windex(0); int ipoloffset=neighboffset[windex(1)]; int readoffset=windex(2)-neighbours_read/2; // symmetrical about root node TinyVector trainingindex; trainingindex(0)=ichan_src; trainingindex(1)=aclindex(0); trainingindex(2)=aclindex(1); trainingindex(3)=aclindex(2)+readoffset; trainingindex(1+interpolIndex)+=ipoloffset; // take neighbour in interpolation direction STD_complex trainingval=trainingdata(trainingindex); if(cabs(trainingval)==0.0) { ODINLOG(odinlog,warningLog) << "Zero trainingdata at " << trainingindex << STD_endl; } Matrix(irow,icol)=trainingval; } } // solve system of linear equations using complex SVD weights_net_vec=solve_linear(Matrix, acl_signal_vec, svd_trunc); // Use residuals to eliminate noisy ACLs (Huo et al., JMRI 2008, 27:1412) if(discard_level>0.0) { Data residuals(cabs(matrix_product(Matrix, weights_net_vec)-acl_signal_vec)); int ndiscard=int(discard_level*nrows+0.5); if(ncols>(nrows-ndiscard)) { ODINLOG(odinlog,warningLog) << "Limiting ndiscard to " << ndiscard << " for sufficient auto-calibration data" << STD_endl; ndiscard=nrows-ncols; } for(int i=0; i windex=index2extent(netshape,icol); weights(ichan_dst, ired, windex(0), windex(1), windex(2))=weights_net_vec(icol); } } // end loop over channels } // end loop over reduction inidices ODINLOG(odinlog,normalDebug) << "cabs(sum(weights" << trainingcoord.print() << "))=" << cabs(sum(weights)) << STD_endl; return true; } /////////////////////////////////////////////////////// template ivector RecoGrappaWeights::acl_lines(const RecoCoord& coord, int numof_neighb, int ired) const { Log odinlog(c_label(),"acl_lines"); ivector neighboffset=next_neighbours_offset(reduction_factor, numof_neighb, ired); ODINLOG(odinlog,normalDebug) << "neighboffset=" << neighboffset.printbody() << STD_endl; ivector indexvec=measlines.get_indices(coord); ODINLOG(odinlog,normalDebug) << "indexvec(" << coord.print() << ")=" << indexvec.printbody() << STD_endl; STD_list indexlist; for(unsigned int i=0; i void RecoGrappa::init() { reduction_factor=0; reduction_factor.set_description("Reduction factor"); append_arg(reduction_factor,"reduction_factor"); keep_shape=false; keep_shape.set_description("Do not correct shape of interpolated k-space according to image space size"); append_arg(keep_shape,"keep_shape"); } template bool RecoGrappa::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); if(!controller.data_announced(grappa_postlabel(interpolDim))) { ODINLOG(odinlog,errorLog) << "GRAPPA weights not available" << STD_endl; return false; } ODINLOG(odinlog,normalDebug) << "reduction_factor=" << reduction_factor << STD_endl; if(!keep_shape) { if(!correct_shape(rd, controller)) return false; // adjust shape to account for incomplete sampling at end of k-space } ODINLOG(odinlog,normalDebug) << "Requesting weights for " << rd.coord().print() << STD_endl; RecoData rdweights(rd.coord()); if(!controller.inquire_data(grappa_postlabel(interpolDim), rdweights)) return false; ODINLOG(odinlog,normalDebug) << "Retrieved weights with " << rdweights.coord().print() << STD_endl; const ComplexData<5>& weights=rdweights.data(Rank<5>()); ODINLOG(odinlog,normalDebug) << "cabs(sum(weights(" << rdweights.coord().print() << ")))=" << cabs(sum(weights)) << STD_endl; ComplexData<4>& kspace=rd.data(Rank<4>()); TinyVector kspaceshape=kspace.shape(); int nChannels=kspaceshape(0); int sizeOrtho=kspaceshape(1+orthoIndex); int sizeInterpol=kspaceshape(1+interpolIndex); int sizeRead=kspaceshape(3); ODINLOG(odinlog,normalDebug) << "nChannels/sizeOrtho/sizeInterpol/sizeRead/reduction_factor=" << nChannels << "/" << sizeOrtho << "/" << sizeInterpol << "/" << sizeRead << "/" << reduction_factor << STD_endl; int neighbours_phase=weights.extent(3); int neighbours_read=weights.extent(4); ODINLOG(odinlog,normalDebug) << "neighbours_phase/neighbours_read=" << neighbours_phase << "/" << neighbours_read << STD_endl; CoordCountMap interpolated_coords; if(rd.interpolated) { measlines.update(*(rd.interpolated)); // take previously interpolated coords into account interpolated_coords=(*(rd.interpolated)); // merge previously interpolated coords } // shape to calculate index vector within interpolation net TinyVector netshape(nChannels, neighbours_phase, neighbours_read); // separate array for interpolated values to avoid recursive summation ComplexData<4> kspace_interpol(kspaceshape); kspace_interpol=STD_complex(0.0); for(int iortho=0; iortho kspaceindex; kspaceindex(0)=ichan; kspaceindex(1+orthoIndex)=iortho; kspaceindex(1+interpolIndex)=ipol; kspaceindex(3)=iread; STD_complex interpolval(0.0); // iterate over 3D interpolation net to accumulate signal value at root node for(int i=0; i netindex=index2extent(netshape,i); // index within net int jchan=netindex(0); int jphase=netindex(1); int jread=netindex(2); int offset_ipol=neighboffset[jphase]; int offset_read=jread-neighbours_read/2; // symmetrical about root node int src_ipol =ipol+offset_ipol; int src_iread =iread+offset_read; if(src_ipol>=0 && src_ipol=0 && src_iread srcindex; srcindex(0)=jchan; srcindex(1+orthoIndex)=iortho; // Use only src points from the same partition in orthogonal direction srcindex(1+interpolIndex)=src_ipol; srcindex(3)=src_iread; STD_complex srcval=kspace(srcindex); if(cabs(srcval)==0.0) { ODINLOG(odinlog,warningLog) << "Zero srcval at " << srcindex << " while interpolating " << kspaceindex << STD_endl; } interpolval += srcval * weights(ichan,ired,jchan,jphase,jread); // linear interpolation of kspace } } kspace_interpol(kspaceindex)=interpolval; } } } } } } } kspace=kspace+kspace_interpol; rd.interpolated=&interpolated_coords; // Inform subsequent steps about the interpolated coordinates return execute_next_step(rd,controller); } /////////////////////////////////////////////////////// template bool RecoGrappa::correct_shape(RecoData& rdkspace, const RecoController& controller) const { Log odinlog(c_label(),"correct_shape"); Range all=Range::all(); ComplexData<4>& inkspace=rdkspace.data(Rank<4>()); TinyVector inshape=inkspace.shape(); int nlines_dst=controller.image_size()(interpolIndex); int nlines_src=inshape(1+interpolIndex); if(nlines_dst==nlines_src) return true; if(nlines_dst outshape(inshape); outshape(1+interpolIndex)=nlines_dst; ODINLOG(odinlog,normalDebug) << "inshape/outshape=" << inshape << "/" << outshape << STD_endl; ComplexData<4> outkspace(outshape); outkspace=STD_complex(0.0); Range srcrange(0,nlines_src-1); if(interpolDim==line) outkspace(all,all,srcrange,all)=inkspace(all,all,srcrange,all); if(interpolDim==line3d) outkspace(all,srcrange,all,all)=inkspace(all,srcrange,all,all); rdkspace.data(Rank<4>()).reference(outkspace); return true; } /////////////////////////////////////////////////////// template bool RecoGrappa::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(!measlines.init(context.coord, context.controller)) return false; } return RecoStep::query(context); } /////////////////////////////////////////////////////// template int RecoGrappa::reduction_index(const ivector& indexvec, int sizePhase, int iphase) const { Log odinlog(c_label(),"reduction_index"); ODINLOG(odinlog,normalDebug) << "reduction_factor/sizePhase/iphase=" << reduction_factor << "/" << sizePhase << "/" << iphase << STD_endl; int posnext=-1; int negnext=-1; // search for next scanned line in positive direction for(int i=iphase; i=0; i--) { if(measured_line(indexvec, i)) { negnext=iphase-i; break; } } ODINLOG(odinlog,normalDebug) << "posnext/negnext(" << iphase << ")=" << posnext << "/" << negnext << STD_endl; if(posnext<0 || negnext<0) return -1; // Measured line is missing in one or more directions -> Line is not surrounded by measured lines return negnext-1; } odin-1.8.5/odinreco/homodyne.h0000644000175000017500000000406411455553545013214 00000000000000/*************************************************************************** homodyne.h - description ------------------- begin : Mon Apr 2 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOHOMODYNE_H #define RECOHOMODYNE_H #include "step.h" #include "measindex.h" template class RecoHomodyne : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const { STD_string result="homodyne"; if(interpolDim==line3d) result+="3d"; if(interpolDim==readout) result+="read"; return result; } STD_string description() const {return "Homodyne reconstruction of partial Fourier data in dimension '"+STD_string(recoDimLabel[interpolDim])+"'";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoHomodyne;} void init() {} // Phase-encoding lines actually measured RecoMeasIndex > measlines; }; #endif odin-1.8.5/odinreco/slicetime.cpp0000644000175000017500000000267711322062351013672 00000000000000#include "slicetime.h" #include "data.h" #include "controller.h" bool RecoSliceTime::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); dvector sliceorder=controller.dim_values(slice); ODINLOG(odinlog,normalDebug) << "sliceorder=" << sliceorder.printbody() << STD_endl; ComplexData<5>& indata=rd.data(Rank<5>()); TinyVector inshape=indata.shape(); int nrep=inshape(0); int nslices=inshape(1); if(nrep>1 && nslices>1) { dvector sliceshift(nslices); sliceshift=0.0; if(nslices==int(sliceorder.size())) { for(int islice=0; islice" << STD_endl; STD_cout << "Options:" << STD_endl; STD_cout << opts.get_cmdline_usage("\t"); STD_cout << "\t" << LogBase::get_usage() << STD_endl; STD_cout << "\t" << helpUsage() << STD_endl; } int main(int argc,char* argv[]) { if(LogBase::set_log_levels(argc,argv)) return 0; Log odinlog("","main"); JcampDxBlock opts; RecoController controller(opts); RecoReaderOdin reader_odin(opts); RecoReaderCustom reader_custom(opts); #ifdef IDEA_PLUGIN RecoReaderTwix reader_twix(opts); #endif if(isCommandlineOption(argc,argv,"-manual")){ STD_cout << controller.stepmanual() << STD_endl; return 0; } if(hasHelpOption(argc,argv)) {usage(opts);return 0;} // Select reader by autodetection RecoReaderInterface* reader=0; char optval[ODIN_MAXCHAR]; JDXfileName input_filename=STD_string("./recoInfo"); // default is odin data if(getCommandlineOption(argc,argv,"-r",optval,ODIN_MAXCHAR)) input_filename=optval; if(input_filename.get_basename()=="recoInfo") reader=&reader_odin; if(input_filename.get_suffix()=="smp") reader=&reader_custom; #ifdef IDEA_PLUGIN if(input_filename.get_suffix()=="dat") reader=&reader_twix; #endif if(!reader) { ODINLOG(odinlog,errorLog) << "Unable to initialize reader for input file " << input_filename << STD_endl; return -1; } opts.parse_cmdline_options(argc,argv,false); // Parse reader options if(!reader->init(input_filename)) return -1; if(!controller.init(reader,opts,argc,argv)) return -1; if(!controller.start()) return -1; Profiler::dump_final_result(); return 0; } odin-1.8.5/odinreco/fft.cpp0000644000175000017500000000056111322062351012461 00000000000000#include "fft.h" #include "data.h" void RecoFFT::init() { forward=true; forward.set_description("Forward (true) or backward (false) FFT"); append_arg(forward,"forward"); } bool RecoFFT::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); rd.data(Rank<3>()).fft(forward); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/offset.cpp0000644000175000017500000000166611455553545013220 00000000000000#include "offset.h" #include "controller.h" #include "data.h" bool RecoOffset::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& data=rd.data(Rank<3>()); float os_factor=rd.coord().overSamplingFactor; // should be set to 1.0 by prior functors if oversampling has already been removed float grid_factor=rd.coord().gridScaleFactor; // spatial shifting TinyVector reloffset=controller.reloffset(); reloffset(2)/=os_factor * grid_factor; reloffset(1)/=grid_factor; bool do_shift=false; if(max(abs(reloffset))>0.0) do_shift=true; if(do_shift) { // data.fft(false); // backward FFT ODINLOG(odinlog,normalDebug) << "shifting with reloffset=" << reloffset << STD_endl; data.modulate_offset(reloffset); // data.fft(true); // forward FFT for correct sign of modulated offset } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/filter.h0000644000175000017500000000322611322062351012635 00000000000000/*************************************************************************** filter.h - description ------------------- begin : Fri Sep 14 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOFILTER_H #define RECOFILTER_H #include "step.h" #include class RecoFilter : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "filter";} STD_string description() const {return "Lowpass filter in k-space with plateau at the center";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoFilter;} void init(); JDXfilter filter; JDXfloat plateau; }; #endif odin-1.8.5/odinreco/mip.cpp0000644000175000017500000000506711322062351012475 00000000000000#include "mip.h" #include "data.h" #include "controller.h" void RecoMip::init() { neighbors=4; neighbors.set_cmdline_option("mn").set_description("In sliding-window maximum-intensity projection, use this number of neighbors in each direction"); append_arg(neighbors,"neighbors"); } /////////////////////////////////////////////////////////////////////////// bool RecoMip::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& indata=rd.data(Rank<3>()); TinyVector shape=indata.shape(); Array magn(cabs(indata)); // Sliding window maximum-intensity projection (MIP) Array mip(shape); mip=0.0; for(int iline=0; iline mipall[3]; mipall[0].resize(1,shape(0),shape(1)); mipall[1].resize(1,shape(0),shape(2)); mipall[2].resize(1,shape(1),shape(2)); for(int j=0; j()).reference(float2real(mip)); rdmip.coord().index[userdef]=1; prot.study.set_Series(series+"_mip",number); if(!execute_next_step(rdmip,controller)) return false; for(int idir=0; idir<3; idir++) { STD_string id; if(idir==0) id=recoDimLabel[readout]; if(idir==1) id=recoDimLabel[line]; if(idir==2) id=recoDimLabel[line3d]; // feed mipall into rest of pipeline RecoData rdmipall(rd); rdmipall.data(Rank<3>()).reference(float2real(mipall[idir])); rdmipall.coord().index[userdef]=2+idir; prot.study.set_Series(series+"_mip"+id,number); if(!execute_next_step(rdmipall,controller)) return false; } return true; } odin-1.8.5/odinreco/blackboard.h0000644000175000017500000000647311322062351013443 00000000000000/*************************************************************************** blackboard.h - description ------------------- begin : Mon Jan 24 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOBLACKBOARD_H #define RECOBLACKBOARD_H #include #include #include /** * @addtogroup odinreco * @{ */ /** * Manages data transfer between functors */ class RecoBlackBoard { public: /** * Constructs empty blackboard */ RecoBlackBoard() {} ~RecoBlackBoard(); /** * Announces that data with identifier 'label' will become available during pipeline execution. */ void announce(const STD_string& label) {ann[label]++;} /** * Posts 'data' with identifier 'label', it will be indexed according to the k-space coordinate in 'data'. */ void post(const STD_string& label, const RecoData& data); /** * Returns true only if data with identifier 'label' will become available during pipeline execution. */ bool announced(const STD_string& label) const {return ann.find(label)!=ann.end();} /** * Returns 'data' with identifier 'label' for k-space coordinate set in 'data'. * If 'blocking' is 'true', the function will return only if data becomes available. * Returns 'true' if data is available, otherwise returns 'false' if data not yet available. */ bool inquire(const STD_string& label, RecoData& data, bool blocking=false); private: bool get_data(const STD_string& label, RecoData& data); // The data on the blackboard typedef STD_map CoordDataMap; typedef STD_map LabelDataMap; LabelDataMap posted; // The events to signal the availability of new data typedef STD_map CoordEventMap; typedef STD_map LabelEventMap; LabelEventMap eventmap; Mutex mutex; // Mutex for both maps STD_map ann; }; /** @} */ /////////////////////////////////////////////////////////////////////////////////////////// class RecoPost : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "post";} STD_string description() const {return "Post data on blackboard";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::any();} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoPost;} void init(); JDXstring postlabel; }; #endif odin-1.8.5/odinreco/oversampling.h0000644000175000017500000000316411322062351014057 00000000000000/*************************************************************************** oversampling.h - description ------------------- begin : Thu Feb 22 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOOVERSAMPLING_H #define RECOOVERSAMPLING_H #include "step.h" class RecoOversampling : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "oversampling";} STD_string description() const {return "Remove oversampling in readout direction in image domain";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoOversampling;} void init() {} }; #endif odin-1.8.5/odinreco/expfit.cpp0000644000175000017500000000421511712547772013223 00000000000000#include "expfit.h" #include "data.h" #include "controller.h" #include /////////////////////////////////////////////////////////////////////////// void RecoExpFit::init() { invert=false; invert.set_description("Calculate inverse after exponential decay fit (for T2)"); append_arg(invert,"invert"); masklevel=0.5; masklevel.set_cmdline_option("el").set_description("Level relative to mean value of first echo for setting mask of exponential decay fit"); append_arg(masklevel,"masklevel"); } bool RecoExpFit::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); Data magn(cabs(indata)); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); dvector xvec=controller.dim_values(userdef); ODINLOG(odinlog,normalDebug) << "xvec=" << xvec.printbody() << STD_endl; int nx=xvec.size(); if(nx!=inshape(0)) { ODINLOG(odinlog,errorLog) << "size mismatch: nx(" << nx << ")!=" << inshape(0) << STD_endl; return false; } ComplexData<3>& outdata=rd.data(Rank<3>()); outdata.resize(outshape); outdata=STD_complex(0.0); float noiselevel=masklevel*mean(magn(0,all,all,all)); LinearFunction linf; Data echomagn(nx); Data echolog(nx); Data ysigma(nx); Data xvals(nx); for(int i=0; inoiselevel) { echomagn=magn(all,iphase3d,iphase,iread); echolog=log(echomagn); ysigma=pow(echomagn, -1); // weight fit by magnitude if(linf.fit(echolog,ysigma,xvals)) { if(invert) { outdata(iphase3d,iphase,iread)=secureDivision( 1.0, -linf.m.val ); } else { outdata(iphase3d,iphase,iread)=-linf.m.val; } } } } } } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/store.h0000644000175000017500000000612711322062351012507 00000000000000/*************************************************************************** store.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSTORE_H #define RECOSTORE_H #include "step.h" #include #include class RecoStore : public RecoStep { public: static STD_string default_format(); private: // implementing virtual functions of RecoStep STD_string label() const {return "store";} STD_string description() const {return "Store reconstructed images";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,repetition,slice,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoStore;} void init(); JDXstring extension; JDXstring prefix; JDXstring formats; JDXstring imageproc; JDXbool storephase; FileWriteOpts wopts; // for access to some autowrite opts bool store_images(const RecoController& controller); FileIO::ProtocolDataMap pdmap; // Will hold image data with protocol as key Mutex mutex; FilterChain filterchain; }; //////////////////////////////////////////////////////////////////////////// class RecoReal : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "real";} STD_string description() const {return "Throw away imaginary part of data and keep only real part";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::any();} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoReal;} void init() {} }; class RecoMagn : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "magn";} STD_string description() const {return "Only take magnitude and set phase to zero";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoMagn;} void init() {} }; #endif odin-1.8.5/odinreco/sum.cpp0000644000175000017500000000066111322062351012507 00000000000000#include "sum.h" #include "sum_code.h" // Instantiations used in step.cpp template class RecoSum<1, RecoDim<1, readout>, 1, RecoDim<1, average> >; template class RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, cycle> >; template class RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition> >; template class RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition>, true >; odin-1.8.5/odinreco/odinreco.10000644000175000017500000001564611734623240013103 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.38.2. .TH ODINRECO "1" "March 2012" "odinreco 1.8.5" "User Commands" .SH NAME odinreco \- Automatic reconstruction for ODIN sequences .SH SYNOPSIS .B odinreco [ \fIoptions \fR] \fI-r \fR .SH DESCRIPTION odinreco: Automatic reconstruction for ODIN sequences .PP odinreco provides a generic reconstruction for imaging sequences (spin\-warp, EPI, RARE, ...). It retrieves the information about the acquired signal from the file 'recoInfo' which is stored on disk together with the raw data. The recoInfo file contains information about the k\-space position of each acquisition windows (ADC). As output, odinreco generates a bunch of files with different image formats (depending on the option \fB\-f\fR and third\-party libraries available to ODIN). The filename of each file starts with the given output prefix. .SH OPTIONS .HP \fB\-bcw\fR: Correlation weighting of all blades against the mean of all blades (in image space) .HP \fB\-bf\fR: Filter function for blade phase correction (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=NoFilter) .HP \fB\-bfw\fR: Width of the filter function used for blade phase correction.[0.0 (0%) ... 1.0 (100%) of blade width; \fB\-1\fR.0 (100%) ... 0.0 (0%) of center width] (default=1.0) .HP \fB\-bkf\fR: Blade\-keyhole filter function (and its arguments) (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=CosSq) .HP \fB\-bkt\fR: Blade\-keyhole transition width (fraction of oversampled k\-space center) (default=0.20) .HP \fB\-bwf\fR: Window/Filter function for kspace weighting of each blade (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=Triangle) .HP \fB\-bww\fR: Window/Filter width for kspace weighting of each blade (default=1.0) .HP \fB\-cp\fR: Use direct Fourier transform with conjugate\-phase correction instead of gridding .HP \fB\-dcr\fR: Load field drift from this file .HP \fB\-dcw\fR: Calculate and store field drift to file with this prefix .HP \fB\-df\fR: Output format (file extension) of dump files (default=nii) .HP \fB\-dg\fR: Disable GRAPPA interpolation .HP \fB\-dh\fR: Disable homodyne reconstruction .HP \fB\-dm\fR: Disable fieldmap\-based multi\-frequency reconstruction .HP \fB\-dp\fR: Prefix of dump files (default=./dump) .HP \fB\-ds\fR: Disable slice\-time correction .HP \fB\-el\fR: Level relative to mean value of first echo for setting mask of exponential decay fit (default=0.50) .HP \fB\-f\fR: Space sepapared list of output formats (file extensions), possible formats are '3db asc coi dat dcm double float gz hdr idx ima jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk ' (default=nii) .HP \fB\-ff\fR: k\-space filter function (and its arguments) (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=NoFilter) .HP \fB\-fm\fR: Load fieldmap data from this file .HP \fB\-fp\fR: Filter plateau width (0=no plateau, 1=full plateau) (default=0.0) .HP \fB\-gd\fR: Fraction of k\-psace points to discard in auto\-calibration lines because of high residuals (default=0.010) .HP \fB\-gp\fR: Number of neigbouring measured k\-space lines used for GRAPPA interpolation (default=2) .HP \fB\-gr\fR: Number of neigbours in read direction used for GRAPPA interpolation (default=5) .HP \fB\-gs\fR: Scale Factor for the grid used for gridding (default=1.0) .HP \fB\-ip\fR: Command line args for extra processing of final images (default=none) .HP \fB\-j\fR: Number of concurrent jobs(threads) in reco (default=4) .HP \fB\-kg1d\fR: Kernel function for 1d k\-space gridding (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=Gauss(0.36169)) .HP \fB\-kg2d\fR: Kernel function for 2d k\-space gridding (options=Gauss NoFilter Triangle Hann Hamming CosSq Blackman BlackmanNuttall Exp , default=Gauss(0.36169)) .HP \fB\-kh\fR: Keyhole reconstruction, e.g. for PROPELLER .HP \fB\-ks\fR: Store k\-space data .HP \fB\-kw1d\fR: Kernel width for 1d k\-space gridding [Pixel] (default=4.24264Pixel) .HP \fB\-kw2d\fR: Kernel width for 2d k\-space gridding [Pixel] (default=3.0Pixel) .HP \fB\-mf\fR: Maximum number of frequencies for multi\-frequency reconstruction (default=256) .HP \fB\-mn\fR: In sliding\-window maximum\-intensity projection, use this number of neighbors in each direction (default=4) .HP \fB\-mr\fR: Maximum recursion of reconstruction when waiting for blackboard data, zero means no recursion (default=100) .HP \fB\-o\fR: Prefix of output files (default=./image) .HP \fB\-pc\fR: Combine phase of channels using a phase correction .HP \fB\-pe\fR: Exponent for magnitude weighting when calculating combined phase of all channels (default=0.0) .HP \fB\-pf\fR: File name of FIFO (named pipe) to obtain the raw data from .HP \fB\-pop\fR: Recipe for post processing of 3D volume after channel combining (default=null) .HP \fB\-prp\fR: Recipe for post processing of 3D volume before channel combining (default=null) .HP \fB\-pt\fR: Combine and store phase timecourse from all channels .HP \fB\-pz\fR: Pad missing raw data (of interrupted measurement) with zeroes .HP \fB\-qs\fR: Quality control: Check for spikes in data .HP \fB\-rd\fR: Dump signal data and its protocol to files with this prefix, do not reconstruct images .HP \fB\-rf\fR: Read reco recipe (pipeline layout) from this file .HP \fB\-rp\fR: Reco recipe (pipeline layout) .HP \fB\-s\fR: Select certain dimensions ranges (space separated list of 'dim=selection', e.g. slice=3) .HP \fB\-sc\fR: Store images from channels separately instead of combining them .HP \fB\-sp\fR: Store phase in addition to magnitude .HP \fB\-sw\fR: Sliding window reconstruction, e.g. for Spiral/PROPELLER .HP \fB\-t1f\fR: Use this type of T1 fit, can be one of 'simple', 'magnitude' (default=simple) .HP \fB\-t1l\fR: Level relative to mean value of first echo for setting mask of T1 fit (default=0.50) .HP \fB\-t1m\fR: Upper limit for T1 fit [ms] (default=3000.0ms) .HP \fB\-to\fR: Timeout for reco in seconds, 0=inifinite (default=0) .HP \fB\-type\fR: Image representation type (options=automatic float double s32bit u32bit s16bit u16bit s8bit u8bit , default=automatic) .HP \fB\-wdialect\fR: Write data using given dialect of the format. (default is no dialect) .HP \fB\-wp\fR: Store the protocol separately to this file. .HP \fB\-zp\fR: Minimum size of final image in phase direction obtained zero filling (default=0) .HP \fB\-zr\fR: Minimum size of final image in read direction obtained zero filling (default=0) .HP \fB\-zs\fR: Minimum size of final image in slice direction obtained zero filling (default=0) .HP \fB\-v\fR or for debugging/tracing all components or a single component, respectively. Possible values for loglevel are: 0(noLog), 1(errorLog), 2(warningLog), 3(infoLog). .HP \fB\-h\fR, \fB\-\-help\fR, \fB\-help\fR, \fB\-\-version\fR : Print help text or version information odin-1.8.5/odinreco/odinreco.h0000644000175000017500000001422211455553545013171 00000000000000/*************************************************************************** odinreco.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef ODINRECO_H #define ODINRECO_H #include #include /** * \page odinreco_usage Automatic image reconstruction for ODIN sequences * * For image reconstruction, execute the program 'odinreco' within the directory of the file 'recoInfo' (the scan directory), * or use the option '-r' to specify the location of 'recoInfo'. For example, the commands * \verbatim odinreco -r /path/to/raw/data/recoInfo -o /path/to/raw/data/image \endverbatim * and * \verbatim cd /path/to/raw/data/recoInfo odinreco \endverbatim * will do the same, i.e. create an image using the raw data in '/path/to/raw/data/'. * * Full description: * \verbinclude odinreco/odinreco.usage * */ /** * \page odinreco_doc ODIN image reconstruction framework (odinreco) * * This page describes the usage and design guidelines of the module \ref odinreco. * For a description how to execute the reconstruction, please refer to \ref odinreco_usage. * * \section process The reconstruction process * Here, image reconstruction refers to converting MR raw data to an image. * It is achieved by the following processing strategy: * Each single acquisition (ADC) is fed separately into the reconstruction pipeline. * The pipeline consists of a chain of steps(functors) which are executed * subsequently in order to process the input data with the reconstructed image * as the final output. * ADCs are processed simultaneously in different threads allowing acceleration * of reconstruction on multi-processor systems. * It is the responsibility of the steps to synchronize properly * if they possess global (static) data. * * * \section pipeline Setting up a reconstruction pipeline * A reconstruction pipeline is described by a string. * This string consists of single tokens representing a step * which can be any of those described in * \ref odinreco_steps. * These steps are chained together using the pipe operator (|). * Only steps with a compatible input and output interface * may be chained together. * A step may accept additional arguments enclosed in parenthesis * after the step label. * In addition, a step may have command-line options to fine-tune * its behaviour. * Please refer to the manual at (\ref odinreco_steps) for the * input/output interface, arguments and options of each step. * * As an example, a simple 2D/3D reconstruction would look like this: * \verbatim kspace | filter(Gauss) | fft | offset | slicecoll | image | store(result) \endverbatim * This would collect k-space data (kspace), apply a Gaussian filter (filter), * perform an FFT if done (fft) and shift the image (offset). * Finally, after collecting slices and repetitions (slicecoll | image), * it would store the data in files starting with the prefix 'result'. * * * \section blackboard Blackboard * Some steps need data produced by another step in another branch * of the pipeline (e.g. phasemap, fieldmap). To pass this data around, * a thread-safe blackboard system is used to post data and retrieve it later. * In particular, the 'post' step (RecoPost) can used to post data and the function * RecoController::inquire_data() can be used to retrieve this data * in another step. * * \section options Reconstruction Options * Each step can have a number of options (i.e. parameters) to customize * its behavior. For instance, the step for zero filling accepts the * zero-padded sizes of the destination grid as its arguments. * For a list of available options of each step, please refer to * \ref odinreco_steps. * Options can be set in different ways. With ascending priority, * these are: * - Command line options as set in the sequence via recoInfo->set_CmdLineOpts(...); * - Command line options a set directly on the command line. * - By a comma-separated list in parenthesis following the step * string in the recipe, e.g. "... | zerofill(1,256,256) | ..." */ /** * @addtogroup odinreco * @{ */ //////////////////////////////////////////////////////////////// // helper class used for debugging the odinreco component class Reco { public: static const char* get_compName(); }; //////////////////////////////////////////////////////////////// /** * Unsigned integer which initializes to zero */ struct UInt { UInt(unsigned int v=0) : val(v) {} UInt& operator = (unsigned int v) {val=v; return *this;} operator unsigned int () const {return val;} unsigned int operator += (unsigned int rhsval) {val+=rhsval; return *this;} unsigned int operator -= (unsigned int rhsval) {val-=rhsval; return *this;} unsigned int operator *= (unsigned int rhsval) {val*=rhsval; return *this;} unsigned int operator /= (unsigned int rhsval) {val/=rhsval; return *this;} unsigned int operator ++ () {val=val+1; return val;} // prefix unsigned int operator ++ (int) {unsigned int tmp=val; val=val+1; return tmp;} // postfix unsigned int operator -- () {val=val-1; return val;} // prefix unsigned int operator -- (int) {unsigned int tmp=val; val=val-1; return tmp;} // postfix private: unsigned int val; }; /** @} */ #endif odin-1.8.5/odinreco/reader.cpp0000644000175000017500000000002411322062351013136 00000000000000#include "reader.h" odin-1.8.5/odinreco/data.h0000644000175000017500000000744211734622163012277 00000000000000/*************************************************************************** data.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECODATA_H #define RECODATA_H #include #include /** * @addtogroup odinreco * @{ */ /////////////////////////////////////////////////////// /** * Helper class to resolve function overloading */ template struct Rank {}; /////////////////////////////////////////////////////// class Profiler; // forward declaration /** * Class to hold intermediate results (multidimensional complex data) of steps in the reconstruction pipeline. */ class RecoData { public: /** * Mode of complex data: * - complex_data : Regular complex data. * - real_data : Use only real part. * - weighted_real_data : weight real part by imaginray part. */ enum dataMode {complex_data=0, real_data, weighted_real_data}; /** * Creates object with initial k-space coordinate 'coord'. */ RecoData(const RecoCoord& coord=RecoCoord()) : override_protocol(0), mode(complex_data), interpolated(0), kcoord(coord), prof(0) {} /** * Copy constructor (deep copy) */ RecoData(const RecoData& rd) : prof(0) {RecoData::operator = (rd);} /** * Destructor */ ~RecoData(); /** * Assignment operator (deep copy) */ RecoData& operator = (const RecoData& rd); /** * Copy only the meta data from 'rd' */ RecoData& copy_meta(const RecoData& rd); /** * Returns reference to current N-dimensional complex data. * The dimension is determined according to the instantiation of template 'Rank'. */ ComplexData<1>& data(Rank<1>) const {return data1;} ComplexData<2>& data(Rank<2>) const {return data2;} ComplexData<3>& data(Rank<3>) const {return data3;} ComplexData<4>& data(Rank<4>) const {return data4;} ComplexData<5>& data(Rank<5>) const {return data5;} ComplexData<6>& data(Rank<6>) const {return data6;} /** * Returns reference to the k-space coordinate. */ RecoCoord& coord() {return kcoord;} /** * Free (deallocate) data with dimension 'dim'. */ RecoData& free(int dim); /** * Returns const reference to the k-space coordinate. */ const RecoCoord& coord() const {return kcoord;} /** * Override protocol in output files if non-zero */ const Protocol* override_protocol; /** * Type of data. */ dataMode mode; /** * Coordinates interpolated during pipeline execution. */ const CoordCountMap* interpolated; /** * Initializes new profiler object which is allocated/deallocted at the entry and exit of each step * to measure the performance of the pipeline. */ void new_profiler(const STD_string& steplabel); private: RecoCoord kcoord; const Profiler* prof; mutable ComplexData<1> data1; mutable ComplexData<2> data2; mutable ComplexData<3> data3; mutable ComplexData<4> data4; mutable ComplexData<5> data5; mutable ComplexData<6> data6; }; /** @} */ #endif odin-1.8.5/odinreco/swi.cpp0000644000175000017500000001065411363773557012536 00000000000000#include "swi.h" #include "data.h" #include "controller.h" #include #include STD_vector > neighb_indices(int radius_pixels) { STD_vector > result; int n=radius_pixels; for(int k=-n; k<=n; k++) { for(int j=-n; j<=n; j++) { for(int i=-n; i<=n; i++) { float radius=sqrt(float(k*k+j*j+i*i)); if(radius<=radius_pixels && (k || j || i) ) { result.push_back(TinyVector( k, j, i)); } } } } return result; } /////////////////////////////////////////////////////////////////////// bool RecoSwi::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); Data pha(phase(data)); Data magn(cabs(data)); int pixelradius=3; // best // Create linear mask for valid pixels Data mask(magn.size()); mask=1; for(int i=0; i index=magn.create_index(i); for(int j=0; j<3; j++) { if(index(j)shape(j)-pixelradius-1) mask(i)=0; } } STD_vector > neighboffset=neighb_indices(pixelradius); int numof_neigb=neighboffset.size(); for(int j=0; j()).reference(float2real(phadiff)); prot.study.set_Series(series+"_phadiff",number); if(!execute_next_step(rdphadiff,controller)) return false; RecoData rdmed(rd); rdmed.coord().index[userdef]=3; rdmed.data(Rank<3>()).reference(float2real(med)); prot.study.set_Series(series+"_median",number); if(!execute_next_step(rdmed,controller)) return false; return true; } odin-1.8.5/odinreco/collector.h0000644000175000017500000000755111322062351013343 00000000000000/*************************************************************************** collector.h - description ------------------- begin : Sun Jan 14 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOCOLLECTOR_H #define RECOCOLLECTOR_H #include "step.h" /** * @addtogroup odinreco * @{ */ /** * Base class for all collector templates to hold code common to all collectors. */ class RecoCollectorBase : public RecoStep { protected: RecoCollectorBase() {} ~RecoCollectorBase(); /** * Removes 'coord' from the todo map, returns 'true' only if the * current set is fully collected, i.e. the todo map is emtpy. * Note: Do not lock any mutexes when calling this function. * If 'custom_count' is non-zero, it will be used instead * of the cached 'count'. */ bool completed(const RecoCoord& coord, unsigned int custom_count); /** * Calcuate the count, i.e. number inputs to be processed before executing the next step. * 'inmask' and 'outmask' are used to filter on particular indices when calculating the todo map. */ bool calculate_count(RecoQueryContext& context, const RecoCoord& inmask, const RecoCoord& outmask); private: CoordCountMap todo; // coordinate always refers to the output of functor, i.e. after applying 'modify_coord' Mutex todomutex; unsigned int count; // initialized in query/calculate_count, assumed to be the same for all coordinates STD_string label_cache; // label() might not be available in destructor }; ///////////////////////////////////////////////////////// /* * Template class to collect data in one or more dimensions. * The rank of the input data is given by 'Nin'. The particular input dimension are given * in 'In' by a specialization of 'RecoDim'. The numer of dimensions to collect data * for is given in 'Ncoll' and specified in 'Coll' by a specialization of 'RecoDim'. * The resulting data array will have the collected dimensions leftmost, i.e. * if In=i1,i2 and Coll=c1, the resulting array will have dimensions (c1,i1,i2) * If 'use_numof' is set to 'true', the numof of the collected indices will be used * for the count instead of using a count map. */ template class RecoCollector : public RecoCollectorBase, public Labeled { public: RecoCollector(const STD_string& coll_label) : Labeled(coll_label) {} private: // implementing virtual functions of RecoStep STD_string label() const {return get_label();} STD_string description() const {return "Collect data in one or more dimensions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return In::preset_coord(RecoIndex::collected);} void modify_coord(RecoCoord& coord) const {Coll::modify(RecoIndex::collected,coord);} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoCollector(get_label());} void init() {} typedef STD_map > DataMap; DataMap datamap; // the data collected Mutex mutex; }; /** @} */ #endif odin-1.8.5/odinreco/dump.h0000644000175000017500000000305311322062351012313 00000000000000/*************************************************************************** dump.h - description ------------------- begin : Mon Oct 13 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECODUMP_H #define RECODUMP_H #include "step.h" class RecoDump : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "dump";} STD_string description() const {return "Dump current data in reconstruction pipeline";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::any();} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoDump;} void init(); JDXstring prefix; JDXstring format; }; #endif odin-1.8.5/odinreco/fmri.h0000644000175000017500000000322411322062351012303 00000000000000/*************************************************************************** fmri.h - description ------------------- begin : Thu Apr 30 2009 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOFMRI_H #define RECOFMRI_H #include "step.h" class RecoFMRI : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "fmri";} STD_string description() const {return "Simple fMRI analysis for fMRI localizer";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, repetition, line3d, line, readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single,repetition);} RecoStep* allocate() const {return new RecoFMRI;} void init(); JDXint stimsize; JDXint restsize; }; #endif odin-1.8.5/odinreco/Makefile.am0000644000175000017500000000675211725203123013243 00000000000000if ONLY_LIBS else INCLUDES = $(all_includes) bin_PROGRAMS = odinreco odinreco_SOURCES = \ odinreco.h odinreco.cpp \ adc.h adc.cpp \ b1fit.h b1fit.cpp \ blade.h blade.cpp \ bladegrid.h bladegrid.cpp \ blackboard.h blackboard.cpp \ channel.h channel.cpp \ circmask.h circmask.cpp \ collector.h collector_code.h collector.cpp \ conjphase.h conjphase.cpp \ controller.h controller.cpp \ data.h data.cpp \ dump.h dump.cpp \ driftcorr.h driftcorr.cpp \ dti.h dti.cpp \ epinavcorr.h epinavcorr.cpp \ expfit.h expfit.cpp \ fieldmap.h fieldmap.cpp \ filter.h filter.cpp \ fft.h fft.cpp \ fmri.h fmri.cpp \ grappa.h grappa_code.h grappa.cpp \ grid.h grid_code.h grid.cpp \ homodyne.h homodyne_code.h homodyne.cpp \ index.h index.cpp \ messer.h messer.cpp \ measindex.h measindex.cpp \ mip.h mip.cpp \ multifreq.h multifreq.cpp \ offset.h offset.cpp \ oversampling.h oversampling.cpp \ phasecorr.h phasecorr.cpp \ phasecourse.h phasecourse.cpp \ qualitycontrol.h qualitycontrol.cpp \ pilot.h pilot.cpp \ reader.h reader.cpp \ reader_odin.h reader_odin.cpp \ reader_custom.h reader_custom.cpp \ refgain.h refgain.cpp \ slicetime.h slicetime.cpp \ slidingwindow.h slidingwindow.cpp \ splitter.h splitter_code.h splitter.cpp \ step.h step.cpp \ store.h store.cpp \ swi.h swi.cpp \ sum.h sum_code.h sum.cpp \ switch.h switch.cpp \ t1fit.h t1fit.cpp \ zerofill.h zerofill.cpp \ main.cpp odinreco_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Auto-generate manual pages, only if not in srcdir %.1: % if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi # Manual pages for distribution dist_man_MANS = odinreco.1 testdata: rm -rf recotestdata if test ! -f recotestdata.tar.gz ; then wget http://downloads.sourceforge.net/od1n/recotestdata.tar.gz ; fi tar -xvzf recotestdata.tar.gz committest: testdata rm -rf recotestdata/*/test* for dir in recotestdata/*; do \ ./odinreco -f jdx -r $$dir/recoInfo -o $$dir/image; \ done rm -f recotestdata/*/image*.v rm -f recotestdata/*/image*.float rm -rf recotestdata/*/image_* rm -f recotestdata/*/diff* rm -f recotestdata/*/*.sum rm -f recotestdata/*/comp tar -cvzf recotestdata.tar.gz recotestdata # test ! # upload recotestdata.tar.gz to wodan@frs.sourceforge.net:uploads (via sftp) test ! # upload recotestdata.tar.gz via webinterface # Alternative with gdb: gdb -batch -return-child-result -eval-command=run -eval-command=bt -args .libs/odinreco -r $$dir/recoInfo -o $$dir/test test: testdata for dir in recotestdata/*; do \ .libs/odinreco -f jdx -r $$dir/recoInfo -o $$dir/test && \ ../cmdline-utils/micalc -if1 $$dir/test.jdx -op - -if2 $$dir/image.jdx -of $$dir/diff.jdx && \ ../cmdline-utils/micalc -if $$dir/diff.jdx -op abs -of $$dir/diffabs.jdx && \ ../cmdline-utils/micalc -if $$dir/diffabs.jdx -op + > $$dir/diff.sum && \ ../cmdline-utils/micalc -if $$dir/image.jdx -op + > $$dir/image.sum && \ echo "$$(cat $$dir/diff.sum) $$(cat $$dir/image.sum)" > $$dir/comp && \ export LC_ALL=C && \ cat $$dir/comp | awk '{if( 1e3*sqrt($$1*$$1)>sqrt($$2*$$2)) print "ERROR";}' >> $$dir/comp; \ if ! test -f $$dir/comp ; then echo "odinreco failed"; exit -1 ; fi; \ if grep -q ERROR $$dir/comp ; then echo "Difference detected in $$dir"; exit -1 ; fi \ done manual: $(bin_PROGRAMS) for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done ./odinreco -manual > manual.h endif clean-local: -rm -rf recotestdata* *.usage manual.h odin-1.8.5/odinreco/Makefile.in0000644000175000017500000007506311734622602013264 00000000000000# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, # 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, # Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. @SET_MAKE@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c INSTALL_HEADER = $(INSTALL_DATA) transform = $(program_transform_name) NORMAL_INSTALL = : PRE_INSTALL = : POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @ONLY_LIBS_FALSE@bin_PROGRAMS = odinreco$(EXEEXT) subdir = odinreco DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" PROGRAMS = $(bin_PROGRAMS) am__odinreco_SOURCES_DIST = odinreco.h odinreco.cpp adc.h adc.cpp \ b1fit.h b1fit.cpp blade.h blade.cpp bladegrid.h bladegrid.cpp \ blackboard.h blackboard.cpp channel.h channel.cpp circmask.h \ circmask.cpp collector.h collector_code.h collector.cpp \ conjphase.h conjphase.cpp controller.h controller.cpp data.h \ data.cpp dump.h dump.cpp driftcorr.h driftcorr.cpp dti.h \ dti.cpp epinavcorr.h epinavcorr.cpp expfit.h expfit.cpp \ fieldmap.h fieldmap.cpp filter.h filter.cpp fft.h fft.cpp \ fmri.h fmri.cpp grappa.h grappa_code.h grappa.cpp grid.h \ grid_code.h grid.cpp homodyne.h homodyne_code.h homodyne.cpp \ index.h index.cpp messer.h messer.cpp measindex.h \ measindex.cpp mip.h mip.cpp multifreq.h multifreq.cpp offset.h \ offset.cpp oversampling.h oversampling.cpp phasecorr.h \ phasecorr.cpp phasecourse.h phasecourse.cpp qualitycontrol.h \ qualitycontrol.cpp pilot.h pilot.cpp reader.h reader.cpp \ reader_odin.h reader_odin.cpp reader_custom.h \ reader_custom.cpp refgain.h refgain.cpp slicetime.h \ slicetime.cpp slidingwindow.h slidingwindow.cpp splitter.h \ splitter_code.h splitter.cpp step.h step.cpp store.h store.cpp \ swi.h swi.cpp sum.h sum_code.h sum.cpp switch.h switch.cpp \ t1fit.h t1fit.cpp zerofill.h zerofill.cpp main.cpp @ONLY_LIBS_FALSE@am_odinreco_OBJECTS = odinreco.$(OBJEXT) \ @ONLY_LIBS_FALSE@ adc.$(OBJEXT) b1fit.$(OBJEXT) blade.$(OBJEXT) \ @ONLY_LIBS_FALSE@ bladegrid.$(OBJEXT) blackboard.$(OBJEXT) \ @ONLY_LIBS_FALSE@ channel.$(OBJEXT) circmask.$(OBJEXT) \ @ONLY_LIBS_FALSE@ collector.$(OBJEXT) conjphase.$(OBJEXT) \ @ONLY_LIBS_FALSE@ controller.$(OBJEXT) data.$(OBJEXT) \ @ONLY_LIBS_FALSE@ dump.$(OBJEXT) driftcorr.$(OBJEXT) \ @ONLY_LIBS_FALSE@ dti.$(OBJEXT) epinavcorr.$(OBJEXT) \ @ONLY_LIBS_FALSE@ expfit.$(OBJEXT) fieldmap.$(OBJEXT) \ @ONLY_LIBS_FALSE@ filter.$(OBJEXT) fft.$(OBJEXT) fmri.$(OBJEXT) \ @ONLY_LIBS_FALSE@ grappa.$(OBJEXT) grid.$(OBJEXT) \ @ONLY_LIBS_FALSE@ homodyne.$(OBJEXT) index.$(OBJEXT) \ @ONLY_LIBS_FALSE@ messer.$(OBJEXT) measindex.$(OBJEXT) \ @ONLY_LIBS_FALSE@ mip.$(OBJEXT) multifreq.$(OBJEXT) \ @ONLY_LIBS_FALSE@ offset.$(OBJEXT) oversampling.$(OBJEXT) \ @ONLY_LIBS_FALSE@ phasecorr.$(OBJEXT) phasecourse.$(OBJEXT) \ @ONLY_LIBS_FALSE@ qualitycontrol.$(OBJEXT) pilot.$(OBJEXT) \ @ONLY_LIBS_FALSE@ reader.$(OBJEXT) reader_odin.$(OBJEXT) \ @ONLY_LIBS_FALSE@ reader_custom.$(OBJEXT) refgain.$(OBJEXT) \ @ONLY_LIBS_FALSE@ slicetime.$(OBJEXT) slidingwindow.$(OBJEXT) \ @ONLY_LIBS_FALSE@ splitter.$(OBJEXT) step.$(OBJEXT) \ @ONLY_LIBS_FALSE@ store.$(OBJEXT) swi.$(OBJEXT) sum.$(OBJEXT) \ @ONLY_LIBS_FALSE@ switch.$(OBJEXT) t1fit.$(OBJEXT) \ @ONLY_LIBS_FALSE@ zerofill.$(OBJEXT) main.$(OBJEXT) odinreco_OBJECTS = $(am_odinreco_OBJECTS) @ONLY_LIBS_FALSE@odinreco_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/tjutils depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) CXXLD = $(CXX) CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(odinreco_SOURCES) DIST_SOURCES = $(am__odinreco_SOURCES_DIST) am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; am__install_max = 40 am__nobase_strip_setup = \ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` am__nobase_strip = \ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" am__nobase_list = $(am__nobase_strip_setup); \ for p in $$list; do echo "$$p $$p"; done | \ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ if (++n[$$2] == $(am__install_max)) \ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ END { for (dir in files) print dir, files[dir] }' am__base_list = \ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ BASELIBS = @BASELIBS@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DATALIBS = @DATALIBS@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GDB = @GDB@ GREP = @GREP@ GUILIBS = @GUILIBS@ HELP2MAN = @HELP2MAN@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LD = @LD@ LDFLAGS = @LDFLAGS@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ MOC = @MOC@ NM = @NM@ NMEDIT = @NMEDIT@ OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ ODINSEQ_INCLUDES = @ODINSEQ_INCLUDES@ OTOOL = @OTOOL@ OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PLATFORMS = @PLATFORMS@ RANLIB = @RANLIB@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ VTKLIBS = @VTKLIBS@ XMKMF = @XMKMF@ XTERM = @XTERM@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ all_includes = @all_includes@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ builddir = @builddir@ datadir = @datadir@ datarootdir = @datarootdir@ docdir = @docdir@ dvidir = @dvidir@ exec_prefix = @exec_prefix@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ @ONLY_LIBS_FALSE@INCLUDES = $(all_includes) @ONLY_LIBS_FALSE@odinreco_SOURCES = \ @ONLY_LIBS_FALSE@odinreco.h odinreco.cpp \ @ONLY_LIBS_FALSE@adc.h adc.cpp \ @ONLY_LIBS_FALSE@b1fit.h b1fit.cpp \ @ONLY_LIBS_FALSE@blade.h blade.cpp \ @ONLY_LIBS_FALSE@bladegrid.h bladegrid.cpp \ @ONLY_LIBS_FALSE@blackboard.h blackboard.cpp \ @ONLY_LIBS_FALSE@channel.h channel.cpp \ @ONLY_LIBS_FALSE@circmask.h circmask.cpp \ @ONLY_LIBS_FALSE@collector.h collector_code.h collector.cpp \ @ONLY_LIBS_FALSE@conjphase.h conjphase.cpp \ @ONLY_LIBS_FALSE@controller.h controller.cpp \ @ONLY_LIBS_FALSE@data.h data.cpp \ @ONLY_LIBS_FALSE@dump.h dump.cpp \ @ONLY_LIBS_FALSE@driftcorr.h driftcorr.cpp \ @ONLY_LIBS_FALSE@dti.h dti.cpp \ @ONLY_LIBS_FALSE@epinavcorr.h epinavcorr.cpp \ @ONLY_LIBS_FALSE@expfit.h expfit.cpp \ @ONLY_LIBS_FALSE@fieldmap.h fieldmap.cpp \ @ONLY_LIBS_FALSE@filter.h filter.cpp \ @ONLY_LIBS_FALSE@fft.h fft.cpp \ @ONLY_LIBS_FALSE@fmri.h fmri.cpp \ @ONLY_LIBS_FALSE@grappa.h grappa_code.h grappa.cpp \ @ONLY_LIBS_FALSE@grid.h grid_code.h grid.cpp \ @ONLY_LIBS_FALSE@homodyne.h homodyne_code.h homodyne.cpp \ @ONLY_LIBS_FALSE@index.h index.cpp \ @ONLY_LIBS_FALSE@messer.h messer.cpp \ @ONLY_LIBS_FALSE@measindex.h measindex.cpp \ @ONLY_LIBS_FALSE@mip.h mip.cpp \ @ONLY_LIBS_FALSE@multifreq.h multifreq.cpp \ @ONLY_LIBS_FALSE@offset.h offset.cpp \ @ONLY_LIBS_FALSE@oversampling.h oversampling.cpp \ @ONLY_LIBS_FALSE@phasecorr.h phasecorr.cpp \ @ONLY_LIBS_FALSE@phasecourse.h phasecourse.cpp \ @ONLY_LIBS_FALSE@qualitycontrol.h qualitycontrol.cpp \ @ONLY_LIBS_FALSE@pilot.h pilot.cpp \ @ONLY_LIBS_FALSE@reader.h reader.cpp \ @ONLY_LIBS_FALSE@reader_odin.h reader_odin.cpp \ @ONLY_LIBS_FALSE@reader_custom.h reader_custom.cpp \ @ONLY_LIBS_FALSE@refgain.h refgain.cpp \ @ONLY_LIBS_FALSE@slicetime.h slicetime.cpp \ @ONLY_LIBS_FALSE@slidingwindow.h slidingwindow.cpp \ @ONLY_LIBS_FALSE@splitter.h splitter_code.h splitter.cpp \ @ONLY_LIBS_FALSE@step.h step.cpp \ @ONLY_LIBS_FALSE@store.h store.cpp \ @ONLY_LIBS_FALSE@swi.h swi.cpp \ @ONLY_LIBS_FALSE@sum.h sum_code.h sum.cpp \ @ONLY_LIBS_FALSE@switch.h switch.cpp \ @ONLY_LIBS_FALSE@t1fit.h t1fit.cpp \ @ONLY_LIBS_FALSE@zerofill.h zerofill.cpp \ @ONLY_LIBS_FALSE@main.cpp @ONLY_LIBS_FALSE@odinreco_LDADD = ../odindata/libodindata.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la # Manual pages for distribution @ONLY_LIBS_FALSE@dist_man_MANS = odinreco.1 all: all-am .SUFFIXES: .SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu odinreco/Makefile'; \ $(am__cd) $(top_srcdir) && \ $(AUTOMAKE) --gnu odinreco/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(top_srcdir)/configure: $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(am__aclocal_m4_deps): install-binPROGRAMS: $(bin_PROGRAMS) @$(NORMAL_INSTALL) test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)" @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ for p in $$list; do echo "$$p $$p"; done | \ sed 's/$(EXEEXT)$$//' | \ while read p p1; do if test -f $$p || test -f $$p1; \ then echo "$$p"; echo "$$p"; else :; fi; \ done | \ sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \ -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ sed 'N;N;N;s,\n, ,g' | \ $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ if ($$2 == $$4) files[d] = files[d] " " $$1; \ else { print "f", $$3 "/" $$4, $$1; } } \ END { for (d in files) print "f", d, files[d] }' | \ while read type dir files; do \ if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ test -z "$$files" || { \ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ } \ ; done uninstall-binPROGRAMS: @$(NORMAL_UNINSTALL) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ files=`for p in $$list; do echo "$$p"; done | \ sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ -e 's/$$/$(EXEEXT)/' `; \ test -n "$$list" || exit 0; \ echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(bindir)" && rm -f $$files clean-binPROGRAMS: @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \ echo " rm -f" $$list; \ rm -f $$list || exit $$?; \ test -n "$(EXEEXT)" || exit 0; \ list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ echo " rm -f" $$list; \ rm -f $$list odinreco$(EXEEXT): $(odinreco_OBJECTS) $(odinreco_DEPENDENCIES) @rm -f odinreco$(EXEEXT) $(CXXLINK) $(odinreco_OBJECTS) $(odinreco_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) distclean-compile: -rm -f *.tab.c @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adc.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/b1fit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blackboard.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blade.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bladegrid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/channel.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/circmask.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/collector.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conjphase.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/controller.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/data.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/driftcorr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dti.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/epinavcorr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/expfit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fft.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fieldmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fmri.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grappa.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/grid.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/homodyne.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/index.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/measindex.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messer.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mip.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/multifreq.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/odinreco.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/offset.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oversampling.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phasecorr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/phasecourse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pilot.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qualitycontrol.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader_custom.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reader_odin.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refgain.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slicetime.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slidingwindow.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/splitter.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/step.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/store.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sum.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/swi.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/switch.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1fit.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/zerofill.Po@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)" @list=''; test -n "$(man1dir)" || exit 0; \ { for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | while read p; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ echo "$$d$$p"; echo "$$p"; \ done | \ sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ sed 'N;N;s,\n, ,g' | { \ list=; while read file base inst; do \ if test "$$base" = "$$inst"; then list="$$list $$file"; else \ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \ fi; \ done; \ for i in $$list; do echo "$$i"; done | $(am__base_list) | \ while read files; do \ test -z "$$files" || { \ echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \ done; } uninstall-man1: @$(NORMAL_UNINSTALL) @list=''; test -n "$(man1dir)" || exit 0; \ files=`{ for i in $$list; do echo "$$i"; done; \ l2='$(dist_man_MANS)'; for i in $$l2; do echo "$$i"; done | \ sed -n '/\.1[a-z]*$$/p'; \ } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \ -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ test -z "$$files" || { \ echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \ cd "$(DESTDIR)$(man1dir)" && rm -f $$files; } ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ shift; \ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ if test $$# -gt 0; then \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ "$$@" $$unique; \ else \ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ $$unique; \ fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ && $(am__cd) $(top_srcdir) \ && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) @list='$(MANS)'; if test -n "$$list"; then \ list=`for p in $$list; do \ if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \ if test -n "$$list" && \ grep 'ab help2man is required to generate this page' $$list >/dev/null; then \ echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \ grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \ echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \ echo " typically \`make maintainer-clean' will remove them" >&2; \ exit 1; \ else :; fi; \ else :; fi @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ list='$(DISTFILES)'; \ dist_files=`for file in $$list; do echo $$file; done | \ sed -e "s|^$$srcdirstrip/||;t" \ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ case $$dist_files in \ */*) $(MKDIR_P) `echo "$$dist_files" | \ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ sort -u` ;; \ esac; \ for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d "$(distdir)/$$file"; then \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ test -f "$(distdir)/$$file" \ || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am install-exec: install-exec-am install-data: install-data-am uninstall: uninstall-am install-am: all-am @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am installcheck: installcheck-am install-strip: $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ `test -z '$(STRIP)' || \ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install mostlyclean-generic: clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @echo "it deletes files that may require special tools to rebuild." clean: clean-am clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \ mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags dvi: dvi-am dvi-am: html: html-am html-am: info: info-am info-am: install-data-am: install-man install-dvi: install-dvi-am install-dvi-am: install-exec-am: install-binPROGRAMS install-html: install-html-am install-html-am: install-info: install-info-am install-info-am: install-man: install-man1 install-pdf: install-pdf-am install-pdf-am: install-ps: install-ps-am install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-am mostlyclean-am: mostlyclean-compile mostlyclean-generic \ mostlyclean-libtool pdf: pdf-am pdf-am: ps: ps-am ps-am: uninstall-am: uninstall-binPROGRAMS uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \ clean-generic clean-libtool clean-local ctags distclean \ distclean-compile distclean-generic distclean-libtool \ distclean-tags distdir dvi dvi-am html html-am info info-am \ install install-am install-binPROGRAMS install-data \ install-data-am install-dvi install-dvi-am install-exec \ install-exec-am install-html install-html-am install-info \ install-info-am install-man install-man1 install-pdf \ install-pdf-am install-ps install-ps-am install-strip \ installcheck installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ tags uninstall uninstall-am uninstall-binPROGRAMS \ uninstall-man uninstall-man1 # Auto-generate manual pages, only if not in srcdir @ONLY_LIBS_FALSE@%.1: % @ONLY_LIBS_FALSE@ if test ! -f $(srcdir)/$@ ; then $(HELP2MAN) --name="$$(./$< --help | grep $<: | sed s/'$<: '//)" ./$< > $@ ; fi @ONLY_LIBS_FALSE@testdata: @ONLY_LIBS_FALSE@ rm -rf recotestdata @ONLY_LIBS_FALSE@ if test ! -f recotestdata.tar.gz ; then wget http://downloads.sourceforge.net/od1n/recotestdata.tar.gz ; fi @ONLY_LIBS_FALSE@ tar -xvzf recotestdata.tar.gz @ONLY_LIBS_FALSE@committest: testdata @ONLY_LIBS_FALSE@ rm -rf recotestdata/*/test* @ONLY_LIBS_FALSE@ for dir in recotestdata/*; do \ @ONLY_LIBS_FALSE@ ./odinreco -f jdx -r $$dir/recoInfo -o $$dir/image; \ @ONLY_LIBS_FALSE@ done @ONLY_LIBS_FALSE@ rm -f recotestdata/*/image*.v @ONLY_LIBS_FALSE@ rm -f recotestdata/*/image*.float @ONLY_LIBS_FALSE@ rm -rf recotestdata/*/image_* @ONLY_LIBS_FALSE@ rm -f recotestdata/*/diff* @ONLY_LIBS_FALSE@ rm -f recotestdata/*/*.sum @ONLY_LIBS_FALSE@ rm -f recotestdata/*/comp @ONLY_LIBS_FALSE@ tar -cvzf recotestdata.tar.gz recotestdata # test ! # upload recotestdata.tar.gz to wodan@frs.sourceforge.net:uploads (via sftp) @ONLY_LIBS_FALSE@ test ! # upload recotestdata.tar.gz via webinterface # Alternative with gdb: gdb -batch -return-child-result -eval-command=run -eval-command=bt -args .libs/odinreco -r $$dir/recoInfo -o $$dir/test @ONLY_LIBS_FALSE@test: testdata @ONLY_LIBS_FALSE@ for dir in recotestdata/*; do \ @ONLY_LIBS_FALSE@ .libs/odinreco -f jdx -r $$dir/recoInfo -o $$dir/test && \ @ONLY_LIBS_FALSE@ ../cmdline-utils/micalc -if1 $$dir/test.jdx -op - -if2 $$dir/image.jdx -of $$dir/diff.jdx && \ @ONLY_LIBS_FALSE@ ../cmdline-utils/micalc -if $$dir/diff.jdx -op abs -of $$dir/diffabs.jdx && \ @ONLY_LIBS_FALSE@ ../cmdline-utils/micalc -if $$dir/diffabs.jdx -op + > $$dir/diff.sum && \ @ONLY_LIBS_FALSE@ ../cmdline-utils/micalc -if $$dir/image.jdx -op + > $$dir/image.sum && \ @ONLY_LIBS_FALSE@ echo "$$(cat $$dir/diff.sum) $$(cat $$dir/image.sum)" > $$dir/comp && \ @ONLY_LIBS_FALSE@ export LC_ALL=C && \ @ONLY_LIBS_FALSE@ cat $$dir/comp | awk '{if( 1e3*sqrt($$1*$$1)>sqrt($$2*$$2)) print "ERROR";}' >> $$dir/comp; \ @ONLY_LIBS_FALSE@ if ! test -f $$dir/comp ; then echo "odinreco failed"; exit -1 ; fi; \ @ONLY_LIBS_FALSE@ if grep -q ERROR $$dir/comp ; then echo "Difference detected in $$dir"; exit -1 ; fi \ @ONLY_LIBS_FALSE@ done @ONLY_LIBS_FALSE@manual: $(bin_PROGRAMS) @ONLY_LIBS_FALSE@ for prog in $(bin_PROGRAMS); do ./$$prog -h > ./`basename $$prog $(EXEEXT)`.usage ; done @ONLY_LIBS_FALSE@ ./odinreco -manual > manual.h clean-local: -rm -rf recotestdata* *.usage manual.h # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: odin-1.8.5/odinreco/grid.h0000644000175000017500000000664311455553545012324 00000000000000/*************************************************************************** grid.h - description ------------------- begin : Wed Feb 21 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOGRID_H #define RECOGRID_H #include "step.h" template class RecoGrid : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "grid"+postfix();} STD_string description() const {return "Grid signal data with arbitrary k-space trajectory in "+itos(NDim)+" dimensions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, readout);} void modify_coord(RecoCoord& coord) const {if(NDim==2) coord.set_mode(RecoIndex::collected, line);} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoGrid;} void init(); JDXbool deapo_shift; JDXfilter kernel; JDXfloat kernelwidth; JDXfloat gridScale; static STD_string postfix() {return itos(NDim)+"d";} static TinyVector gridshape(const RecoCoord& coord, RecoController& controller); const Gridding& get_gridder(const RecoCoord& coord, RecoController& controller); // cache gridders typedef STD_map > GridderMap; GridderMap gridmap; Mutex gridmutex; }; ///////////////////////////////////////////////////////////////////////////////// template class RecoDeapodize : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "deapodize"+postfix();} STD_string description() const {return "De-apodize gridded data in "+itos(NDim)+" dimensions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, line3d, line, readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoDeapodize;} void init() {} static STD_string postfix() {return itos(NDim)+"d";} }; class RecoGridCut : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "gridcut"; } STD_string description() const {return "Cut out central part of image to remove effects from gridding on a denser grid";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, line3d, line, readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoGridCut;} void init() {} }; #endif odin-1.8.5/odinreco/slicetime.h0000644000175000017500000000316711322062351013332 00000000000000/*************************************************************************** slicetime.h - description ------------------- begin : Sun Jun 3 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSLICETIME_H #define RECOSLICETIME_H #include "step.h" class RecoSliceTime : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "slicetime";} STD_string description() const {return "Slice-time correction for data with multiple repetitions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected, repetition, slice, line3d, line, readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoSliceTime;} void init() {} }; #endif odin-1.8.5/odinreco/reader_custom.cpp0000644000175000017500000001204111322062351014532 00000000000000#include "reader_custom.h" #include // for loading sample file bool RecoReaderCustom::init(const STD_string& input_filename) { Log odinlog("RecoReaderCustom","init"); Range all=Range::all(); // Create synthetic raw data using a virtual sample // Load sample Sample smp; if(smp.load(input_filename)<0) { ODINLOG(odinlog,errorLog) << "Cannot read sample file " << input_filename << STD_endl; return false; } farray spinDensity=smp.get_spinDensity(); spinDensity.autosize(); ODINLOG(odinlog,infoLog) << "Read sample with extent " << STD_string(spinDensity.get_extent()) << STD_endl; ///////////////////////////////////////////////////////////////////////////////////// // Create the raw data // Create signal data for one image ComplexData<2> oneimage(float2real(Data(spinDensity))); oneimage.fft(); // Create 2-dim raw data array, these dims are: (repetition x slice x phase, read) int nrep=15; int nslice=7; int nphase=oneimage.extent(1); int nread=oneimage.extent(0); int nadcs=nrep*nslice*nphase; rawdata.resize(nadcs, nread); // Resize the vector of reco coordinates (indices) coord_vec_cache.resize(nadcs); // Iterate over dimensions and create raw data and reco indices count=0; for(int irep=0; irep(0.0,0.05,0.1); // shift image in phase and read direction by 0.05*FOV and 0.1*FOV, respectively ///////////////////////////////////////////////////////////////////////////////////// // Adjust protocol. We can keep the default settings, or fill in our own values. // Most of these settings are irrelevant for the reconstruction, but will // stored together with the raw data, e.g. in DICOM files // Study information, which is stored together with the raw data prot_cache.study.set_Patient("TESTID", "John Doe", "19730913", 'M', 80.0); prot_cache.study.set_Context("RecoReaderCustom","DrNo"); prot_cache.study.set_Series("Test",7); // Set some parameters that might be relevant to reco prot_cache.seqpars.set_RepetitionTime(1300.0).set_FlipAngle(66.0); // For correct T1 fit prot_cache.seqpars.set_ReductionFactor(1); // For correct GRAPPA interpolation // Geometry settings prot_cache.geometry.set_orientation(-66.7, 78.2, -124.7); prot_cache.geometry.set_offset(readDirection,22.7); prot_cache.geometry.set_offset(phaseDirection,-5.9); prot_cache.geometry.set_offset(sliceDirection,1.9); prot_cache.geometry.set_FOV(readDirection,192.6); prot_cache.geometry.set_FOV(phaseDirection,200.2); prot_cache.geometry.set_sliceDistance(6.1); prot_cache.geometry.set_sliceThickness(3.2); ///////////////////////////////////////////////////////////////////////////////////// count=0; // reset global counter because it is used in fetch return true; } bool RecoReaderCustom::fetch(RecoCoord& coord, ComplexData<1>& adc) { if(count>=coord_vec_cache.size()) return false; // This check is necessary for proper multi-threading // Return the next raw data ADC coord=coord_vec_cache[count]; adc.resize(rawdata.extent(1)); adc=rawdata(count, Range::all()); // Return deep copy bool contin=int(count) /////////////////////////////////////////////////////////////////////////// // function class to fit IR timecourse struct InversionRecoveryFunction : public ModelFunction { fitpar M0; fitpar lambda; float evaluate_f(float x) const {return M0.val * (1.0 - 2.0 * exp (lambda.val * x) );} fvector evaluate_df(float x) const { fvector result(numof_fitpars()); result[0]=1.0 - 2.0 * exp (lambda.val * x); result[1]=-x * 2.0 * M0.val * exp (lambda.val * x); return result; } unsigned int numof_fitpars() const {return 2;} fitpar& get_fitpar(unsigned int i) { if(i==0) return M0; if(i==1) return lambda; return dummy_fitpar; } }; /////////////////////////////////////////////////////////////////////////// // function class to fit magnitude IR timecourse struct InversionRecoveryAbsFunction : public ModelFunction { bool fitphi; fitpar M0; fitpar phi; fitpar Ri; float evaluate_f(float x) const { double winkel = atan(phi.val)/PII+0.5; double e = exp(-Ri.val*x); return fabs(M0.val*(1-2*winkel*e)); } fvector evaluate_df(float x) const { fvector result(numof_fitpars()); double winkel = atan(phi.val)/PII+0.5; double e = exp(-Ri.val*x); double Fun = (2*winkel*e-1); result[0]=fabs(M0.val)*fabs(Fun)/M0.val; result[1]=(-2.0*fabs(M0.val)*winkel*x*e*Fun)/(fabs(Fun)); if(fitphi) result[2]=(2.0*fabs(M0.val)*e*Fun)/(PII*(pow(phi.val,2)+1)*fabs(Fun)); return result; } unsigned int numof_fitpars() const {return 2+fitphi;} fitpar& get_fitpar(unsigned int i) { if(i==0) return M0; if(i==1) return Ri; if(i==2) return phi; return dummy_fitpar; } }; /////////////////////////////////////////////////////////////////////////// void RecoT1Fit::init() { fittype="simple"; fittype.set_cmdline_option("t1f").set_description("Use this type of T1 fit, can be one of 'simple', 'magnitude'"); append_arg(fittype,"fittype"); masklevel=0.5; masklevel.set_cmdline_option("t1l").set_description("Level relative to mean value of first echo for setting mask of T1 fit"); append_arg(masklevel,"masklevel"); maxt1=3000.0; maxt1.set_unit(ODIN_TIME_UNIT).set_cmdline_option("t1m").set_description("Upper limit for T1 fit"); append_arg(maxt1,"maxt1"); } #define START_T1 1000.0 bool RecoT1Fit::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); Data magn(cabs(indata)); TinyVector inshape=indata.shape(); TinyVector outshape(inshape(1), inshape(2), inshape(3)); // magn.autowrite("magn.jdx"); ODINLOG(odinlog,normalDebug) << "inshape=" << inshape << STD_endl; dvector tis=controller.dim_values(userdef); ODINLOG(odinlog,normalDebug) << "tis=" << tis.printbody() << STD_endl; int ntis=tis.size(); if(ntis!=inshape(0) || ntis<2) { ODINLOG(odinlog,errorLog) << "size mismatch or too small" << STD_endl; return false; } float noiselevel=masklevel*mean(magn(0,all,all,all)); float deltaEcho=tis[1]-tis[0]; Protocol prot(controller.protocol()); float pulse_term=log(cos(prot.seqpars.get_FlipAngle()/180.0*PII))/deltaEcho; ODINLOG(odinlog,normalDebug) << "pulse_term=" << pulse_term << STD_endl; InversionRecoveryFunction irfunc; InversionRecoveryAbsFunction irabsfunc; irabsfunc.fitphi=false; FunctionFit irfit(irfunc,ntis); FunctionFit irabsfit(irabsfunc,ntis); Data T1map(outshape); T1map=0.0; Data S0map(outshape); S0map=0.0; Data angmap(outshape); angmap=0.0; Data pixel4fit(ntis); Data ysigma(ntis); ysigma=1.0; Data xvals(ntis); for(int iti=0; itinoiselevel) { pixel4fit=magn(all,iphase3d,iphase,iread); int minindex=minIndex(pixel4fit)(0); float M0=0.0; float t1star=0.0; float angle=0.0; if(fittype=="magnitude") { irabsfunc.M0.val=max(pixel4fit); irabsfunc.phi.val=tan(PII*cos(PII*170/180-PII)-PII/2); irabsfunc.Ri.val=secureInv( 1.45*tis[minindex]); if(irabsfit.fit(pixel4fit, ysigma, xvals)) { M0=irabsfunc.M0.val; angle=acos(-atan(irabsfunc.phi.val)/PII-0.5)/PII*180.0; t1star=secureInv(irabsfunc.Ri.val); } } else { for(int i=0; i0.0) t1=secureDivision(1.0 , 1.0/t1star + pulse_term); // correction for Look Locker sequence check_range(t1, 0.0, maxt1); T1map(iphase3d,iphase,iread)=t1; S0map(iphase3d,iphase,iread)=M0; angmap(iphase3d,iphase,iread)=angle; } } } } // modify coordinate int numof_output=2; if(sum(angmap)>0.0) numof_output++; rd.coord().index[userdef].set_numof(numof_output); rd.override_protocol=&prot; STD_string series; int number; prot.study.get_Series(series, number); // feed T1 into rest of pipeline RecoData rdT1(rd); rdT1.data(Rank<3>()).resize(outshape); rdT1.data(Rank<3>())=float2real(T1map); rdT1.coord().index[userdef]=0; prot.study.set_Series(series+"_T1",number); if(!execute_next_step(rdT1,controller)) return false; // feed S0 into rest of pipeline RecoData rdS0(rd); rdS0.data(Rank<3>()).resize(outshape); rdS0.data(Rank<3>())=float2real(S0map); rdS0.coord().index[userdef]=1; prot.study.set_Series(series+"_S0",number); if(!execute_next_step(rdS0,controller)) return false; // feed angle into rest of pipeline if(sum(angmap)>0.0) { RecoData rdang(rd); rdang.data(Rank<3>()).resize(outshape); rdang.data(Rank<3>())=float2real(angmap); rdang.coord().index[userdef]=2; prot.study.set_Series(series+"_angle",number); if(!execute_next_step(rdang,controller)) return false; } return true; } odin-1.8.5/odinreco/zerofill.cpp0000644000175000017500000000444711455553545013560 00000000000000#include "zerofill.h" #include "data.h" #include "controller.h" void RecoZeroFill::init() { minread=0; minread.set_cmdline_option("zr").set_description("Minimum size of final image in read direction obtained zero filling"); append_arg(minread,"minread"); minphase=0; minphase.set_cmdline_option("zp").set_description("Minimum size of final image in phase direction obtained zero filling"); append_arg(minphase,"minphase"); minslice=0; minslice.set_cmdline_option("zs").set_description("Minimum size of final image in slice direction obtained zero filling"); append_arg(minslice,"minslice"); } bool RecoZeroFill::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector oldshape=data.shape(); TinyVector newshape=controller.image_size(); ODINLOG(odinlog,normalDebug) << "controller.image_size()=" << newshape << STD_endl; newshape(0)=STD_max(newshape(0),int(minslice)); newshape(1)=STD_max(newshape(1),int(minphase)); newshape(2)=STD_max(newshape(2),int(float(minread)*rd.coord().overSamplingFactor+0.5)); // take oversampling into account if(oldshape!=newshape) { for(int idim=0; idim<3; idim++) { newshape(idim)=STD_max(newshape(idim),oldshape(idim)); // only size increase } ODINLOG(odinlog,normalDebug) << "newshape/oldshape=" << newshape << "/" << oldshape << STD_endl; TinyVector lowerBounds, upperBounds; for(int idim=0; idim<3; idim++) { int diff=newshape(idim)-oldshape(idim); if(diff>0) { lowerBounds(idim)=diff/2; // offset to center old data upperBounds(idim)=lowerBounds(idim)+oldshape(idim)-1; } else { lowerBounds(idim)=0; upperBounds(idim)=oldshape(idim)-1; } } ODINLOG(odinlog,normalDebug) << "lowerBounds/upperBounds=" << lowerBounds << "/" << upperBounds << STD_endl; ComplexData<3> datacopy(data); datacopy.makeUnique(); data.resize(newshape); data=STD_complex(0.0); data(RectDomain<3>(lowerBounds, upperBounds))=datacopy; // adjust numof rd.coord().index[line3d].set_numof(newshape(0)); rd.coord().index[line].set_numof(newshape(1)); rd.coord().index[readout].set_numof(newshape(2)); } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/splitter.h0000644000175000017500000000454411322062351013222 00000000000000/*************************************************************************** splitter.h - description ------------------- begin : Fri Feb 2 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSPLITTER_H #define RECOSPLITTER_H #include "step.h" /* * Template class to split data in one or more dimensions and to feed it separately * into the remaining part of the pipeline. * The rank of the unmodified collected data dimensions is is given by 'Nunmod'. * The particular unmodified dimension are given in 'Unmod' by a specialization of 'RecoDim'. * The numer of dimensions to split is given in 'Nsplit' and specified in 'Split' by * a specialization of 'RecoDim'. * The dimensions to split are expected leftmost in the input data array. */ template class RecoSplitter : public RecoStep, public Labeled { public: RecoSplitter(const STD_string& split_label) : Labeled(split_label) {} private: // implementing virtual functions of RecoStep STD_string label() const {return get_label();} STD_string description() const {return "Split data in one or more dimensions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {RecoCoord result=Unmod::preset_coord(RecoIndex::collected); Split::modify(RecoIndex::collected,result); return result;} void modify_coord(RecoCoord& coord) const {Split::modify(RecoIndex::separate,coord);} RecoStep* allocate() const {return new RecoSplitter(get_label());} void init() {} }; #endif odin-1.8.5/odinreco/filter.cpp0000644000175000017500000000300711322062351013165 00000000000000#include "filter.h" #include "data.h" #include "controller.h" void RecoFilter::init() { filter.set_funcpars("NoFilter"); filter.set_cmdline_option("ff").set_description("k-space filter function (and its arguments)"); append_arg(filter,"filter"); plateau=0.0; plateau.set_cmdline_option("fp").set_description("Filter plateau width (0=no plateau, 1=full plateau)"); append_arg(plateau,"plateau"); } bool RecoFilter::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ODINLOG(odinlog,normalDebug) << "filter/plateau=" << filter.get_function_name() << "/" << plateau << STD_endl; if(filter.get_function_name()!="NoFilter") { ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); ODINLOG(odinlog,normalDebug) << "shape=" << shape << STD_endl; float plat=plateau; check_range(plat, 0.0, 1.0); float plateau_factor=secureInv( 1.0-plat); for(int i=0; i index=data.create_index(i); float factor=1.0; for(int idir=0; idir<3; idir++) { if(shape(idir)>1) { float relradius=2.0*secureDivision(abs(index(idir)-shape(idir)/2),shape(idir)); if(relradius>plat) { relradius=plateau_factor*(relradius-plateau); if(relradius<=1.0) factor*=filter.calculate(relradius); else factor=0.0; } } } data(index)*=STD_complex(factor); } } return execute_next_step(rd, controller); } odin-1.8.5/odinreco/index.cpp0000644000175000017500000000211711322062351013010 00000000000000#include "index.h" STD_string RecoIndex::print(recoDim dim, printMode printmode) const { bool do_print=false; if(printmode==brief && (numof>1 || mode==single)) do_print=true; if(printmode==all) do_print=true; if(printmode==filename && numof>1 && mode==separate) do_print=true; if(do_print) { STD_string result=kSpaceCoord::index2string(val, dim, numof); switch(mode) { case ignore: result+="i"; break; case single: result+="s"; break; case collected: result="all"; break; case any: result="any"; break; } return result; } return ""; } STD_string RecoCoord::print(RecoIndex::printMode printmode) const { STD_string result; const char* separator=","; const char* equals="="; if(printmode==RecoIndex::filename) { separator="_"; equals=""; } bool first=true; for(int i=0; i& data=rd.data(Rank<1>()); ComplexData<1> adc_reversed(data.copy()); adc_reversed.reverseSelf(firstDim); data(Range::all())=adc_reversed(Range::all()); } return execute_next_step(rd,controller); } /////////////////////////////////////////////////////////////////////////// bool RecoAdcGridPrep::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); if(rd.coord().readoutShape) { trajmutex.lock(); // also protect global readoutShape if(!traj.size()) { const Data& readoutShape=rd.coord().readoutShape->first; ComplexData<1>& indata=rd.data(Rank<1>()); int npts=indata.size(); ODINLOG(odinlog,normalDebug) << "npts=" << npts << STD_endl; if(readoutShape.size()!=npts) { trajmutex.unlock(); ODINLOG(odinlog,errorLog) << "Size mismatch: " << readoutShape.size() << "!=" << npts << STD_endl; return false; } // calc kspace by integration of readout shape fvector kspace(npts); kspace=0.0; if(npts) { kspace[0]=0.5*readoutShape(0); for(int i=1; i(0.0,0.0,kspace[i]); } } trajmutex.unlock(); rd.coord().kspaceTraj=&traj; } return execute_next_step(rd,controller); } /////////////////////////////////////////////////////////////////////////// bool RecoAdcWeight::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); const ComplexData<1>* weightVec=rd.coord().weightVec; if(weightVec) { MutexLock lock(weightMutex); // protect global weightVec int weightsize=weightVec->size(); ODINLOG(odinlog,normalDebug) << "weightsize=" << weightsize << STD_endl; ComplexData<1>& data=rd.data(Rank<1>()); if(weightsize!=data.extent(0)) { ODINLOG(odinlog,errorLog) << "Size mismatch weightsize(" << weightsize << ")!=adc(" << data.extent(0) << ")" << STD_endl; return false; } data=data*(*weightVec); } return execute_next_step(rd,controller); } /////////////////////////////////////////////////////////////////////////// bool RecoAdcBaseline::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<1>& adc=rd.data(Rank<1>()); float maxsig=max(cabs(adc)); // Calculate mean complex offset of samples with small magnitude int nsamples_bline=0; STD_complex sigsum(0.0); for(int isample=0; isample odinlog(c_label(),"process"); ComplexData<1>& adc=rd.data(Rank<1>()); float relcenter=rd.coord().relCenterPos; if(relcenter<0.0 || relcenter>1.0) { ODINLOG(odinlog,errorLog) << "relcenter=" << relcenter << STD_endl; return false; } bool end_omitted=false; if(relcenter>0.5) { relcenter=1.0-relcenter; } int oldsize=adc.size(); int newsize=int(2.0*(1.0-relcenter)*oldsize+0.5); ODINLOG(odinlog,normalDebug) << "oldsize/newsize=" << oldsize << "/" << newsize << STD_endl; ComplexData<1> newadc(newsize); newadc=STD_complex(0.0); int offset=newsize-oldsize; if(end_omitted) offset=0; newadc(Range(offset,offset+oldsize-1))=adc; adc.reference(newadc); // adjust numof and center position rd.coord().index[readout].set_numof(newsize); rd.coord().relCenterPos=0.5; // Adjust adcstart/end if(!end_omitted) { rd.coord().adcstart+=offset; rd.coord().adcend+=offset; } ODINLOG(odinlog,normalDebug) << "adcstart/adcend=" << rd.coord().adcstart << "/" << rd.coord().adcend << STD_endl; return execute_next_step(rd,controller); } odin-1.8.5/odinreco/epinavcorr.cpp0000644000175000017500000001033711734622163014066 00000000000000#include "epinavcorr.h" #include "data.h" #include "controller.h" #include static const char* posted_phasemap_label="epinav"; bool RecoEpiNavScan::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<2>& indata=rd.data(Rank<2>()); TinyVector inshape(indata.shape()); int nechoes=inshape(0); int nread=inshape(1); if(nechoes!=3) { ODINLOG(odinlog,errorLog) << "nechoes=" << nechoes << STD_endl; return false; } TinyVector navshape(2,nread); ComplexData<2> navdata(navshape); navdata(0,all)=STD_complex(0.5)*(indata(0,all)+indata(2,all)); // average both even echoes navdata(1,all)=indata(1,all); // FFT in read direction navdata.partial_fft(TinyVector(false,true)); ComplexData<2> phasemap(navshape); // The result // Calculate phase-difference Data phasediff(nread); Data sigma(nread); // Error for fit for(int iread=0; iread(expc(float2imag(phasediff))).phasemap(); // Linear fit to phasediff LinearFunction linf; linf.fit(phasediff, sigma); float slope=linf.m.val; float offset=linf.c.val; ODINLOG(odinlog,normalDebug) << "slope/offset=" << slope << "/" << offset << STD_endl; for(int iread=0; iread odinlog(c_label(),"process"); if(!controller.data_announced(posted_phasemap_label)) { ODINLOG(odinlog,errorLog) << posted_phasemap_label << " not available" << STD_endl; return false; } RecoData one_echo_phasemap; one_echo_phasemap.coord()=rd.coord(); RecoEpiNavScan::modify4blackboard(one_echo_phasemap.coord()); int itrain=rd.coord().echotrain; ODINLOG(odinlog,normalDebug) << "itrain=" << itrain << STD_endl; one_echo_phasemap.coord().index[epi]=itrain; int iecho=bool(rd.coord().flags&recoReflectBit); ODINLOG(odinlog,normalDebug) << "iecho=" << iecho << STD_endl; one_echo_phasemap.coord().index[echo]=iecho; if(!controller.inquire_data(posted_phasemap_label, one_echo_phasemap)) return false; ComplexData<1>& pmap=one_echo_phasemap.data(Rank<1>()); ComplexData<1>& adc=rd.data(Rank<1>()); if(pmap.size()!=adc.size()) { ODINLOG(odinlog,errorLog) << "Size mismatch: " << pmap.size() << " != " << adc.size() << STD_endl; return false; } // FFT forward adc.fft(true); // Phase correction Range all=Range::all(); adc(all)=adc(all)/pmap(all); // Blitz throws an error if arrays are used directly // FFT back adc.fft(false); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/blackboard.cpp0000644000175000017500000000731111455553545014007 00000000000000#include "blackboard.h" #include "controller.h" RecoBlackBoard::~RecoBlackBoard() { // Free thread events for(LabelEventMap::iterator lit=eventmap.begin(); lit!=eventmap.end(); ++lit) { for(CoordEventMap::iterator cit=lit->second.begin(); cit!=lit->second.end(); ++cit) { delete cit->second; } } } void RecoBlackBoard::post(const STD_string& label, const RecoData& data) { Log odinlog("RecoBlackBoard","post"); mutex.lock(); CoordDataMap& cdmap=posted[label]; if(cdmap.find(data.coord())!=cdmap.end()) { ODINLOG(odinlog,warningLog) << label << "(" << data.coord().print() << ") posted already, will overwrite it" << STD_endl; } cdmap[data.coord()]=data; // deep copy ODINLOG(odinlog,normalDebug) << "Posted " << label << "(" << data.coord().print() << ")" << STD_endl; // Notify other waiting threads via event STD_list eventlist; LabelEventMap::iterator lit=eventmap.find(label); if(lit!=eventmap.end()) { CoordEventMap& ccm=lit->second; for(CoordEventMap::const_iterator cit=ccm.begin(); cit!=ccm.end(); ++cit) { if(cit->first==data.coord()) eventlist.push_back(cit->second); // Find ALL coords whicht match the data } } mutex.unlock(); if(eventlist.size()) { ODINLOG(odinlog,normalDebug) << "Signaling " << eventlist.size() << " threads waiting for " << label << "(" << data.coord().print() << ")" << STD_endl; for(STD_list::const_iterator it=eventlist.begin(); it!=eventlist.end(); ++it) { (*it)->signal(); } } } bool RecoBlackBoard::get_data(const STD_string& label, RecoData& data) { Log odinlog("RecoBlackBoard","get_data"); LabelDataMap::const_iterator lit=posted.find(label); if(lit==posted.end()) return false; const CoordDataMap& cdmap=lit->second; CoordDataMap::const_iterator cit=cdmap.find(data.coord()); if(cit==cdmap.end()) return false; data=cit->second; // deep copy return true; } bool RecoBlackBoard::inquire(const STD_string& label, RecoData& data, bool blocking) { Log odinlog("RecoBlackBoard","inquire"); ODINLOG(odinlog,normalDebug) << "Requested " << label << "(" << data.coord().print() << ")" << STD_endl; mutex.lock(); if(get_data(label,data)) {mutex.unlock(); return true;} // We're done here if(!blocking) {mutex.unlock(); return false;} // We're done here Event* event=0; CoordEventMap& ccm=eventmap[label]; CoordEventMap::iterator cit=ccm.find(data.coord()); if(cit==ccm.end()) { ODINLOG(odinlog,normalDebug) << "New event for " << label << "(" << data.coord().print() << ")" << STD_endl; event=new Event; ccm[data.coord()]=event; } else { event=cit->second; // Already there } mutex.unlock(); if(event) event->wait(); ODINLOG(odinlog,normalDebug) << "received signal for " << label << "(" << data.coord().print() << ")" << STD_endl; mutex.lock(); bool result=get_data(label,data); // Try again mutex.unlock(); if(!result) { ODINLOG(odinlog,warningLog) << "Data not available after wait: " << label << "(" << data.coord().print() << ")" << STD_endl; } return result; } /////////////////////////////////////////////////////////////////////////////////////////// void RecoPost::init() { postlabel.set_description("Post data on blackboard with this label"); append_arg(postlabel,"postlabel"); } bool RecoPost::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); controller.post_data(postlabel, rd); return execute_next_step(rd,controller); } bool RecoPost::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { context.controller.announce_data(postlabel); } return RecoStep::query(context); } odin-1.8.5/odinreco/epinavcorr.h0000644000175000017500000000476411322062351013530 00000000000000/*************************************************************************** epinavcorr.h - description ------------------- begin : Fr Sep 19 2008 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOEPINAVCORR_H #define RECOEPINAVCORR_H #include "step.h" class RecoEpiNavScan : public RecoStep { public: static void modify4blackboard(RecoCoord& coord) { // index for blackboard coord.set_uniform_mode(RecoIndex::ignore); coord.set_mode(RecoIndex::separate, echo, channel, epi); // the three coordinates relevant to navigators, 'epi' will be used for the echo-train index } private: // implementing virtual functions of RecoStep STD_string label() const {return "epinavscan";} STD_string description() const {return "Calculate and post data for Siemens EPI phase correction";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,echo,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoEpiNavScan;} void init() {} }; ////////////////////////////////////////////////////////////// class RecoEpiNavCorr : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "epinavcorr";} STD_string description() const {return "Apply Siemens EPI phase correction";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoEpiNavCorr;} void init() {} }; #endif odin-1.8.5/odinreco/collector.cpp0000644000175000017500000001125011734622163013677 00000000000000#include "collector.h" #include "controller.h" #include "phasecorr.h" // for phasemapcoll #include "epinavcorr.h" // for epinavcoll #include "collector_code.h" RecoCollectorBase::~RecoCollectorBase() { Log odinlog(label_cache.c_str(),"~RecoCollectorBase"); if(todo.size()) { ODINLOG(odinlog,errorLog) << "TODO list not empty:" << STD_endl; for(CoordCountMap::const_iterator it=todo.begin(); it!=todo.end(); ++it) { ODINLOG(odinlog,errorLog) << "(" << it->first.print(RecoIndex::all) << "): " << it->second << STD_endl; } } } bool RecoCollectorBase::completed(const RecoCoord& coord, unsigned int custom_count) { Log odinlog(c_label(),"completed"); unsigned int numof_todo=count; if(custom_count) numof_todo=custom_count; if(numof_todo<2) return true; // dataset is always complete in this case RecoCoord coord_copy=coord; modify_coord(coord_copy); // just make sure we check against the output side of the functor ODINLOG(odinlog,normalDebug) << "coord_copy=" << coord_copy.print() << STD_endl; MutexLock lock(todomutex); CoordCountMap::iterator it=todo.find(coord_copy); if(it==todo.end()) { // add new entry in todo todo[coord_copy]=(numof_todo-1); } else { it->second--; // reduce todo count by one if(!it->second) { // is count zero ? todo.erase(it); return true; } } return false; } bool RecoCollectorBase::calculate_count(RecoQueryContext& context, const RecoCoord& inmask, const RecoCoord& outmask) { Log odinlog(c_label(),"calculate_count"); label_cache=label(); ODINLOG(odinlog,normalDebug) << "context.coord=" << context.coord.print() << STD_endl; // modify_input_coord(context.coord); const CoordCountMap* inmap=context.controller.create_count_map(inmask); ODINLOG(odinlog,normalDebug) << "inmask=" << inmask.print() << STD_endl; if(!inmap) return false; const CoordCountMap* outmap=context.controller.create_count_map(outmask); ODINLOG(odinlog,normalDebug) << "outmask=" << outmask.print() << STD_endl; if(!outmap) return false; unsigned int incount=inmap->size(); unsigned int outcount=outmap->size(); ODINLOG(odinlog,normalDebug) << "incount/outcount=" << incount << "/" << outcount << STD_endl; if(!incount) { ODINLOG(odinlog,errorLog) << "No input data" << STD_endl; return false; } if(!outcount) { ODINLOG(odinlog,errorLog) << "No output data" << STD_endl; return false; } if(incount%outcount) { ODINLOG(odinlog,errorLog) << "incount(" << incount << ") not a multiple of outcount(" << outcount << ")" << STD_endl; ODINLOG(odinlog,errorLog) << "inmask=" << inmask.print() << STD_endl; ODINLOG(odinlog,errorLog) << "outmask=" << outmask.print() << STD_endl; return false; } count=incount/outcount; // simply take the quotient ODINLOG(odinlog,normalDebug) << "count=" << count << STD_endl; return true; } ////////////////////////////////////////////////////////////////////////////////////////////////////// // Instantiations used in step.cpp template class RecoCollector<1, RecoDim<1, readout>, 2, RecoDim<2, line3d, line> >; template class RecoCollector<2, RecoDim<2, line, readout>, 1, RecoDim<1, line3d> >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, slice>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, channel>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, cycle>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, te>, true >; //template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, epi>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, userdef>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, freq>, true >; template class RecoCollector<4, RecoDim<4, slice, line3d, line, readout>, 1, RecoDim<1, repetition>, true >; template class RecoCollector<1, RecoDim<1, readout>, 1, RecoDim<1, average>, true >; template class RecoCollector<1, RecoDim<1, readout>, 1, RecoDim<1, echo>, true >; template class RecoCollector<1, RecoDim<1, readout>, 1, RecoDim<1, channel>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 2, RecoDim<2, channel, repetition>, true >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 3, RecoDim<3, channel, repetition, slice>, true >; odin-1.8.5/odinreco/step.h0000644000175000017500000001150111322062351012316 00000000000000/*************************************************************************** step.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOSTEP_H #define RECOSTEP_H #include #include #include /** * @addtogroup odinreco * @{ */ class RecoData; // forward declaration class RecoController; // forward declaration /////////////////////////////////////////////////////////////////////////////////// /** * Context when querying reconstruction pipeline. */ struct RecoQueryContext { /** * Mode for querying pipeline. * - prep: Will be set when querying once before starting the pipeline * - finalize: Will be set when querying once after the pipeline was used * - print: print pipeline layout */ enum queryMode {prep=0, finalize, print}; queryMode mode; /** * The reconstruction controller. */ RecoController& controller; /** * Prefix when printing functors. */ STD_string printprefix; /** * Postfix when printing functors. */ STD_string printpostfix; /** * State/index in each dimension during current step of the pipeline. */ RecoCoord coord; RecoQueryContext(queryMode m, RecoController& contr, unsigned short numof[n_recoDims]) : mode(m), controller(contr) { for(int idim=0; idim { public: virtual ~RecoStep() {} /** * Overload this function to perform the reconstruction step. * Input data should be taken from 'rd' and the result stored back into 'rd' * before executing the next step with 'execute_next_step()'. * Read-only access to the current reconstruction controller is possible * via 'controller'. * Return 'true' on sucess, and 'false' if functor fails. */ virtual bool process(RecoData& rd, RecoController& controller) = 0; /** * Overload this function to specify the input dimensions state/index of the functor. */ virtual RecoCoord input_coord() const = 0; /** * Overload this function to specify the modification of the input dimensions state/index after applying the functor. */ virtual void modify_coord(RecoCoord& coord) const = 0; /** * Overload this function to initialize the step for usage in the pieline. * Read-only access to the current reconstruction controller is possible via 'controller'. * The input interface of the step is passed in 'input_coord'. */ virtual bool pipeline_init(const RecoController& controller, const RecoCoord& input_coord) {return true;} /** * Queries the reconstruction pipeline. * Overload this function for particular actions depending on 'context'. * Returns 'true' only if sucessful. */ virtual bool query(RecoQueryContext& context); /** * Sets the functor to be executed after this. */ void set_next_step(RecoStep* step) {next_step=step;} // To be used by factory via duck typing static void create_templates(STD_list& result); static STD_string manual_group() {return "odinreco_steps";} static void interface_description(const RecoStep* step, STD_string& in, STD_string& out); protected: friend class RecoController; /** * Default constructor */ RecoStep() : next_step(0) {} /** * Execute next functor in reconstruction pipeline, * returns 'true' on sucess, and 'false' if functor fails. * Note: Do not lock any mutexes when calling this function. */ bool execute_next_step(RecoData& rd, RecoController& controller); private: void interface_dims(int& in, int& out) const; RecoStep* next_step; }; /////////////////////////////////////////////////////////////////////////////////// typedef StepFactory RecoStepFactory; // The factory for reco steps /** @} */ #endif odin-1.8.5/odinreco/t1fit.h0000644000175000017500000000330311322062351012373 00000000000000/*************************************************************************** t1fit.h - description ------------------- begin : Thu Mar 15 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOT1FIT_H #define RECOT1FIT_H #include "step.h" class RecoT1Fit : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "t1fit";} STD_string description() const {return "Calculate T1 relaxation time using data from Look-Locker sequence";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,userdef,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::separate,userdef);} RecoStep* allocate() const {return new RecoT1Fit;} void init(); JDXstring fittype; JDXfloat masklevel; JDXfloat maxt1; }; #endif odin-1.8.5/odinreco/refgain.h0000644000175000017500000000323211322062351012760 00000000000000/*************************************************************************** refgain.h - description ------------------- begin : Thu Feb 22 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOREFGAIN_H #define RECOREFGAIN_H #include "step.h" class RecoRefGain : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "refgain";} STD_string description() const {return "Calculate reference gain (Bruker)";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,userdef,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single,userdef);} RecoStep* allocate() const {return new RecoRefGain;} void init(); JDXfloat pulsedur; JDXfloat pulsegain; }; #endif odin-1.8.5/odinreco/splitter.cpp0000644000175000017500000000041711322062351013550 00000000000000#include "splitter.h" #include "splitter_code.h" // Instantiations used in step.cpp template class RecoSplitter<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, channel> >; template class RecoSplitter<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition> >;odin-1.8.5/odinreco/circmask.cpp0000644000175000017500000000136511322062351013501 00000000000000#include "circmask.h" #include "data.h" bool RecoCircMask::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); if(shape(1)!=shape(2)) { ODINLOG(odinlog,errorLog) << "non-quadratic image shape=" << shape << STD_endl; return false; } float radius=0.5*float(shape(1)-1); for(int iphase3d=0; iphase3dradius) data(iphase3d,iphase,iread)=STD_complex(0.0); } } } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/step.cpp0000644000175000017500000002146311734622163012673 00000000000000#include "step.h" #include "b1fit.h" #include "blade.h" #include "blackboard.h" #include "channel.h" #include "circmask.h" #include "collector.h" #include "conjphase.h" #include "controller.h" #include "adc.h" #include "dump.h" #include "dti.h" #include "driftcorr.h" #include "epinavcorr.h" #include "expfit.h" #include "fieldmap.h" #include "filter.h" #include "fft.h" #include "fmri.h" #include "grappa.h" #include "grid.h" #include "homodyne.h" #include "messer.h" #include "mip.h" #include "multifreq.h" #include "offset.h" #include "oversampling.h" #include "phasecorr.h" #include "phasecourse.h" #include "pilot.h" #include "qualitycontrol.h" #include "refgain.h" #include "slicetime.h" #include "slidingwindow.h" #include "splitter.h" #include "store.h" #include "sum.h" #include "swi.h" #include "switch.h" #include "t1fit.h" #include "zerofill.h" // Instantiate template classes #include template class Step; template class StepFactory; bool RecoStep::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); ODINLOG(odinlog,normalDebug) << "mode=" << context.mode << STD_endl; if(context.mode==RecoQueryContext::print) { int padlength=STD_max(1,16-int(label().size())); int in, out; interface_dims(in, out); STD_string ifacestr; if(in || out) { if(in==out) ifacestr="(dim: "+itos(in)+")"; else ifacestr="(dim: "+itos(in)+"->"+itos(out)+")"; } ODINLOG(odinlog,infoLog) << STD_string(padlength,' ') << context.printprefix << " " << context.printpostfix << ifacestr << STD_endl; } modify_coord(context.coord); // apply changes to coordinate before querying next step if(next_step) return next_step->query(context); return true; } bool RecoStep::execute_next_step(RecoData& rd, RecoController& controller) { if(next_step) { rd.new_profiler(next_step->label()); modify_coord(rd.coord()); // apply changes to coordinate // delete old data int in, out; interface_dims(in, out); if(in != out) rd.free(in); return next_step->process(rd,controller); } return true; } void RecoStep::create_templates(STD_list& result) { result.push_back(new RecoAdcBaseline()); result.push_back(new RecoAdcGridPrep()); result.push_back(new RecoAdcPad()); result.push_back(new RecoAdcReflect()); result.push_back(new RecoAdcWeight()); result.push_back(new RecoB1Fit()); result.push_back(new RecoBladeComb()); result.push_back(new RecoBladeCorr()); result.push_back(new RecoBladeGrid()); result.push_back(new RecoChannelSum()); result.push_back(new RecoCircMask()); result.push_back(new RecoCollector<1, RecoDim<1, readout>, 2, RecoDim<2, line3d, line> > ("kspace")); result.push_back(new RecoCollector<2, RecoDim<2, line, readout>, 1, RecoDim<1, line3d> > ("line3dcoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, slice>, true > ("slicecoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, channel>, true > ("chancoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, cycle>, true > ("cyclecoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, te>, true > ("tecoll")); // result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, epi>, true > ("epicoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, userdef>, true > ("usercoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition>, true > ("repcoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, freq>, true > ("freqcoll")); result.push_back(new RecoCollector<4, RecoDim<4, slice, line3d, line, readout>, 1, RecoDim<1, repetition>, true > ("image")); result.push_back(new RecoCollector<1, RecoDim<1, readout>, 1, RecoDim<1, average>, true > ("averagecoll")); result.push_back(new RecoCollector<1, RecoDim<1, readout>, 1, RecoDim<1, echo>, true > ("echocoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 2, RecoDim<2, channel, repetition>, true > ("chanrepcoll")); result.push_back(new RecoCollector<3, RecoDim<3, line3d, line, readout>, 3, RecoDim<3, channel, repetition, slice>, true > ("chanrepslicecoll")); result.push_back(new RecoConjPhaseFT()); result.push_back(new RecoCycleRot()); result.push_back(new RecoDeapodize<1>()); result.push_back(new RecoDeapodize<2>()); result.push_back(new RecoDump()); result.push_back(new RecoDTI()); result.push_back(new RecoDriftCalc()); result.push_back(new RecoDriftCorr()); result.push_back(new RecoEpiNavScan()); result.push_back(new RecoEpiNavCorr()); result.push_back(new RecoExpFit()); result.push_back(new RecoFieldMap()); result.push_back(new RecoFilter()); result.push_back(new RecoFFT()); result.push_back(new RecoFMRI()); result.push_back(new RecoFreqComb()); result.push_back(new RecoGrappaWeights()); // result.push_back(new RecoGrappaWeights >()); // Assume only one GRAPPA template for all userdef indices result.push_back(new RecoGrappaWeights >()); result.push_back(new RecoGrappaWeights()); // result.push_back(new RecoGrappaWeights >()); // Assume only one GRAPPA template for all userdef indices result.push_back(new RecoGrappaWeights >()); result.push_back(new RecoGrappa()); result.push_back(new RecoGrappa()); result.push_back(new RecoGrid<1>()); result.push_back(new RecoGrid<2>()); result.push_back(new RecoGridCut()); result.push_back(new RecoHomodyne()); result.push_back(new RecoHomodyne()); result.push_back(new RecoHomodyne()); result.push_back(new RecoStore()); // result.push_back(new RecoInterpolate()); result.push_back(new RecoMesser()); result.push_back(new RecoMip()); result.push_back(new RecoMultiFreq()); result.push_back(new RecoOffset()); result.push_back(new RecoOversampling()); result.push_back(new RecoPhaseMap()); result.push_back(new RecoPhaseCorr()); result.push_back(new RecoPhaseCourse()); result.push_back(new RecoPilot()); result.push_back(new RecoPost()); result.push_back(new RecoQualityControlSpike()); result.push_back(new RecoReal()); result.push_back(new RecoMagn()); result.push_back(new RecoRefGain()); result.push_back(new RecoSliceTime()); result.push_back(new RecoSlidingWindow()); result.push_back(new RecoSplitter<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, channel> > ("chansplit")); result.push_back(new RecoSplitter<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition> > ("repsplit")); result.push_back(new RecoSum<1, RecoDim<1, readout>, 1, RecoDim<1, average> > ("averagesum")); result.push_back(new RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, cycle> > ("cyclesum")); result.push_back(new RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition> > ("repsum")); result.push_back(new RecoSum<3, RecoDim<3, line3d, line, readout>, 1, RecoDim<1, repetition>, true > ("repmagnsum")); result.push_back(new RecoSwi()); result.push_back(new RecoSwitch()); result.push_back(new RecoT1Fit()); result.push_back(new RecoZeroFill()); } STD_string interface_str(const RecoCoord& coord) { STD_list colldims; for(int i=0; i::const_iterator it=colldims.begin(); it!=colldims.end(); ++it) { if(collstr!="") collstr+=","; collstr+=*it; } return itos(ncoll)+"-dimensional, these dimensions are: \\verbatim ("+collstr+") \\endverbatim"; } void RecoStep::interface_description(const RecoStep* step, STD_string& in, STD_string& out) { RecoCoord coord=step->input_coord(); in=interface_str(coord); step->modify_coord(coord); out=interface_str(coord); } void RecoStep::interface_dims(int& in, int& out) const { RecoCoord coord=input_coord(); in=0; for(int i=0; i odinlog("RecoReaderOdin","concat_data"); // Find and sort file names svector fnames=browse_dir(scandir); STD_list sorted_names; for(unsigned int i=0; i0) fileunmap(fd, dataptr, fsize, 0); rmfile(fname.c_str()); } if(file_ptr!=NULL) fclose(file_ptr); return true; } bool RecoReaderOdin::init(const STD_string& input_filename) { Log odinlog("RecoReaderOdin","init"); ODINLOG(odinlog,infoLog) << "Loading recoInfo ..." << STD_endl; if(recoInfo.load(input_filename)<0) return false; const JDXkSpaceCoords& coords=recoInfo.get_kSpaceCoords(); if(!coords.size()) { ODINLOG(odinlog,errorLog) << "JDXkSpaceCoords empty" << STD_endl; return false; } // get weighting factors for different channels nChannels_cache=coords[0].channels; // assume the same for all ADCs channelFactors=recoInfo.get_ChannelScales(); if(channelFactors.extent(firstDim)0) { ODINLOG(odinlog,infoLog) << "Using CoordinateScaling=" << CoordinateScaling.printbody() << STD_endl; if(CoordinateScaling[1]<0.0) { image_proc_cache="-pflip"; } } else { image_proc_cache=recoInfo.get_ImageProc(); } // Get offset, thereby reverse dimension order from (read,phase,slice) to (slice,phase,read) for(int idir=0; idir<3; idir++) { reloffset_cache(2-idir)=recoInfo.get_RelativeOffset()[idir]; } STD_string scandir=JDXfileName(input_filename).get_dirname(); // Concat data and create filename if(fifoFile=="") { if(!concat_data(rawdata_filename, scandir, recoInfo.get_RawFile())) return false; } else { rawdata_filename=fifoFile; } // get format and endianess of raw data dataformat=recoInfo.get_DataFormat(); if(dataformat=="long") dataformat="s32bit"; // for backwards compatability rawtypesize=TypeTraits::typesize(dataformat); if(!rawtypesize) { ODINLOG(odinlog,errorLog) << "Unrecognized dataformat >" << dataformat << "<" << STD_endl; return false; } bool little_endian=recoInfo.is_LittleEndian(); ODINLOG(odinlog,infoLog) << "Raw data is in file " << rawdata_filename << ", dataformat=" << dataformat << ", typesize=" << rawtypesize << ", little endian=" << little_endian << STD_endl; // swap raw data if neccessary if(little_endian!=little_endian_byte_order()) { ODINLOG(odinlog,infoLog) << "Swabbing raw data ..." << STD_endl; STD_string newrawfile(rawdata_filename+"."+SWAB_SUFFIX); STD_string swabcmd("swab "+itos(rawtypesize)+" "+rawdata_filename+" "+newrawfile+" 20"); system(swabcmd.c_str()); rawdata_filename=newrawfile; } // precalculations to remove zero padding from fid nadc=recoInfo.numof_adcs(); zeroesPerChunk=0; ODINLOG(odinlog,infoLog) << "nadc=" << nadc << STD_endl; if(fifoFile=="") { LONGEST_INT nAdcChunks=recoInfo.get_NumOfAdcChunks(); LONGEST_INT rawheadersize=recoInfo.get_RawHeaderSize(); LONGEST_INT fsize_bytes=filesize(rawdata_filename.c_str()); if(fsize_bytes<=rawheadersize) { ODINLOG(odinlog,errorLog) << "File size of " << rawdata_filename << " too small (fsize_bytes=" << fsize_bytes << ", rawheadersize=" << rawheadersize << " )" << STD_endl; return false; } LONGEST_INT rawfilesize=(fsize_bytes-rawheadersize)/(2*rawtypesize); LONGEST_INT sizePaddedChunk=rawfilesize/nAdcChunks; LONGEST_INT samplesTotal=recoInfo.get_TotalNumOfSamples(); if(samplesTotal>rawfilesize) { if(padZero) { LONGEST_INT padbytes=(samplesTotal-rawfilesize)*2*rawtypesize; ODINLOG(odinlog,infoLog) << "Padding raw data with " << padbytes << " bytes" << STD_endl; if(create_empty_file(rawdata_filename, padbytes, appendMode)) { ODINLOG(odinlog,errorLog) << "Cannot zero pad file : " << lasterr() << STD_endl; return false; } rawfilesize=samplesTotal; } else { ODINLOG(odinlog,errorLog) << "Total number of expected sampling points ( " <0) { prot_cache.load(protfile); // Backwards compatability ODINLOG(odinlog,infoLog) << "Loading protocol from " << protfile << STD_endl; } else { prot_cache=recoInfo.get_protocol(); // The new way: Assume protocol is contained in recoInfo ODINLOG(odinlog,infoLog) << "Using protocol from recoInfo" << STD_endl; } size_cache(0)=1; if(prot_cache.geometry.get_Mode()==voxel_3d) size_cache(0)=prot_cache.seqpars.get_MatrixSize(sliceDirection); size_cache(1)=prot_cache.seqpars.get_MatrixSize(phaseDirection); size_cache(2)=prot_cache.seqpars.get_MatrixSize(readDirection); ODINLOG(odinlog,normalDebug) << "size_cache=" << size_cache << STD_endl; // If series number is zero, set series number according to current scandir number STD_string seriesdescr; int seriesno; prot_cache.study.get_Series(seriesdescr,seriesno); if(seriesno<=0) { seriesno=atoi(JDXfileName(scandir).get_basename().c_str()); // Try passed in scandir number first } if(seriesno<=0) { seriesno=atoi(JDXfileName(getpwd()).get_basename().c_str()); // Try PWD next } prot_cache.study.set_Series(seriesdescr,seriesno); ODINLOG(odinlog,infoLog) << "Using seriesno=" << seriesno << " for file conversion" << STD_endl; // get read-out shape arrays (for ramp-sampling EPI) for(int j=0; j(shape)); readoutShape_cache[j].second=dstsize; ODINLOG(odinlog,normalDebug) << "shape/dstsize(" << j << ")=" << readoutShape_cache[j].first.size() << "/" << readoutShape_cache[j].second << STD_endl; } } // get k-space trajectories for(int itraj=0; itraj(ktraj(iseg,ipt,2), ktraj(iseg,ipt,1), ktraj(iseg,ipt,0)); // reverse order of x,y,z kspaceTraj_cache[itraj](iseg,ipt).weight=1.0; } } } } // get weighting vectors for(int iweight=0; iweight(recoInfo.get_AdcWeightVector(iweight))); } index=0; ri_index=0; chancount=0; return true; } template bool RecoReaderOdin::read_block(T2 dummy, ComplexData<2>& block) { Log odinlog("RecoReaderOdin","read_block"); bool result=true; // Delay opening opening raw data file until neccessary for reading of FIFO if(rawdata_fileptr==NULL) { rawdata_fileptr=FOPEN(rawdata_filename.c_str(),modestring(readMode)); if(rawdata_fileptr==NULL) { ODINLOG(odinlog,errorLog) << "fopen(" << rawdata_filename << "): " << lasterr() << STD_endl; return false; } int offset_bytes=recoInfo.get_RawHeaderSize(); if(offset_bytes>0) { // Only if neccessary, to allow reading from a named pipe if(FSEEK(rawdata_fileptr, offset_bytes, SEEK_SET)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; return false; } } } int nitems=2*block.size(); T2* ptr=new T2[nitems]; int toberead=nitems; int currpos=0; while(toberead) { // While loop for FIFO int freadresult=fread(ptr+currpos, sizeof(T2), toberead, rawdata_fileptr); if(!freadresult) { // signals an error, even for a FIFO ODINLOG(odinlog,errorLog) << "fread() failed: " << lasterr() << STD_endl; result=false; break; } currpos+=freadresult; toberead=nitems-currpos; } if(result) convert_from_ptr(block, ptr, block.shape()); delete[] ptr; return result; } bool RecoReaderOdin::fetch(RecoCoord& coord, ComplexData<1>& adc) { Log odinlog("RecoReaderOdin","fetch"); if(index>=get_coords().size()) return false; coord=get_coords()[index]; // Load next block of raw data if(!chancount) { kcoord_cache=recoInfo.get_kSpaceCoord(ri_index); rawdata.resize(kcoord_cache.channels,kcoord_cache.adcSize); bool readresult=false; if(dataformat==TypeTraits::type2label((s16bit)0)) readresult=read_block((s16bit)0, rawdata); if(dataformat==TypeTraits::type2label((s32bit)0)) readresult=read_block((s32bit)0, rawdata); if(dataformat==TypeTraits::type2label((float)0)) readresult=read_block((float)0, rawdata); if(!readresult) { ODINLOG(odinlog,errorLog) << "Failed to read coord[" << ri_index << "]" << STD_endl; return false; } // skip padding at end of chunk if(kcoord_cache.flags&recoLastInChunkBit) { int skip_bytes=zeroesPerChunk*kcoord_cache.channels*rawtypesize*2; if(skip_bytes>0) { // Only if neccessary, to allow reading from a named pipe if(FSEEK(rawdata_fileptr, skip_bytes, SEEK_CUR)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; return false; } } } // reorder data in case of conctatenated acquisitions if(kcoord_cache.concat>1) { if(kcoord_cache.adcSize%kcoord_cache.concat) { ODINLOG(odinlog,errorLog) << "adcSize(" << kcoord_cache.adcSize << ") not a multiple of concat(" << kcoord_cache.concat << ")" << STD_endl; return false; } int onesize=kcoord_cache.adcSize/kcoord_cache.concat; TinyVector shape_concat(kcoord_cache.concat, kcoord_cache.channels, onesize); ODINLOG(odinlog,normalDebug) << "shape_concat=" << shape_concat << STD_endl; ComplexData<3> data_concat(Array(rawdata.c_array(), shape_concat, neverDeleteData).copy()); Range all=Range::all(); for(int icat=0; icat=0) coord.readoutShape=&(readoutShape_cache[kcoord.readoutIndex]); if(kcoord.trajIndex>=0) coord.kspaceTraj=&(kspaceTraj_cache[kcoord.trajIndex]); if(kcoord.weightIndex>=0) coord.weightVec=&(weightVec_cache[kcoord.weightIndex]); coord.dwellTime=recoInfo.get_DwellTime(kcoord.dtIndex); coord.overSamplingFactor=kcoord.oversampling; coord.relCenterPos=kcoord.relcenter; coord.echopos=coord.index[echo]; // Move echo index to echopos to avoid it to interfere with other indices coord.echotrain=coord.index[epi]; // Move EPI index to echotrain to avoid it to interfere with other indices if(coord.index[templtype]==phasecorr_template) { // PE indices can and should be ignored coord.index[line]=0; coord.index[line3d]=0; } else { coord.index[echo]=0; // ignore, echopos will be used instead coord.index[epi]=0; // ignore, echotrain will be used instead } } const STD_vector& RecoReaderOdin::get_coords() const { Log odinlog("RecoReaderOdin","get_coords"); if(!coord_vec_cache.size()) { coord_vec_cache.resize(nadc*nChannels_cache); STD_map repcounter_cache; // to adjust repetition index RecoCoord coord; unsigned int index=0; for(unsigned int iadc=0; iadc odinlog(c_label(),"init"); extension.set_description("Extra file name extension"); append_arg(extension,"extension"); // make this come 1st so it can be easily used when creating recipe prefix=STD_string(".")+SEPARATOR_STR+"image"; prefix.set_cmdline_option("o").set_description("Prefix of output files"); append_arg(prefix,"prefix"); formats=default_format(); formats.set_cmdline_option("f").set_description("Space sepapared list of output formats (file extensions), possible formats are '"+FileIO::autoformats().printbody()+"'"); append_arg(formats,"formats"); imageproc="none"; imageproc.set_cmdline_option("ip").set_description("Command line args for extra processing of final images"); append_arg(imageproc,"imageproc"); storephase=false; storephase.set_cmdline_option("sp").set_description("Store phase in addition to magnitude"); append_arg(storephase,"storephase"); // Add useful options of FileWriteOpts append_arg(wopts.dialect,"wopts.dialect"); append_arg(wopts.wprot,"wopts.wprot"); append_arg(wopts.datatype,"wopts.datatype"); ODINLOG(odinlog,normalDebug) << "storephase=" << bool(storephase) << STD_endl; } bool RecoStore::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<5>& indata=rd.data(Rank<5>()); TinyVector inshape=indata.shape(); int nrep=inshape(0); int nslice=inshape(1); int nphase3d=inshape(2); int nphase=inshape(3); int nread=inshape(4); if(nslice>1 && nphase3d>1) { ODINLOG(odinlog,errorLog) << "Implement me: multi-slice 3D data" << STD_endl; return false; } Data fdata(inshape); if(rd.mode==RecoData::real_data || rd.mode==RecoData::weighted_real_data) fdata=creal(indata); else fdata=cabs(indata); ODINLOG(odinlog,normalDebug) << "storephase=" << bool(storephase) << STD_endl; Data pdata; if(storephase) { pdata.resize(inshape); pdata=phase(indata); } TinyVector storeshape(nrep, nslice*nphase3d, nphase, nread); // collapse slices and phase3d to one dimension Data storefdata(storeshape); Data storepdata; if(storephase) storepdata.resize(storeshape); if(nslice>1) { storefdata(all,all,all,all)=fdata(all,all,0,all,all); if(storephase) storepdata(all,all,all,all)=pdata(all,all,0,all,all); } else { storefdata(all,all,all,all)=fdata(all,0,all,all,all); if(storephase) storepdata(all,all,all,all)=pdata(all,0,all,all,all); } // create protocol Protocol prot(controller.protocol()); if(rd.override_protocol) prot=(*(rd.override_protocol)); // make sure protocol dimension are set correctly prot.seqpars.set_NumOfRepetitions(inshape(0)); prot.seqpars.set_MatrixSize(phaseDirection, inshape(3)); prot.seqpars.set_MatrixSize(readDirection, inshape(4)); // Store float data whenever possible prot.system.set_data_type(TypeTraits::type2label(float(0))); Protocol protphase(prot); // Add fileid to series description to distinguish separate protocols STD_string idstr=rd.coord().print(RecoIndex::filename); STD_string seriesdescr; int seriesno; prot.study.get_Series(seriesdescr,seriesno); if(idstr!="") seriesdescr=idstr+"_"+seriesdescr; // make idstr become first for better lexicographical comparison of filenames prot.study.set_Series(seriesdescr,seriesno); protphase.study.set_Series(seriesdescr+"_phase",seriesno); mutex.lock(); pdmap[prot].reference(storefdata); if(storephase) pdmap[protphase].reference(storepdata); mutex.unlock(); return execute_next_step(rd,controller); } bool RecoStore::store_images(const RecoController& controller) { Log odinlog(c_label(),"store_images"); svector format=tokens(formats); ODINLOG(odinlog,normalDebug) << "formats/format=" << formats << "/" << format.printbody() << STD_endl; if(!filterchain.apply(pdmap)) return false; // Store all data in one file/directory, if possible for(unsigned int i=0; i odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { STD_string procstr; if(imageproc!="none") procstr=imageproc; else procstr=context.controller.image_proc(); ODINLOG(odinlog,normalDebug) << "procstr=" << procstr << STD_endl; if(!filterchain.init(procstr)) return false; } ODINLOG(odinlog,normalDebug) << "storephase=" << bool(storephase) << STD_endl; if(context.mode==RecoQueryContext::finalize) { if(!store_images(context.controller)) return false; } return RecoStep::query(context); } //////////////////////////////////////////////////////////////////////////// bool RecoReal::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); rd.mode=RecoData::real_data; return execute_next_step(rd,controller); } //////////////////////////////////////////////////////////////////////////// bool RecoMagn::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<3>& indata=rd.data(Rank<3>()); indata = float2real(cabs(indata)); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/odinreco.cpp0000644000175000017500000000017611322062351013506 00000000000000#include "odinreco.h" #include const char* Reco::get_compName() {return "Reco";} LOGGROUNDWORK(Reco) odin-1.8.5/odinreco/collector_code.h0000644000175000017500000000623111322062351014327 00000000000000#include "collector.h" template bool RecoCollector::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); TinyVector index; Coll::create_index(rd.coord(), index); TinyVector shape; Coll::create_shape(rd.coord(), shape); // create shape of collected data TinyVector collshape; for(int i=0; i()).extent(i); ODINLOG(odinlog,normalDebug) << "index/shape/collshape=" << index << "/" << shape << "/" << collshape << STD_endl; if(!product(collshape)) { ODINLOG(odinlog,errorLog) << "Zero-size shape " << collshape << STD_endl; return false; } // adjust coordinate to output dims for correct indexing of todo map modify_coord(rd.coord()); // create new view of input data ComplexData indata; rd.data(Rank()).convert_to(indata); // bring to same rank // create domains for copying input data to the correct position TinyVector lowin=0; TinyVector uppin=0; TinyVector lowdst=0; TinyVector uppdst=0; for(int i=0; i()).extent(i)-1; ODINLOG(odinlog,normalDebug) << "lowin/uppin=" << lowin << "/" << uppin << STD_endl; ODINLOG(odinlog,normalDebug) << "lowdst/uppdst=" << lowdst << "/" << uppdst << STD_endl; RectDomain indomain(lowin,uppin); RectDomain dstdomain(lowdst,uppdst); // fill data mutex.lock(); ComplexData& dataref=datamap[rd.coord()]; if(dataref.shape()!=collshape) { dataref.resize(collshape); dataref=STD_complex(0.0); // Initialize to zero for partial k-space acquisition } dataref(dstdomain)=dataref(dstdomain)+indata(indomain); mutex.unlock(); unsigned int numof_count=0; if(use_numof) numof_count=product(shape); if( completed(rd.coord(),numof_count) ) { ODINLOG(odinlog,normalDebug) << " data " << collshape << " complete" << STD_endl; // fill rd with collected data mutex.lock(); typename DataMap::iterator it=datamap.find(rd.coord()); // typename is necessary here for GCC4 rd.data(Rank()).free(); // deallocate input data rd.data(Rank()).reference(it->second); datamap.erase(it); // delete entry from map to save memory and to trigger initialization if data is needed again mutex.unlock(); if(!execute_next_step(rd,controller)) return false; } return true; } template bool RecoCollector::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(!use_numof) { RecoCoord outmask=context.coord; modify_coord(outmask); if(!calculate_count(context, context.coord, outmask)) return false; } } return RecoStep::query(context); } odin-1.8.5/odinreco/controller.cpp0000644000175000017500000010232411734622163014077 00000000000000#include "controller.h" #include "data.h" #include "step.h" #include "reader.h" #include "measindex.h" #include "fieldmap.h" // for posted_fmap_str #include "driftcorr.h" // for posted_drift_str RecoController::RecoController(JcampDxBlock& parblock) : input(0), pipeline(0), factory(0), pmeter(display) { jobs=numof_cores(); jobs.set_cmdline_option("j").set_description("Number of concurrent jobs(threads) in reco"); parblock.append(jobs); recipe.set_cmdline_option("rp").set_description("Reco recipe (pipeline layout)"); parblock.append(recipe); recipeFile.set_cmdline_option("rf").set_description("Read reco recipe (pipeline layout) from this file"); parblock.append(recipeFile); select.set_cmdline_option("s").set_description("Select certain dimensions ranges (space separated list of 'dim=selection', e.g. slice=3)"); parblock.append(select); timeout=0; timeout.set_cmdline_option("to").set_description("Timeout for reco in seconds, 0=inifinite"); parblock.append(timeout); maxrecursion=100; maxrecursion.set_cmdline_option("mr").set_description("Maximum recursion of reconstruction when waiting for blackboard data, zero means no recursion"); parblock.append(maxrecursion); conjPhaseFT=false; conjPhaseFT.set_cmdline_option("cp").set_description("Use direct Fourier transform with conjugate-phase correction instead of gridding"); parblock.append(conjPhaseFT); slidingWindow=false; slidingWindow.set_cmdline_option("sw").set_description("Sliding window reconstruction, e.g. for Spiral/PROPELLER"); parblock.append(slidingWindow); keyhole=false; keyhole.set_cmdline_option("kh").set_description("Keyhole reconstruction, e.g. for PROPELLER"); parblock.append(keyhole); sepChannels=false; sepChannels.set_cmdline_option("sc").set_description("Store images from channels separately instead of combining them"); parblock.append(sepChannels); dumpKspace=false; dumpKspace.set_cmdline_option("ks").set_description("Store k-space data"); parblock.append(dumpKspace); disableHomodyne=false; disableHomodyne.set_cmdline_option("dh").set_description("Disable homodyne reconstruction"); parblock.append(disableHomodyne); disableMultiFreq=false; disableMultiFreq.set_cmdline_option("dm").set_description("Disable fieldmap-based multi-frequency reconstruction"); parblock.append(disableMultiFreq); disableSliceTime=false; disableSliceTime.set_cmdline_option("ds").set_description("Disable slice-time correction"); parblock.append(disableSliceTime); disableGrappa=false; disableGrappa.set_cmdline_option("dg").set_description("Disable GRAPPA interpolation"); parblock.append(disableGrappa); phaseCourse=false; phaseCourse.set_cmdline_option("pt").set_description("Combine and store phase timecourse from all channels"); parblock.append(phaseCourse); qcspike=false; qcspike.set_cmdline_option("qs").set_description("Quality control: Check for spikes in data"); parblock.append(qcspike); preproc3d="null"; preproc3d.set_cmdline_option("prp").set_description("Recipe for post processing of 3D volume before channel combining"); parblock.append(preproc3d); postproc3d="null"; postproc3d.set_cmdline_option("pop").set_description("Recipe for post processing of 3D volume after channel combining"); parblock.append(postproc3d); dumpRawPrefix=""; dumpRawPrefix.set_cmdline_option("rd").set_description("Dump signal data and its protocol to files with this prefix, do not reconstruct images"); parblock.append(dumpRawPrefix); fieldmapFile=""; fieldmapFile.set_cmdline_option("fm").set_description("Load fieldmap data from this file"); parblock.append(fieldmapFile); driftcalcFile=""; driftcalcFile.set_cmdline_option("dcw").set_description("Calculate and store field drift to file with this prefix"); parblock.append(driftcalcFile); driftcorrFile=""; driftcorrFile.set_cmdline_option("dcr").set_description("Load field drift from this file"); parblock.append(driftcorrFile); factory=new RecoStepFactory(&parblock); } RecoController::~RecoController() { delete_countmap_cache(); delete factory; } TinyVector RecoController::reloffset() const { TinyVector result; result=0.0; MutexLock lock(inputmutex); if(input) result=input->reloffset(); return result; } dvector RecoController::dim_values(recoDim dim) const { dvector result; MutexLock lock(inputmutex); if(input) result=input->dim_values(dim); return result; } STD_string RecoController::image_proc() const { STD_string result; MutexLock lock(inputmutex); if(input) result=input->image_proc(); return result; } TinyVector RecoController::image_size() const { TinyVector result; result=0; MutexLock lock(inputmutex); if(input) result=input->image_size(); return result; } TinyVector RecoController::kspace_extent() const { TinyVector result; result=0; TinyVector imgshape=image_size(); for(int i=0; i odinlog("RecoController","inquire_data"); if(!status) return false; // Return immediately if an error occured, i.e. do not wait for any data in this case ODINLOG(odinlog,normalDebug) << "Requested " << label << "(" << data.coord().print() << ")" << STD_endl; if(blackboard.inquire(label,data)) return true; // 1st shot without feeding pipeline or signalling waiting state ODINLOG(odinlog,normalDebug) << label << "(" << data.coord().print() << ") not ready" << STD_endl; int depth=thread_depth[Thread::self()]; if(depthfirst)+": "+it->second+"\n"; } return false; } // ODINLOG(odinlog,normalDebug) << "sleeping while waiting for " << label << STD_endl; // sleep_ms(10); // Avoid tight inifinite loop, give other threads CPU time to process their input } ODINLOG(odinlog,normalDebug) << "blocked inquire successful" << STD_endl; decr_waiting_threads(); return true; } void RecoController::delete_countmap_cache() { for(STD_map::const_iterator it=countmap_cache.begin(); it!=countmap_cache.end(); ++it) { delete it->second; } countmap_cache.clear(); } const CoordCountMap* RecoController::create_count_map(const RecoCoord& mask) const { Log odinlog("RecoController","create_count_map"); if(!input) { ODINLOG(odinlog,errorLog) << "Input reader not initialized yet" << STD_endl; return 0; } STD_string maskstring=mask.print(RecoIndex::all); // Using full printout as unique key for masks STD_map::const_iterator it=countmap_cache.find(maskstring); if(it!=countmap_cache.end()) { ODINLOG(odinlog,normalDebug) << "Using cached countmap for " << mask.print() << STD_endl; return it->second; } const STD_vector& coords=input->get_coords(); ODINLOG(odinlog,normalDebug) << "sizeof(RecoCoord)/coords.size()=" << sizeof(RecoCoord) << "/" << coords.size() << STD_endl; CoordCountMap* countmap=new CoordCountMap; ODINLOG(odinlog,normalDebug) << "coords.size()=" << coords.size() << STD_endl; for(unsigned int iadc=0; iadcbegin(); it!=countmap->end(); ++it) { const RecoCoord& coord=it->first; ODINLOG(odinlog,normalDebug) << "coord(" << it->second << ")=" << coord.print() << STD_endl; for(unsigned int idim=0; idim1.0) has_oversampling_cache=true; if(coord.relCenterPos!=0.5) has_relcenter_cache=true; } } for(int idim=0; idim1) printed+="#"+STD_string(recoDimLabel[idim])+"="+itos(numof[idim])+" "; } ODINLOG(odinlog,normalDebug) << "numof: " << printed << STD_endl; return true; } static bool in_tracefunction=false; // to avoid recursion void RecoController::tracefunction(const LogMessage& msg) { if(in_tracefunction) return; in_tracefunction=true; int selfid=Thread::self(); if(selfid!=controlthread) STD_cerr << "job" << selfid << "-"; // Do not prefix messages of control thread STD_cerr << msg.str(); in_tracefunction=false; } RecoStep* RecoController::create_pipeline(const STD_string& rec, const RecoCoord* initial_coord, int argc, char* argv[]) const { Log odinlog("RecoController","create_pipeline"); RecoStep* result=0; svector toks(tokens(rec,'|','(',')')); RecoCoord coord; // coordinate interfaces during pipeline if(initial_coord) coord=(*initial_coord); RecoStep* laststep=0; for(unsigned int itok=0; itok" << toks[itok] << "/" << functorstr << "/" << args << "<" << STD_endl; RecoStep* step=factory->create(functorstr); if(!step) { ODINLOG(odinlog,errorLog) << "Could not create functor with label >" << functorstr << "<" << STD_endl; return 0; // Return immediately if functor could not be created } if(args!="") step->set_args(args); if(!step->pipeline_init(*this,coord)) { ODINLOG(odinlog,errorLog) << "Could not initialize pipeline of functor >" << functorstr << "< with arguments >" << args << "<" << STD_endl; return 0; } // check interface between steps RecoCoord coordin=step->input_coord(); if(!coord.compatible(coordin)) { STD_string lastlabel; if(laststep) lastlabel=laststep->label(); ODINLOG(odinlog,errorLog) << "Interface mismatch: output(" << lastlabel << ")=" << coord.print(RecoIndex::all) << " does not match input(" << step->label() << ")=" << coordin.print(RecoIndex::all) << STD_endl; return 0; } step->modify_coord(coord); // update interface if(!itok) result=step; if(laststep) { laststep->set_next_step(step); } laststep=step; } return result; } STD_string RecoController::stepmanual() const { return factory->manual(); } ////////////////////////////////////////////////////////////////////////////////////// class TimeOutThread : public Thread { public: TimeOutThread(unsigned int seconds) : secs(seconds) {} bool init(unsigned int seconds) { return true; } private: void run() { Log odinlog("TimeOutThread","run"); sleep_ms(1000*secs); ODINLOG(odinlog,warningLog) << "Reco timed out after " << secs << " seconds, exiting" << STD_endl; exit(1); } unsigned int secs; }; ////////////////////////////////////////////////////////////////////////////////////// template bool RecoController::get_kspace_sampling_pattern(const RecoCoord& mask, unsigned int& reduction_factor, bool& partial_fourier) const { Log odinlog("RecoController","get_kspace_sampling_pattern"); reduction_factor=1; partial_fourier=false; if(numof_cache[Dim]<2) return true; RecoMeasIndex > measlines; // exclude unimportant dimensions for effiency measlines.init(mask, *this); for(unsigned int iorth=0; iorth=int(reduction_factor)) partial_fourier=true; } return true; } ////////////////////////////////////////////////////////////////////////////////////// bool RecoController::autorecipe(const RecoCoord& mask, STD_string& result) const { Log odinlog("RecoController","autorecipe"); result=""; ODINLOG(odinlog,infoLog) << "Creating default recipe ..." << STD_endl; unsigned int reduction_factor=0; bool partial_fourier=false; if(!get_kspace_sampling_pattern(mask,reduction_factor, partial_fourier)) return false; ODINLOG(odinlog,normalDebug) << "reduction_factor/partial_fourier=" << reduction_factor << "/" << partial_fourier << STD_endl; unsigned int reduction_factor3d=0; bool partial_fourier3d=false; if(!get_kspace_sampling_pattern(mask,reduction_factor3d, partial_fourier3d)) return false; ODINLOG(odinlog,normalDebug) << "reduction_factor3d/partial_fourier3d=" << reduction_factor3d << "/" << partial_fourier3d << STD_endl; unsigned int max_reduction_factor=STD_max(reduction_factor,reduction_factor3d); unsigned int reduction_factor_prot=protocol().seqpars.get_ReductionFactor(); if(max_reduction_factor!=reduction_factor_prot) { ODINLOG(odinlog,warningLog) << "Mismatch: max_reduction_factor(" << max_reduction_factor << ")=!reduction_factor_prot(" << reduction_factor_prot << ")" << STD_endl; } bool max_partial_fourier=partial_fourier || partial_fourier3d; bool partial_fourier_prot=(protocol().seqpars.get_PartialFourier()>0.0); if(max_partial_fourier!=partial_fourier_prot) { ODINLOG(odinlog,warningLog) << "Mismatch: max_partial_fourier(" << max_partial_fourier << ")=!partial_fourier_prot(" << partial_fourier_prot << ")" << STD_endl; } STD_string driftcorrstr; if(driftcorrFile!="") driftcorrstr="driftcorr | "; STD_string averagestr; if(numof_cache[average]>1) averagestr="averagecoll | averagesum | "; bool has_blade=(numof_cache[cycle]>1 && !has_traj); // Assume PROPELLER STD_string adcprep; if(!has_traj && has_relcenter_cache) adcprep+="adc_pad | "; STD_string adcdeapodize; STD_string adcdeapodize_blade; if(has_readoutshape) { STD_string gridarg; if(has_blade) gridarg="(false)"; // no deapo shift adcprep+="adc_gridprep | grid1d"+gridarg+" | "; // regrid first to correct for antisymmetric gradient distortions before reflecting / adc_regrid does not work well for blades yet if(!dumpKspace) { if(has_blade) adcdeapodize_blade="deapodize1d | "; else adcdeapodize ="deapodize1d | "; } } if(has_flag_cache&recoReflectBit) adcprep+="adc_reflect | "; STD_string chanstr; if(numof_cache[channel]>1 && !sepChannels && !dumpKspace) chanstr="chancoll | chansum | "; STD_string corrstr; STD_string navstr; STD_string phasecorrstr; if(has_templcorr_cache[phasecorr_template]) { phasecorrstr="phasecorr | "; corrstr+="templtype=P { "+averagestr+adcprep+"echocoll | phasemap}"; } STD_string oversamplingstr; if(has_oversampling_cache && !dumpKspace) oversamplingstr="oversampling | "; STD_string mfreqbegin; STD_string mfreqend; STD_string chansumopt; bool ext_fieldmap=fieldmapFile!=""; if(!disableMultiFreq && (has_templcorr_cache[fieldmap_template] || ext_fieldmap) ) { if(!conjPhaseFT && !dumpKspace) { mfreqbegin="multifreq | "; mfreqend="freqcoll | freqcomb | "; } if(!ext_fieldmap) { if(corrstr!="") corrstr+="; "; STD_string fmap_offsetstr="offset | "; if(has_blade && mfreqend!="") fmap_offsetstr=""; // disable offset for multi-frequency reco of blades //STD_string cyclerotstr; //if(has_blade) cyclerotstr="cyclerot | "; //corrstr+="templtype=F { adc_reflect | kspace | offset | filter(Hann) | fft | tecoll | fieldmap | "+chanstr+"interpolate | "+cyclerotstr+"post(fieldmap) | "+oversamplingstr+"slicecoll | image | store(fieldmap)}"; corrstr+="templtype=F { adc_reflect | kspace |"+fmap_offsetstr+"filter(Hann) | fft | tecoll | fieldmap | "+chanstr+oversamplingstr+" post(fieldmap) | "+"slicecoll | image | store(fieldmap)}"; } } if(has_navigator_cache[epi_navigator]) { phasecorrstr="epinavcorr | "; if(navstr!="") navstr+="; "; navstr+="navigator=e { "+adcprep+"echocoll | epinavscan }"; } STD_string interpolstr; if(!disableGrappa) { bool has_grappa_template=has_templcorr_cache[grappa_template]; if(has_grappa_template || reduction_factor>1 || reduction_factor3d>1) { STD_string redfactstr=itos(reduction_factor); STD_string redfactstr3d=itos(reduction_factor3d); if(has_grappa_template) { if(corrstr!="") corrstr+="; "; corrstr+="templtype=G {"+averagestr+adcprep+phasecorrstr+"kspace | chancoll | "; if(reduction_factor>1) corrstr+="grappaweightstempl(" +redfactstr+ ")"; if(reduction_factor3d>1) corrstr+="grappaweightstempl3d("+redfactstr3d+")"; corrstr+="}"; } STD_string weightsstr; if(!has_grappa_template) { if(reduction_factor>1) weightsstr+="grappaweights("+ redfactstr+ ") | "; if(reduction_factor3d>1) weightsstr+="grappaweights3d("+redfactstr3d+") | "; } interpolstr+="chancoll | "+weightsstr; STD_string keephshapestr; if(has_blade) keephshapestr=",true"; // do not expand k-space to image matrix size if(reduction_factor>1) interpolstr+="grappa(" +redfactstr+keephshapestr+ ") | "; if(reduction_factor3d>1) interpolstr+="grappa3d("+redfactstr3d+keephshapestr+") | "; interpolstr+="chansplit | "; } } STD_string fftstr="fft | "; if(!has_traj && !disableHomodyne) { unsigned int homodyne_dims=0; if(has_relcenter_cache) {fftstr="homodyneread | "; homodyne_dims++;} if (partial_fourier && !has_blade) {fftstr="homodyne | "; homodyne_dims++;} if(partial_fourier3d) {fftstr="homodyne3d | "; homodyne_dims++;} if(homodyne_dims>1) { ODINLOG(odinlog,errorLog) << "Not yet implemented: partial Fourier reconstruction in more than one direction" << STD_endl; return false; } } STD_string offsetstr="offset | "; if(dumpKspace) { fftstr=""; offsetstr=""; } STD_string swstr; if(slidingWindow || (keyhole && has_blade) ) swstr="slidingwindow | "; STD_string spikestr=""; if(qcspike) spikestr="qcspike | "; // insert after k-space has been collected but before interpolation STD_string kspacestr=adcprep + phasecorrstr + "kspace | " + spikestr + interpolstr; STD_string adcbaselinestr; STD_string deapodizestr; STD_string gridstr; if(has_traj) { adcbaselinestr="adc_baseline | "; if(conjPhaseFT) { kspacestr="adc_weight | conjphase | " + spikestr + swstr + "cyclecoll | cyclesum | "; offsetstr=""; fftstr=""; } else { kspacestr="grid2d | line3dcoll | " + spikestr + swstr + "cyclecoll | cyclesum | "; if(!dumpKspace) deapodizestr="deapodize2d | "; gridstr="gridcut | "; } oversamplingstr=""; } STD_string bladestr; if(has_blade) { STD_string keyholeopt; if(keyhole) keyholeopt="(true)"; // partial fourier reconstruction has to be applied before combining the blades! STD_string bladefftstr = ""; if (mfreqend!="") bladefftstr = "fft | "; if (!disableHomodyne && partial_fourier) { if (mfreqend!="") bladefftstr = "homodyne | "; else bladefftstr = "homodyne | fft(false) | "; } STD_string bladecorrstr="bladecorr | "; if(mfreqend!="") bladecorrstr=mfreqend+"magn | "+adcdeapodize_blade+"fft(false) | "; mfreqend=""; // do not use in rest of pipeline bladestr=bladefftstr+bladecorrstr+swstr+"cyclecoll | bladecomb"+keyholeopt+" | grid2d | line3dcoll | "; if(!dumpKspace) deapodizestr="deapodize2d | "; gridstr="gridcut | "; } STD_string maskstr; if(has_traj || has_blade) maskstr="circmask | "; STD_string slicetimestr; if(!disableSliceTime && numof_cache[repetition]>1 && numof_cache[slice]>1 && !dumpKspace) { slicetimestr="slicetime | "; } STD_string pp3dpre; STD_string pp3dpost; if(!dumpKspace) { if(preproc3d!="null") pp3dpre=preproc3d; else pp3dpre=shrink(input->preProc3D()); if(postproc3d!="null") pp3dpost=postproc3d; else pp3dpost=shrink(input->postProc3D()); if(pp3dpre.size() && (pp3dpre[pp3dpre.size()-1]!='|') ) pp3dpre+="|"; if(pp3dpost.size() && (pp3dpost[pp3dpost.size()-1]!='|') ) pp3dpost+="|"; } STD_string freqcomb_and_oversampling=mfreqend+oversamplingstr; if(ext_fieldmap) freqcomb_and_oversampling=oversamplingstr+mfreqend; // remove oversampling 1st before combining with external fieldmap STD_string phasecoursestr; if(phaseCourse) { phasecoursestr="switch( { chanrepcoll | phasecourse | repsplit | "+ freqcomb_and_oversampling + "slicecoll | image | " + slicetimestr + "store(phasecourse) } ) | "; } STD_string kspaceprep="zerofill | filter | "; if(dumpKspace) kspaceprep=""; if(numof_cache[dti]>1) pp3dpost+="dti | "; result = driftcorrstr + averagestr + adcbaselinestr + mfreqbegin + kspacestr + bladestr + offsetstr + kspaceprep + fftstr + adcdeapodize + deapodizestr + gridstr + phasecoursestr + pp3dpre + chanstr + freqcomb_and_oversampling + pp3dpost + maskstr + "slicecoll | image | " + slicetimestr + "store"; if(driftcalcFile!="") { result= averagestr + adcbaselinestr + kspacestr + bladestr + offsetstr + kspaceprep + fftstr + adcdeapodize + deapodizestr + gridstr + oversamplingstr + " chanrepslicecoll | driftcalc | dump("+driftcalcFile+",asc)"; } if(disableGrappa || corrstr!="") { result="switch(templtype=N { "+result+"} ; "+corrstr+")"; } if(navstr!="") { result="switch(navigator=n { "+result+"} ; "+navstr+")"; } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return true; } ////////////////////////////////////////////////////////////////////////////////////// bool RecoController::init(RecoReaderInterface* reader, JcampDxBlock& opts, int argc, char* argv[]) { Log odinlog("RecoController","init"); input=reader; if(!input) { ODINLOG(odinlog,errorLog) << "no reader provided" << STD_endl; return false; } // Initialize default protocol by reader, do this as afirst step prot_cache=input->protocol(); bool modify_args=false; // Do not modify command-line args since the same option may be used in different template instantiations // Parse recoInfo args svector riargs(tokens(input->cmdline_opts(),' ','\"','\"')); int riargc=riargs.size()+1; // 1st string is neglected ODINLOG(odinlog,normalDebug) << "riargc=" << riargc << STD_endl; char* riargv[riargc+1]; for(int i=0; i<(riargc+1); i++) riargv[i]=0; for(unsigned int i=0; i0) { (new TimeOutThread(timeout))->start(); } #endif // Parse selected dimensions RecoCoord initcoord; STD_map selmap; svector seltoks(tokens(select)); for(unsigned int isel=0; isel reloffset() const; /** * Extra command-line arguments for processing of final images. */ STD_string image_proc() const; /** * Returns the image size, will be used if it cannot be determined from the k-space * coordinates (i.e. when gridding). */ TinyVector image_size() const; /** * Returns the extent of the k-space in each direction (in rad/mm) */ TinyVector kspace_extent() const; /** * Returns the scan protocol. */ const Protocol& protocol() const {return prot_cache;} /** * Announces to blackboard that data with identifier 'label' will become available during pipeline execution. */ void announce_data(const STD_string& label) {blackboard.announce(label);} /** * Posts 'data' with identifier 'label' on blackboard, it will be indexed according to the k-space coordinate in 'data'. */ void post_data(const STD_string& label, const RecoData& data) {blackboard.post(label,data);} /** * Returns whether data with 'label' will become available during pipeline execution. */ bool data_announced(const STD_string& label) {return blackboard.announced(label);} /** * Returns 'data' with identifier 'label' for k-space coordinate set in 'data' from blackboard. * Waits until data becomes available. Returns 'true' if data is available, otherwise returns 'false' if all data was processed * and the requested data was not available. */ bool inquire_data(const STD_string& label, RecoData& data); /** * Returns a map where the key are k-space coordinates * (except those not in 'mask') and the value of the map is a count * of ADC indices with this particular k-space coordinate. */ const CoordCountMap* create_count_map(const RecoCoord& mask) const; /** * Creates the maximum extent of reco dimension in 'numof' * using all coordinates except those not in 'mask'. * In addition, returns a printed version of the result in 'printed'. */ bool create_numof(const RecoCoord& mask, unsigned short numof[n_recoDims], STD_string& printed) const; /** * Creates a pipeline and returns its 1st functor according to the recipe (pieline layout) given in 'rec'. * Checking of input/output dimension match starts with 'initial_coord', if non-zero. * Returns zero if the pipeline could not be created because of input/output dimension mismatches. */ RecoStep* create_pipeline(const STD_string& rec, const RecoCoord* initial_coord=0, int argc=0, char* argv[]=0) const; /** * Returns documention 'code' of steps for doxygen. */ STD_string stepmanual() const; private: friend class RecoThread; // Options JDXint jobs; JDXstring recipe; JDXstring recipeFile; JDXstring select; JDXint timeout; JDXint maxrecursion; JDXbool conjPhaseFT; JDXbool slidingWindow; JDXbool keyhole; JDXbool sepChannels; JDXbool dumpKspace; JDXbool disableHomodyne; JDXbool disableMultiFreq; JDXbool disableSliceTime; JDXbool disableGrappa; JDXbool phaseCourse; JDXbool qcspike; JDXstring preproc3d; JDXstring postproc3d; JDXstring dumpRawPrefix; JDXstring fieldmapFile; JDXstring driftcalcFile; JDXstring driftcorrFile; bool execute_pipeline(); bool prepare_pipeline(); bool finalize_pipeline(); bool feed_pipeline(); bool dump_raw() const; static void tracefunction(const LogMessage& msg); static int controlthread; template bool get_kspace_sampling_pattern(const RecoCoord& mask, unsigned int& reduction_factor, bool& partial_fourier) const; bool autorecipe(const RecoCoord& mask, STD_string& result) const; typedef STD_map WaitingMap; WaitingMap waiting; STD_string waiting_error; Mutex waiting_mutex; void incr_waiting_threads(const STD_string& condition) {MutexLock lock(waiting_mutex); waiting[Thread::self()]=condition;} void decr_waiting_threads() {MutexLock lock(waiting_mutex); waiting.erase(waiting.find(Thread::self()));} unsigned int numof_waiting_threads() {MutexLock lock(waiting_mutex); return waiting.size();} STD_map thread_depth; // trace the depth (recursion level) of each thread RecoReaderInterface* input; mutable Mutex inputmutex; RecoStep* pipeline; RecoStepFactory* factory; RecoBlackBoard blackboard; ProgressDisplayConsole display; // Create display before pmeter ProgressMeter pmeter; // ProgressMeter is thread-safe unsigned short numof_cache[n_recoDims]; mutable bool has_readoutshape; mutable unsigned char has_flag_cache; mutable bool has_templcorr_cache[n_templateTypes]; mutable bool has_navigator_cache[n_navigatorTypes]; mutable bool has_traj; mutable bool has_oversampling_cache; mutable bool has_relcenter_cache; Protocol prot_cache; volatile bool status; // Although it is used in different threads, we will assume that reads/writes to bool are atomic mutable STD_map countmap_cache; // cache countmap since the same countmap is calculated several times in create_count_map() void delete_countmap_cache(); }; /** @} */ #endif odin-1.8.5/odinreco/grid_code.h0000644000175000017500000002064411455553545013313 00000000000000#include "grid.h" #include "data.h" #include "controller.h" static const char* deapodize_post_str="deapodize"; template void RecoGrid::init() { deapo_shift=true; deapo_shift.set_description("Shift deapodization function for correct offset"); append_arg(deapo_shift,"deapo_shift"); kernel.set_funcpars("Gauss"); kernel.set_cmdline_option("kg"+postfix()).set_description("Kernel function for "+postfix()+" k-space gridding"); append_arg(kernel,"kernel"); kernelwidth=sqrt(float(3-NDim))*3.0; // found empirically kernelwidth.set_cmdline_option("kw"+postfix()).set_unit("Pixel").set_description("Kernel width for "+postfix()+" k-space gridding"); append_arg(kernelwidth,"kernelwidth"); gridScale = 1.0; gridScale.set_cmdline_option("gs").set_description("Scale Factor for the grid used for gridding"); append_arg(gridScale,"gridScale"); } template TinyVector RecoGrid::gridshape(const RecoCoord& coord, RecoController& controller) { Log odinlog("RecoGrid","gridshape"); TinyVector imagesize=controller.image_size(); TinyVector result; for(int i=0; isecond)>0) result(0)=coord.readoutShape->second; // already includes oversampling else result(0)=int(result(0)*coord.overSamplingFactor+0.5); // only for ADC regridding, oversampling will be removed later in image domain } ODINLOG(odinlog,normalDebug) << "result=" << result << STD_endl; return result; } template const Gridding& RecoGrid::get_gridder(const RecoCoord& coord, RecoController& controller) { Log odinlog(c_label(),"get_gridder"); MutexLock lock(gridmutex); const KspaceTraj* traj=coord.kspaceTraj; // access is protected by mutex typename GridderMap::const_iterator it=gridmap.find(traj); if(it==gridmap.end()) { Gridding& gridder=gridmap[traj]; float appGridScale = gridScale; if (NDim == 1) appGridScale = 1.0; // don't use grid scaling for 1D Gridding TinyVector dstshape=gridshape(coord, controller); int nseg=traj->extent(0); // e.g. spiral segments int npts=traj->extent(1); STD_vector > srccoords(nseg*npts); // all segments in one gridder for correct weighting of src values for(int iseg=0; iseg& kpoint=(*traj)(iseg,ipt).coord; TinyVector& srcpoint=srccoords[iseg*npts+ipt].coord; for(int i=0; i kmax=controller.kspace_extent(); TinyVector dstextent; for(int i=0; i sampldens(dstshape); sampldens=gridder.init(dstshape, dstextent, srccoords, kernel, kwidth); // sampldens.autowrite("sampldens.jdx"); // Create magnitude correction for regridded data according to the gridding kernel used int deapo_os_factor=4; // oversampling to account for small kernels TinyVector shape_os(deapo_os_factor*dstshape); ComplexData kspace_kernel_os(shape_os); kspace_kernel_os=STD_complex(0.0); // fill k-space with gridding kernel for(int i=0; i index=kspace_kernel_os.create_index(i); TinyVector dist=index-shape_os/2; float radius=secureDivision( sqrt(double(sum(dist*dist))), 0.5*deapo_os_factor*kernelwidth*appGridScale); if(radius<=1.0) kspace_kernel_os(index)=STD_complex(kernel.calculate(radius)); } ODINLOG(odinlog,normalDebug) << "deapo_shift=" << deapo_shift << STD_endl; if(deapo_shift) { // Take spatial offset into account TinyVector reloffset=controller.reloffset(); TinyVector reloffset_os; for(int i=0; i0.0) kspace_kernel_os.modulate_offset(reloffset_os); } // FFT and cutting out central part with de-apodize function kspace_kernel_os.fft(); Data apodize(dstshape); apodize=cabs(kspace_kernel_os(RectDomain((shape_os-dstshape)/2, (shape_os-dstshape)/2+dstshape-1))); // apodize.autowrite("apodize"+ptos(traj)+".jdx"); if(min(apodize)>0.0) { RecoData rdposted; // post separately for templates rdposted.coord().index[templtype]=coord.index[templtype]; rdposted.coord().index[templtype].set_mode(RecoIndex::separate); rdposted.data(Rank()).reference(float2real(mean(apodize)/apodize)); controller.post_data(deapodize_post_str+postfix(), rdposted); } else { ODINLOG(odinlog,warningLog) << "FT of gridding kernel contains zero, not applying de-apodize correction" << STD_endl; } return gridder; } return it->second; } template bool RecoGrid::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); if(!rd.coord().kspaceTraj) { ODINLOG(odinlog,errorLog) << "No kspaceTraj available for coord=" << rd.coord().print() << STD_endl; return false; } rd.coord().gridScaleFactor = gridScale; const Gridding& gridder=get_gridder(rd.coord(), controller); TinyVector outshape=gridshape(rd.coord(), controller); if (NDim > 1) { for (int i=0; i outdata(outshape); ComplexData<1>& adc=rd.data(Rank<1>()); int adcSize=adc.extent(0); ODINLOG(odinlog,normalDebug) << "adcSize=" << adcSize << STD_endl; unsigned int offset=0; if(rd.coord().kspaceTraj->extent(0)>1) offset=rd.coord().index[cycle]*adcSize; // only for segmented 2D spirals, ignore cycle otherwise outdata=gridder(adc, offset); rd.data(Rank()).reference(outdata); return execute_next_step(rd,controller); } template bool RecoGrid::query(RecoQueryContext& context) { if(context.mode==RecoQueryContext::prep) { context.controller.announce_data(deapodize_post_str+postfix()); } return RecoStep::query(context); } ///////////////////////////////////////////////////////////////////////////////// template bool RecoDeapodize::process(RecoData& rd, RecoController& controller) { RecoData rddeapo; if(!controller.inquire_data(deapodize_post_str+postfix(), rddeapo)) return false; ComplexData<3>& data=rd.data(Rank<3>()); ComplexData& deapo=rddeapo.data(Rank()); for(int i=0; i index=data.create_index(i); TinyVector deapoindex; for(int i=0; i& indata=rd.data(Rank<3>()); TinyVector inshape(indata.shape()); TinyVector outshape(inshape(0), inshape(1) / scaleFactor, inshape(2) / scaleFactor); TinyVector phasebounds((inshape(1) - outshape(1)) / 2, (inshape(1) + outshape(1)) / 2); TinyVector readbounds((inshape(1) - outshape(1)) / 2, (inshape(1) + outshape(1)) / 2); ComplexData<3> outdata(outshape); outdata = indata(all,Range(phasebounds(0),phasebounds(1)),Range(readbounds(0),readbounds(1))); rd.data(Rank<3>()).reference(outdata); rd.coord().gridScaleFactor = 1.0; // reset to 1.0 since the scaling has been removed from the data } return execute_next_step(rd,controller); } odin-1.8.5/odinreco/index.h0000644000175000017500000002705111734622163012473 00000000000000/*************************************************************************** index.h - description ------------------- begin : Mon Jan 27 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOINDEX_H #define RECOINDEX_H #include #include /** * @addtogroup odinreco * @{ */ /** * Manages information of data in one dimension. */ class RecoIndex { public: /** * Mode the index is used for: * - separate : Dimensions are processed separately. * - ignore : Same as 'separate', but the index is ignored when comparing indices. * - single : In a previous processing step, a single index was selected (or reduction to a single index), as an effect, this index is always zero. (Since only one value is possible, it is ignored when sorting indices (operator <)) * - collected : Data from all inidices is combined and transfered simultaneously. * - any : Any of the above (for checking functor interfaces). */ enum indexMode {separate=0, ignore, single, collected, any}; /** * Constructs default index object. */ RecoIndex(unsigned short v=0) : mode(separate), val(v), numof(1) {} /** * Assignment operator from integer. */ RecoIndex& operator = (unsigned short v) {val=v; return *this;} /** * Comparison operator for indexing */ bool operator < (const RecoIndex& ri) const { // comparison makes sense only in 'separate' mode. if( mode==separate && ri.mode==separate ) { return val < ri.val; } return false; // equal or ignored when comparing } /** * Conversion operator */ operator unsigned short () const {if(mode==single) return 0; return val;} // return zero index in single mode for numof=1 /** * Sets the mode */ RecoIndex& set_mode(indexMode m) {mode=m; return *this;} /** * Returns the mode */ indexMode get_mode() const {return indexMode(mode);} /** * Returns true if two indices are compatible when chaining functors */ bool compatible(const RecoIndex& ri) const { if(mode==any || ri.mode==any) return true; if(mode==collected && ri.mode!=collected) return false; if(mode!=collected && ri.mode==collected) return false; if(mode==single && ri.mode==single && val!=ri.val) return false; return true; } /** * Returns true if this is in the range of 'mask'. Prepares index for count map. */ bool prep_count(const RecoIndex& mask) { if(mask.mode==single) { if(val!=mask.val) return false; } mode=mask.mode; return true; } /** * Sets the number of indices */ RecoIndex& set_numof(unsigned short n) {numof=n; return *this;} /** * Returns the number of indices */ unsigned short get_numof() const {if(mode==single) return 1; return numof;} /** * Mode for printing the index: * - brief : Brief version for debugging * - all : Include all information, i.e. all indices will be printed with their current value, regardless of their mode or numof * - filename : Suitable for generating filenames */ enum printMode {brief=0, all, filename}; /** * Converts the index to a string for reco dimension 'dim' according to 'printmode' */ STD_string print(recoDim dim, printMode printmode=brief) const; private: unsigned char mode; unsigned short val; unsigned short numof; }; ////////////////////////////////////////////////////////////////// typedef Data ,2> KspaceTraj; // dimension is (nsegments, npoints) typedef STD_pair, int> ReadoutShape; // shape and target grid size /** * Holds reconstruction coordinate of one acquisition frame, i.e. position of reconstruction data in multiple dimensions. */ struct RecoCoord { /** * Construct default coordinate */ RecoCoord() {common_init();} /** * Comparison operator for indexing */ bool operator < (const RecoCoord& rc) const { for(int i=0; i* weightVec; /** * Dwell time of the signal data */ double dwellTime; /** * Oversampling factor in readout direction */ float overSamplingFactor; /** * Relative position of k-space center in readout direction */ float relCenterPos; /** * First index in readout direction actually measured */ unsigned short adcstart; /** * Last index in readout direction actually measured */ unsigned short adcend; /** * Scale factor for gridding reconstruction */ float gridScaleFactor; /** * Echo-train index in a multi-echo readout, e.g. an CPMG or EPI echo train. * Use this for non-phasecorr template scans and set echo index to zero. */ unsigned short echopos; /** * EPI echo-train index for 3D multi-EPI readout and EPI navigator correction. */ unsigned short echotrain; private: void common_init() { flags=0; readoutShape=0; kspaceTraj=0; weightVec=0; dwellTime=0.0; overSamplingFactor=1.0; relCenterPos=0.5; adcstart=0; adcend=0; gridScaleFactor=1.0; echopos=0; echotrain=0; index[readout].set_mode(RecoIndex::collected); // readout is already collected for ADCs } }; //////////////////////////////////////////////////////////////////////////// /** * Map to count the number of times a coordinate was measured/interpolated */ typedef STD_map CoordCountMap; //////////////////////////////////////////////////////////////////////////// /** * Helper template to define a set of 'Ndim' dimensions using default arguments for unused dimensions. */ template struct RecoDim { /** * Returns the number of dimensions to set/modify. */ static unsigned int dim() {return Ndim;} /** * Returns coordinate with specified dimensions set to mode 'm'. */ static RecoCoord preset_coord(RecoIndex::indexMode m) {return RecoCoord::coord_with_mode(m, d1, d2, d3, d4, d5, d6);} /** * Sets specified dimensions in coordinate 'coord' to mode 'm'. */ static void modify(RecoIndex::indexMode m, RecoCoord& coord) {coord.set_mode(m, d1, d2, d3, d4, d5, d6);} /** * Creates 'Ndim' dimensional index vector in specified dimensions using coordinate 'coord'. */ static void create_index(const RecoCoord& coord, TinyVector& index) { unsigned int idim=0; if(d1!=n_recoDims) {index(idim)=coord.index[d1]; idim++;} if(d2!=n_recoDims) {index(idim)=coord.index[d2]; idim++;} if(d3!=n_recoDims) {index(idim)=coord.index[d3]; idim++;} if(d4!=n_recoDims) {index(idim)=coord.index[d4]; idim++;} if(d5!=n_recoDims) {index(idim)=coord.index[d5]; idim++;} if(d6!=n_recoDims) {index(idim)=coord.index[d6]; idim++;} } /** * Creates 'Ndim' dimensional shape vector in specified dimensions using coordinate 'coord'. */ static void create_shape(const RecoCoord& coord, TinyVector& shape) { unsigned int idim=0; if(d1!=n_recoDims) {shape(idim)=coord.numof(d1); idim++;} if(d2!=n_recoDims) {shape(idim)=coord.numof(d2); idim++;} if(d3!=n_recoDims) {shape(idim)=coord.numof(d3); idim++;} if(d4!=n_recoDims) {shape(idim)=coord.numof(d4); idim++;} if(d5!=n_recoDims) {shape(idim)=coord.numof(d5); idim++;} if(d6!=n_recoDims) {shape(idim)=coord.numof(d6); idim++;} } /** * Copies values of 'Ndim' dimensional index vector to specified dimensions in 'coord'. */ static void set_index(const TinyVector& index, RecoCoord& coord) { unsigned int idim=0; if(d1!=n_recoDims) {coord.index[d1]=index(idim); idim++;} if(d2!=n_recoDims) {coord.index[d2]=index(idim); idim++;} if(d3!=n_recoDims) {coord.index[d3]=index(idim); idim++;} if(d4!=n_recoDims) {coord.index[d4]=index(idim); idim++;} if(d5!=n_recoDims) {coord.index[d5]=index(idim); idim++;} if(d6!=n_recoDims) {coord.index[d6]=index(idim); idim++;} } }; /** @} */ #endif odin-1.8.5/odinreco/driftcorr.cpp0000644000175000017500000000613711734622163013717 00000000000000#include "driftcorr.h" #include "data.h" #include "controller.h" bool RecoDriftCalc::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<6>& indata=rd.data(Rank<6>()); ComplexData<1>& outdata=rd.data(Rank<1>()); TinyVector inshape=indata.shape(); ODINLOG(odinlog,normalDebug) << "inshape=" << inshape << STD_endl; int nchan=inshape(0); int nrep=inshape(1); int nslice=inshape(2); ComplexData<1> cplxtcourse(nrep); Data phasecourse(nrep); Data phasecoursesum(nrep); phasecoursesum=0.0; float magnsum=0.0; for(int ichan=0; ichan0.0 && te>0.0) { rd.mode=RecoData::real_data; outdata.resize(nrep); outdata=float2real(phasecoursesum/(magnsum*te)); } else { ODINLOG(odinlog,errorLog) << "Cannot calculate field drift" << STD_endl; return false; } indata.free(); return execute_next_step(rd,controller); } ///////////////////////////////////////////////////////////////////////// bool RecoDriftCorr::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); double freq=0.0; mutex.lock(); int cachesize=driftcache.size(); mutex.unlock(); ODINLOG(odinlog,normalDebug) << "cachesize=" << cachesize << STD_endl; if(!cachesize) { RecoData rdfdrift; if(!controller.inquire_data(posted_drift_str, rdfdrift)) return false; mutex.lock(); driftcache.reference(creal(rdfdrift.data(Rank<1>()))); ODINLOG(odinlog,normalDebug) << "driftcache" << driftcache << STD_endl; mutex.unlock(); } int irep=rd.coord().index[repetition]; mutex.lock(); int nrep=driftcache.size(); if(irep& data=rd.data(Rank<1>()); unsigned int adcSize=data.extent(0); double dt=rd.coord().dwellTime; ODINLOG(odinlog,normalDebug) << "freq/adcSize/dt=" << freq << "/" << adcSize << "/" << dt << STD_endl; double reftime=0.0; dvector echostart=controller.dim_values(echo); unsigned int iecho=rd.coord().echopos; if(echostart.size()) reftime=echostart[iecho]; ODINLOG(odinlog,normalDebug) << "echostart/reftime=" << echostart << "/" << reftime << STD_endl; for(unsigned int isample=0; isample #include /** * @addtogroup odinreco * @{ */ /** * Interface class for all raw-data readers. */ class RecoReaderInterface { public: virtual ~RecoReaderInterface() {} /** * Initializes reader. * 'input_filename' contains meta and/or references raw data. */ virtual bool init(const STD_string& input_filename) = 0; /** * Returns the next available ADC (each channel has its own ADC) in 'adc' with k-space coordinates 'coord', * returns 'false' only if none left. */ virtual bool fetch(RecoCoord& coord, ComplexData<1>& adc) = 0; /** * Gets the k-space coordinates of all ADCs (each channel has its own ADC) in a single vector. */ virtual const STD_vector& get_coords() const = 0; /** * Returns vector of values associated with a certain dimension. */ virtual dvector dim_values(recoDim dim) const = 0; /** * Returns the relative spatial offset the image should be shifted after reconstruction. * The result contains the offsets in (phase3d,phase,read) direction. */ virtual const TinyVector& reloffset() const = 0; /** * Extra command-line arguments for processing of final images. */ virtual STD_string image_proc() const = 0; /** * Returns the image size, will be used if it cannot be determined from the k-space * coordinates (i.e. when gridding). */ virtual const TinyVector& image_size() const = 0; /** * Returns the scan protocol. */ virtual const Protocol& protocol() const = 0; /** * Returns the reco recipe (pipeline layout) as specified by the sequence. * If result is left blank, the recipe will be generated automatically. */ virtual STD_string seqrecipe() const = 0; /** * Returns the extra chain of reconstruction steps (functors) which will be * performed after 3D reconstruction (including channel combination) but before * data is stored on disk. Leave blank if no extra steps are necessary. */ virtual STD_string postProc3D() const = 0; /** * Returns the extra chain of reconstruction steps (functors) described by 'recipe' * wil be performed after 3D FFT but before channel combination. * Leave blank if no extra steps are necessary. */ virtual STD_string preProc3D() const = 0; /** * Returns extra command-line options for the reco. */ virtual STD_string cmdline_opts() const = 0; }; /** @} */ #endif odin-1.8.5/odinreco/homodyne_code.h0000644000175000017500000001315311455553545014205 00000000000000#include "homodyne.h" #include "data.h" #include "controller.h" #include template bool RecoHomodyne::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); int nipol=shape(interpolIndex); int startindex=0; if(interpolDim==readout) { if(rd.coord().adcend<(nipol-1)) { ODINLOG(odinlog,errorLog) << "Not implemented: Interpolation at end of readout" << STD_endl; return false; } startindex=rd.coord().adcstart; } else { if(rd.interpolated) measlines.update(*(rd.interpolated)); // take previously interpolated coords into account ivector indexvec=measlines.get_indices(rd.coord()); startindex=indexvec.minvalue(); } float center=0.5*float(nipol-1); int endindex=nipol-1-startindex; ODINLOG(odinlog,normalDebug) << "startindex/endindex/center=" << startindex << "/" << endindex << "/" << center << STD_endl; if(float(startindex) symmetric(shape); symmetric=STD_complex(0.0); if(startindex>0) { // Don't do this for fully-sampled k-space // symmetric part Range symrange(startindex,endindex); if(interpolIndex==0) symmetric(symrange,all,all)=data(symrange,all,all); if(interpolIndex==1) symmetric(all,symrange,all)=data(all,symrange,all); if(interpolIndex==2) symmetric(all,all,symrange)=data(all,all,symrange); symmetric.fft(); // pre weighting fvector transition(endindex-startindex+1); transition.fill_linear(0.0,1.0); ComplexData<1> weight(shape(interpolIndex)); weight=STD_complex(1.0); TinyVector index; for(int i=0; i0) { // Don't do this for fully-sampled k-space // phase correction data*=expc(float2imag(-phase(symmetric))); // take real part ComplexData<3> realpart(shape); realpart=float2real(creal(data)); data.reference(realpart); } } else if(fabs(float(startindex)-center)<=1.0) { // Just mirror k-space ODINLOG(odinlog,significantDebug) << "Conjugate-mirror reco with startindex=" << startindex << STD_endl; if(interpolDim!=line) { ODINLOG(odinlog,errorLog) << "Not implemented: Conjugate-mirror reco in dimension " << recoDimLabel[interpolDim] << STD_endl; return false; } int nread=shape(2); // Apply phase correction using the central line data.partial_fft(TinyVector(false,false,true)); // FFT in read ComplexData<1> centline(data(shape(0)/2,startindex,all)); Data centphase(centline.phasemap()); Data centmagn(cabs(centline)); Data centerr(nread); for(int iread=0; iread(false,false,true),false); // inv FFT in read ComplexData<1> oneline(nread); int nmeas=nipol-startindex; for(int iphase3d=0; iphase3d=0) { oneline=conjc(data(iphase3d,isrc,all).reverse(0)); if(!(nread%2)) oneline.shift(0,1); // for even nread, the center frequency is at nread/2 data(iphase3d,idst,all)=oneline; } } } if(!(nread%2)) data(all,0,all)=STD_complex(0.0); // zero-fill garbage from cyclic shift // do the FFT data.fft(); /* Data(creal(data)).autowrite("creal_"+rd.coord().print(RecoIndex::filename)+".jdx"); Data(cimag(data)).autowrite("cimag_"+rd.coord().print(RecoIndex::filename)+".jdx"); Data(cabs(data)).autowrite("cabs_"+rd.coord().print(RecoIndex::filename)+".jdx"); Data(phase(data)).autowrite("phase_"+rd.coord().print(RecoIndex::filename)+".jdx"); */ } else { ODINLOG(odinlog,errorLog) << "startindex=" << startindex << " larger than center=" << center << STD_endl; return false; } return execute_next_step(rd,controller); } /////////////////////////////////////////////////////// template bool RecoHomodyne::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(interpolDim!=readout) { if(!measlines.init(context.coord, context.controller)) return false; } } return RecoStep::query(context); } odin-1.8.5/odinreco/qualitycontrol.cpp0000644000175000017500000000616511725203123015002 00000000000000#include "qualitycontrol.h" #include "data.h" bool RecoQualityControlSpike::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); float kspace_center_frac=0.5; float kspace_magn_excess=4.0; float spike_excess=3.0; TinyVector lowerBounds, upperBounds; for(int idim=0; idim<3; idim++) { int low=int(0.5*shape(idim) * (1.0-kspace_center_frac) + 0.5); if(low<0) low=0; lowerBounds(idim) = low; int upp=int(0.5*shape(idim) * (1.0+kspace_center_frac) + 0.5); if(upp>(shape(idim)-1)) upp=shape(idim)-1; upperBounds(idim) = upp; } ODINLOG(odinlog,normalDebug) << "lowerBounds/upperBounds=" << lowerBounds << "/" << upperBounds << STD_endl; RectDomain<3> kspace_center(lowerBounds, upperBounds); int npts_kspace=data.size(); int npts_kspace_center=product(TinyVector(upperBounds-lowerBounds+1)); int npts_kspace_periphery=npts_kspace-npts_kspace_center; ODINLOG(odinlog,normalDebug) << "npts_kspace/npts_kspace_center=" << npts_kspace << "/" << npts_kspace_center << STD_endl; totalmutex.lock(); total_acqpts+=npts_kspace_periphery; totalmutex.unlock(); Data magn(cabs(data)); magn(kspace_center)=0.0; float meanmagn_periphery=secureDivision(sum(magn),npts_kspace_periphery); ODINLOG(odinlog,normalDebug) << "meanmagn_periphery=" << meanmagn_periphery << STD_endl; float kpsace_thresh=kspace_magn_excess*meanmagn_periphery; for(int iphase3d=0; iphase3dkpsace_thresh) { if(magnval>(spike_excess*magn(iphase3d,iphase,iread-2)) && magnval>(spike_excess*magn(iphase3d,iphase,iread+2))) { MutexLock lock(spikemutex); spikecount[ rd.coord().index[channel]]++; // data(iphase3d,iphase,iread)=STD_complex(1.0); ODINLOG(odinlog,normalDebug) << "Spike detected at iphase3d/iphase/iread=" << iphase3d << "/" << iphase << "/" << iread << " in k-space of " << rd.coord().print() << STD_endl; } } } } } return execute_next_step(rd,controller); } ////////////////////////////////////////////////////////////////////// bool RecoQualityControlSpike::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { total_acqpts=0; spikecount.clear(); } unsigned int total=0; STD_string spikestr; if(context.mode==RecoQueryContext::finalize) { for(STD_map::const_iterator it=spikecount.begin(); it!=spikecount.end(); ++ it) { spikestr+=itos(it->second)+"("+itos(it->first)+") "; total+=it->second; } ODINLOG(odinlog,infoLog) << "spikecount=" << spikestr << " total / ratio = " << total << " / " << secureDivision(total,total_acqpts) << STD_endl; if(spikecount.size()) ODINLOG(odinlog,warningLog) << "Spikes detected" << STD_endl; } return RecoStep::query(context); } odin-1.8.5/odinreco/multifreq.h0000644000175000017500000000531011322062351013354 00000000000000/*************************************************************************** multifreq.h - description ------------------- begin : Wed Jun 6 2007 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECOMULTIFREQ_H #define RECOMULTIFREQ_H #include "fieldmap.h" class RecoMultiFreq : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "multifreq";} STD_string description() const {return "Generate multi-frequency ADCs based on fieldmap";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoMultiFreq;} void init(); JDXint max_numof_freq; bool get_freqs(Data& result, const RecoCoord& fmapcoord, double adcdur, RecoController& controller); // cache frequency values typedef STD_map > FreqMap; FreqMap freqmap; Mutex freqmutex; darray echoTimeStamps; // epis x echoes Mutex stampmutex; }; ///////////////////////////////////////////////////////////////////////////////////////////////////////// class RecoFreqComb : public RecoFieldMapUser { // implementing virtual functions of RecoStep STD_string label() const {return "freqcomb";} STD_string description() const {return "Combine multi-frequency images using fieldmap";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,freq,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single,freq);} RecoStep* allocate() const {return new RecoFreqComb;} void init() {} bool get_freqs(Data& result, const RecoCoord& fmapcoord, RecoController& controller); }; #endif odin-1.8.5/odinreco/driftcorr.h0000644000175000017500000000451111734622163013356 00000000000000/*************************************************************************** driftcorr.h - description ------------------- begin : Thu Mar 1 2012 copyright : (C) 2001 by Thies Jochimsen email : jochimse@cns.mpg.de ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef RECODRIFTCORR_H #define RECODRIFTCORR_H #include "step.h" static const char* posted_drift_str="fielddrift"; class RecoDriftCalc: public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "driftcalc";} STD_string description() const {return "Calculate field drift over repetitions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,channel,repetition,slice,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::single, channel,slice,line3d,line,readout);} RecoStep* allocate() const {return new RecoDriftCalc;} void init() {} }; //////////////////////////////////////////////////////// class RecoDriftCorr: public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "driftcorr";} STD_string description() const {return "Correct for linear field drift over repetitions";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,readout);} void modify_coord(RecoCoord& coord) const {} RecoStep* allocate() const {return new RecoDriftCorr;} void init() {} Data driftcache; Mutex mutex; }; #endif odin-1.8.5/odinreco/blade.cpp0000644000175000017500000004672111363773557013007 00000000000000#include "blade.h" #include "data.h" #include "controller.h" #include "bladegrid.h" #include #include #include void RecoBladeGrid::init() { fft = false; fft.set_description("Perform partial FFT into image space before feeding data into rest of the pipeline"); append_arg(fft,"fft"); filtermask.set_funcpars("Triangle"); filtermask.set_description("Filter function for k-space center. NoFilter = whole blade (not only center)"); append_arg(filtermask,"filtermask"); } bool RecoBladeGrid::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& data=rd.data(Rank<4>()); TinyVector inshape=data.shape(); TinyVector inshape3d(inshape(1), inshape(2), inshape(3)); ODINLOG(odinlog,normalDebug) << "inshape3d=" << inshape3d << STD_endl; float os_factor=rd.coord().overSamplingFactor; ODINLOG(odinlog,normalDebug) << "os_factor=" << os_factor << STD_endl; if(os_factor<1.0) { ODINLOG(odinlog,errorLog) << "os_factor(" << os_factor << ") < 1.0" << STD_endl; return false; } dvector angles=controller.dim_values(cycle); ODINLOG(odinlog,normalDebug) << "angles=" << angles.printbody() << STD_endl; TinyVector fov; fov=1; // fov(0)=controller.protocol().geometry.get_FOV(sliceDirection); fov(1)=controller.protocol().geometry.get_FOV(phaseDirection); fov(2)=controller.protocol().geometry.get_FOV(readDirection); ODINLOG(odinlog,normalDebug) << "fov=" << fov << STD_endl; // Prepare Input Data if(rd.interpolated) measlines.update(*(rd.interpolated)); // take previously interpolated coords into account ivector indexvec3d=measlines.get_indices(rd.coord()); // Use only planes actually measured ComplexData<4> infixed(inshape(0),indexvec3d.size(),inshape(2),inshape(3)); for(int i = 0; i < indexvec3d.size(); i++) { int iphase3d = indexvec3d[i]; infixed(all,i,all,all) = data(all,iphase3d,all,all); } // Grid blades BladeGrid bg; bg.init(inshape3d,fov,controller.image_size(),os_factor,filtermask); ComplexData<4> bladesgrid_kspace = bg(infixed,angles); // perform FFT if parameter is set if (fft) { TinyVector fftdims(false,false,true,true); bladesgrid_kspace.partial_fft(fftdims,true); } data.resize(bladesgrid_kspace.shape()); data = bladesgrid_kspace; return execute_next_step(rd,controller); } /////////////////////////////////////////////////////////////////////////// bool RecoBladeGrid::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(!measlines.init(context.coord, context.controller)) return false; } return RecoStep::query(context); } //////////////////////////////////////////////////////////////////////////////////// bool RecoCycleRot::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); dvector angles=controller.dim_values(cycle); if(!angles.size()) { ODINLOG(odinlog,errorLog) << "No angles available for cycle" << STD_endl; return false; } // feed each rotated dataset into rest of pipeline for(int i=0; i& data=rdcopy.data(Rank<3>()); RotMatrix rotmat; rotmat.set_inplane_rotation(-angles[i]); TinyVector offset=0.0; TinyMatrix rotation; for(int irow=0; irow<2; irow++) { for(int icol=0; icol<2; icol++) { rotation(1-irow,1-icol)=rotmat[irow][icol]; } } CoordTransformation transform(TinyVector(data.extent(1),data.extent(2)), rotation, offset, 2.0); for(int iphase3d=0; iphase3d odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<3>& indata=rd.data(Rank<3>()); float os_factor=rd.coord().overSamplingFactor; ODINLOG(odinlog,normalDebug) << "os_factor=" << os_factor << STD_endl; if(os_factor<1.0) { ODINLOG(odinlog,errorLog) << "os_factor(" << os_factor << ") < 1.0" << STD_endl; return false; } TinyVector inshape3d(indata.shape()); TinyVector inshape3d_no(inshape3d(0), inshape3d(1), int(inshape3d(2)/os_factor+0.5)); // without oversampling ODINLOG(odinlog,normalDebug) << "inshape3d=" << inshape3d << STD_endl; ODINLOG(odinlog,normalDebug) << "inshape3d_no=" << inshape3d_no << STD_endl; int center_diameter=STD_min(inshape3d_no(1),inshape3d_no(2)); // Size of the fully oversampled center of k-space int kspace_diameter=STD_max(inshape3d_no(1),inshape3d_no(2)); // The size of the overall k-space ODINLOG(odinlog,normalDebug) << "center_diameter/kspace_diameter=" << center_diameter << "/" << kspace_diameter << STD_endl; TinyVector diashape(inshape3d(0), kspace_diameter, int(kspace_diameter*os_factor+0.5)); if(inshape3d(1)%2 != diashape(1)%2) diashape(1)++; // for correct placing at center if(inshape3d(2)%2 != diashape(2)%2) diashape(2)++; // for correct placing at center ODINLOG(odinlog,normalDebug) << "diashape=" << diashape << STD_endl; TinyVector centshape(inshape3d(0), center_diameter, int(center_diameter*os_factor+0.5)); if(inshape3d(1)%2 != centshape(1)%2) centshape(1)++; // for correct placing at center if(inshape3d(2)%2 != centshape(2)%2) centshape(2)++; // for correct placing at center ODINLOG(odinlog,normalDebug) << "centshape=" << centshape << STD_endl; TinyVector lowsrc(0, (inshape3d(1)-centshape(1))/2, (inshape3d(2)-centshape(2))/2); TinyVector uppsrc(inshape3d(0)-1,(inshape3d(1)+centshape(1))/2-1,(inshape3d(2)+centshape(2))/2-1); ODINLOG(odinlog,normalDebug) << "lowsrc=" << lowsrc << STD_endl; ODINLOG(odinlog,normalDebug) << "uppsrc=" << uppsrc << STD_endl; TinyVector lowdst(0, (diashape(1)-centshape(1))/2, (diashape(2)-centshape(2))/2); TinyVector uppdst(inshape3d(0)-1,(diashape(1)+centshape(1))/2-1,(diashape(2)+centshape(2))/2-1); ODINLOG(odinlog,normalDebug) << "lowdst=" << lowdst << STD_endl; ODINLOG(odinlog,normalDebug) << "uppdst=" << uppdst << STD_endl; // The domains when copying data from central part of blades to central part of square k-space RectDomain<3> srcdomain(lowsrc,uppsrc); RectDomain<3> dstdomain(lowdst,uppdst); // Consistency check TinyVector srcrange=srcdomain.ubound()-srcdomain.lbound(); TinyVector dstrange=dstdomain.ubound()-dstdomain.lbound(); if(srcrange!=dstrange) { ODINLOG(odinlog,errorLog) << "range error:" << STD_endl; ODINLOG(odinlog,errorLog) << "srcrange=" << srcrange << STD_endl; ODINLOG(odinlog,errorLog) << "dstrange=" << dstrange << STD_endl; return false; } TinyVector lowpad(0, (diashape(1)-inshape3d(1))/2, (diashape(2)-inshape3d(2))/2); TinyVector upppad(inshape3d(0)-1,(diashape(1)+inshape3d(1))/2-1,(diashape(2)+inshape3d(2))/2-1); RectDomain<3> paddomain(lowpad,upppad); ODINLOG(odinlog,normalDebug) << "lowpad=" << lowpad << STD_endl; ODINLOG(odinlog,normalDebug) << "upppad=" << upppad << STD_endl; // Remove apodization from ramp regridding STD_string deapo_postlabel="deapodize1d"; bool has_deapo=false; ComplexData<3> deapo; if(controller.data_announced(deapo_postlabel)) { RecoData rddeapo; if(!controller.inquire_data(deapo_postlabel, rddeapo)) return false; const ComplexData<1>& deapoline=rddeapo.data(Rank<1>()); if(deapoline.size()!=inshape3d(2)) { ODINLOG(odinlog,errorLog) << "Size mistmatch" << STD_endl; return false; } deapo.resize(inshape3d); for(int iphase3d=0; iphase3d(cabs(deapo)).autowrite("deapo.jdx"); } bool isNoFilter = (phasecorr_filter.get_function_name() == "NoFilter"); ComplexData<3> blade_pad(diashape); blade_pad=STD_complex(0.0); // 2D Phase correction // Phase correction by windowed fourier transformation and phase removing if (isNoFilter) { // simply remove all phase in image space blade_pad(paddomain) = indata; // Put blade at center of padded kspace blade_pad.fft(true); // FFT into image space blade_pad = float2real(cabs(blade_pad)); // remove phase } else { // Low pass filter for k-space center Data filtermask(inshape3d); filtermask=0.0; TinyVector bounds(inshape3d); if (phasecorr_width < 0.0) bounds(2) = centshape(2) * (-1) * phasecorr_width; else bounds(2) *= phasecorr_width; for(int j=0; j lowpass_kspace(diashape); // 2D Phase correction // Phase correction by windowed fourier transformation and phase removing Data phasemap(diashape); lowpass_kspace=STD_complex(0.0); blade_pad=STD_complex(0.0); lowpass_kspace(paddomain) = indata * float2real(filtermask); // Smooth transition at edges blade_pad(paddomain) = indata; // Put blade at center of padded kspace lowpass_kspace.fft(true); blade_pad.fft(true); phasemap = phase(lowpass_kspace); blade_pad=blade_pad*expc(float2imag(-phasemap)); // Phase correction } if(has_deapo) blade_pad=blade_pad*deapo; // deapodization in image space blade_pad.fft(false); // inverse FFT indata=blade_pad(paddomain); return execute_next_step(rd,controller); } /////////////////////////////////////////////////////////////////////////// void RecoBladeComb::init() { keyhole=false; keyhole.set_description("Keyhole combination of blades"); append_arg(keyhole,"keyhole"); corrweight=false; corrweight.set_cmdline_option("bcw").set_description("Correlation weighting of all blades against the mean of all blades (in image space)"); append_arg(corrweight,"corrweight"); keyhole_filter.set_funcpars("CosSq"); keyhole_filter.set_cmdline_option("bkf").set_description("Blade-keyhole filter function (and its arguments)"); append_arg(keyhole_filter,"keyhole_filter"); kspaceweight_filter.set_funcpars("Triangle"); kspaceweight_filter.set_cmdline_option("bwf").set_description("Window/Filter function for kspace weighting of each blade"); append_arg(kspaceweight_filter,"kspaceweight_filter"); kspaceweight_width = 1; kspaceweight_width.set_cmdline_option("bww").set_description("Window/Filter width for kspace weighting of each blade"); append_arg(kspaceweight_width,"kspaceweight_width"); transition=0.2; transition.set_cmdline_option("bkt").set_description("Blade-keyhole transition width (fraction of oversampled k-space center)"); append_arg(transition,"transition"); } /////////////////////////////////////////////////////////////////////////// bool RecoBladeComb::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); TinyVector inshape=indata.shape(); TinyVector inshape3d(inshape(1), inshape(2), inshape(3)); int nblades=inshape(0); dvector angles=controller.dim_values(cycle); ODINLOG(odinlog,normalDebug) << "angles=" << angles.printbody() << STD_endl; TinyVector fov; fov=1; // fov(0)=controller.protocol().geometry.get_FOV(sliceDirection); // No regridding in line3d direction fov(1)=controller.protocol().geometry.get_FOV(phaseDirection); fov(2)=controller.protocol().geometry.get_FOV(readDirection); ODINLOG(odinlog,normalDebug) << "fov=" << fov << STD_endl; Data corrweights(nblades); // correlation weighting if (corrweight) { float os_factor=rd.coord().overSamplingFactor; ODINLOG(odinlog,normalDebug) << "os_factor=" << os_factor << STD_endl; if(os_factor<1.0) { ODINLOG(odinlog,errorLog) << "os_factor(" << os_factor << ") < 1.0" << STD_endl; return false; } // Filter for k-space center JDXfilter kernel_center; kernel_center.set_funcpars("Triangle"); // Prepare Input Data if(rd.interpolated) measlines.update(*(rd.interpolated)); // take previously interpolated coords into account ivector indexvec3d=measlines.get_indices(rd.coord()); // Use only planes actually measured ComplexData<4> infixed(inshape(0),indexvec3d.size(),inshape(2),inshape(3)); for(int i = 0; i < indexvec3d.size(); i++) { int iphase3d = indexvec3d[i]; infixed(all,i,all,all) = indata(all,iphase3d,all,all); } // Grid blades BladeGrid bg; bg.init(inshape3d,fov,controller.image_size(),os_factor,kernel_center); ComplexData<4> bladesgrid_kspace = bg(infixed,angles); // FFT TinyVector gridshape(bladesgrid_kspace.shape()); Data bladesgrid(gridshape(0),gridshape(1),gridshape(2),gridshape(3)); TinyVector fftdims(false,false,true,true); bladesgrid_kspace.partial_fft(fftdims,true); bladesgrid = cabs(bladesgrid_kspace); //bladesgrid.autowrite("grid-blades.nii"); // Calculate correlation coefficient for all blades and planes corrweights = 0.0; for (int iphase3d = 0; iphase3d < gridshape(1); iphase3d++) { // Merge all blades Data bladesmean(gridshape(2),gridshape(3)); bladesmean = 0.0; for (int iblade = 0; iblade < nblades; iblade++) { bladesmean += bladesgrid(iblade,iphase3d,all,all); } bladesmean /= nblades; //bladesmean.autowrite("grid-blades-mean.nii"); // Calculate correlation coefficient for all blades for (int iblade = 0; iblade < nblades; iblade++) { correlationResult cr = correlation(bladesmean,bladesgrid(iblade,iphase3d,all,all)); corrweights(iblade) += cr.r; } } corrweights /= gridshape(1); ODINLOG(odinlog,normalDebug) << "corrweights=" << corrweights << STD_endl; } else corrweights = 1.0; int ikey=0; // the index for the blade filling the center of k-space in keyhole mode if(keyhole) { int irep=rd.coord().index[repetition]; ikey=(irep+nblades/2)%nblades; ODINLOG(odinlog,normalDebug) << "ikey(" << irep << ")=" << ikey << STD_endl; } KspaceTraj* trajptr=0; trajmutex.lock(); if(trajmap.find(ikey)==trajmap.end()) { trajptr=new KspaceTraj; trajmap[ikey]=trajptr; int npts=inshape(0)*inshape(2)*inshape(3); // cycles x 2D plane trajptr->resize(1,npts); TinyVector kspace_center=inshape3d/2; // correct index of center: odd N -> N/2 / even N -> (N-1)/2 ODINLOG(odinlog,normalDebug) << "kspace_center=" << kspace_center << STD_endl; TinyVector kmax=inshape3d*2.0*PII/fov; kmax(2)/=rd.coord().overSamplingFactor; float kcent_radius=0.5*STD_min(kmax(1),kmax(2)); TinyVector findex; TinyVector kcoord; TinyVector kcoord_shift; TinyVector kcoord_rot; int itraj=0; for(int iblade=0; iblade inplaneindex(0, iphase, iread); double angle_rad=-angles[iblade]; // Reverse blade rotation findex=(inplaneindex-kspace_center)/inshape3d; kcoord=findex*kmax; kcoord_shift=kcoord; float si=sin(angle_rad); float co=cos(angle_rad); /*if (shiftPhaseCorr) { kcoord_shift(1) += koffset(iblade,0) / inshape3d(1) * kmax(1); kcoord_shift(2) += koffset(iblade,1) / inshape3d(2) * kmax(2); }*/ kcoord_rot(0)=0.0; kcoord_rot(1)=co*kcoord_shift(1)-si*kcoord_shift(2); kcoord_rot(2)=si*kcoord_shift(1)+co*kcoord_shift(2); (*trajptr)(0,itraj).coord=kcoord_rot; float weight = corrweights(iblade); float kcoord_temp; if (kmax(1) > kmax(2)) kcoord_temp = kcoord(2); // select the smaller(=y) coordinate else kcoord_temp = kcoord(1); float y = secureDivision(abs(kcoord_temp),kcent_radius); if (y > 1) // ouside of the blade weight = 0.0; else weight *= kspaceweight_filter.calculate(kspaceweight_width * y); if(keyhole && iblade!=ikey) { float relradius=secureDivision(norm(kcoord_rot(1),kcoord_rot(2)),kcent_radius); float plateau=1.0-transition; float r=1.0-secureDivision(relradius-plateau,transition); if(r>=0.0 && r<=1.0) weight*=keyhole_filter.calculate(r); if(r>1.0) weight=0.0; } (*trajptr)(0,itraj).weight=weight; itraj++; } } } } else { trajptr=trajmap[ikey]; } trajmutex.unlock(); if(rd.interpolated) measlines.update(*(rd.interpolated)); // take previously interpolated coords into account ivector indexvec3d=measlines.get_indices(rd.coord()); // Use only planes actually measured // feed each 3d-phase encoded k-space plane separately into rest of pipeline for(int i=0; i& outdata=rdcopy.data(Rank<1>()); ComplexData<3> indata2d; indata2d.reference(indata(all,iphase3d,all,all)); indata2d.convert_to(outdata); if(!execute_next_step(rdcopy,controller)) return false; } return true; } /////////////////////////////////////////////////////////////////////////// bool RecoBladeComb::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(!measlines.init(context.coord, context.controller)) return false; } return RecoStep::query(context); } /////////////////////////////////////////////////////////////////////////// RecoBladeComb::~RecoBladeComb() { Log odinlog("","~RecoBladeComb"); for(STD_map::iterator it=trajmap.begin(); it!=trajmap.end(); ++it) { delete it->second; } } odin-1.8.5/odinreco/dump.cpp0000644000175000017500000000315711322062351012653 00000000000000#include "dump.h" #include "store.h" #include "data.h" template bool dump_recodata(const ComplexData& indata, const STD_string& filename, RecoData::dataMode mode) { if(indata.size()) { Data magn(indata.shape()); if (mode==RecoData::real_data || mode==RecoData::weighted_real_data) magn = creal(indata); else magn = cabs(indata); magn.autowrite(filename); return true; } return false; } void RecoDump::init() { Log odinlog(c_label(),"init"); prefix=STD_string(".")+SEPARATOR_STR+"dump"; prefix.set_cmdline_option("dp").set_description("Prefix of dump files"); append_arg(prefix,"prefix"); format=RecoStore::default_format(); format.set_cmdline_option("df").set_description("Output format (file extension) of dump files"); append_arg(format,"format"); } bool RecoDump::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); STD_string filename=prefix; STD_string coordstr=rd.coord().print(RecoIndex::filename); if(coordstr!="") filename+="_"+coordstr; filename+="."+format; ODINLOG(odinlog,normalDebug) << "filename=" << filename << STD_endl; bool dumped= // stop if data with highest dim written dump_recodata(rd.data(Rank<5>()),filename,rd.mode) || dump_recodata(rd.data(Rank<4>()),filename,rd.mode) || dump_recodata(rd.data(Rank<3>()),filename,rd.mode) || dump_recodata(rd.data(Rank<2>()),filename,rd.mode) || dump_recodata(rd.data(Rank<1>()),filename,rd.mode); ODINLOG(odinlog,normalDebug) << "dumped=" << dumped << STD_endl; return execute_next_step(rd,controller); } odin-1.8.5/odinreco/bladegrid.cpp0000644000175000017500000001043611363773557013647 00000000000000#include "bladegrid.h" #include bool BladeGrid::init(const TinyVector& inshape, const TinyVector fov, const TinyVector image_size, const float os_factor, const JDXfilter& filterkernel) { Log odinlog("BladeGrid","init"); Range all=Range::all(); // Initialize important dimensions TinyVector inshape_no(inshape(0), inshape(1), int(inshape(2)/os_factor+0.5)); // without oversampling ODINLOG(odinlog,normalDebug) << "inshape_no=" << inshape_no << STD_endl; int center_diameter=STD_min(inshape_no(1),inshape_no(2)); // Size of the fully oversampled center of k-space int kspace_diameter=STD_max(inshape_no(1),inshape_no(2)); // The size of the overall k-space ODINLOG(odinlog,normalDebug) << "center_diameter/kspace_diameter=" << center_diameter << "/" << kspace_diameter << STD_endl; TinyVector centshape(inshape(0), center_diameter, int(center_diameter*os_factor+0.5)); if(inshape(1)%2 != centshape(1)%2) centshape(1)++; // for correct placing at center if(inshape(2)%2 != centshape(2)%2) centshape(2)++; // for correct placing at center ODINLOG(odinlog,normalDebug) << "centshape=" << centshape << STD_endl; // prepare filtermask TinyVector inshape2d(inshape(1),inshape(2)); filtermask_center.resize(inshape2d); filtermask_center = 0.0; if (filterkernel.get_function_name() == "NoFilter") { // NoFilter means entire blade filtermask_center = 1.0; } else { TinyVector bounds(inshape2d); bounds(0) = centshape(1); bounds(1) = centshape(2); for(int j=0; j BladeGrid::operator () (const ComplexData<4>& src, const dvector& angles) const { Log odinlog("BladeGrid","()"); Range all=Range::all(); JDXfilter gridkernel; gridkernel.set_function("Gauss"); TinyVector inshape4d(src.shape()); TinyVector inshape3d(inshape4d(1),inshape4d(2),inshape4d(3)); TinyVector inshape2d(inshape4d(2),inshape4d(3)); int nBlades = inshape4d(0); int npts3d = product(inshape3d); TinyVector kspace_center = inshape2d/2; // correct index of center: odd N -> N/2 / even N -> (N-1)/2 float dk = max(dstextent/dstshape); float kwidth = 3*dk; ComplexData<4> images(nBlades,inshape3d(0),dstshape(0),dstshape(1)); ODINLOG(odinlog,normalDebug) << "dstshape/dstextent/dk/kwidth=" << dstshape << "/" << dstextent << "/" << dk << "/" << kwidth << STD_endl; for (int iblade = 0; iblade < nBlades; iblade++) { // Prepare Gridder TinyVector findex; TinyVector kcoord; TinyVector kcoord_rot; STD_vector > src_coords(npts3d); int n = 0; for (int iphase = 0; iphase < inshape3d(1); iphase++) { for (int iread = 0; iread < inshape3d(2); iread++) { TinyVector inplaneindex(iphase, iread); findex = (inplaneindex - kspace_center) / inshape2d; kcoord = findex*kmax; float si = sin(-angles[iblade]); float co = cos(-angles[iblade]); kcoord_rot(0)=co*kcoord(0)-si*kcoord(1); kcoord_rot(1)=si*kcoord(0)+co*kcoord(1); src_coords[n].coord(0) = kcoord_rot(0); src_coords[n].coord(1) = kcoord_rot(1); src_coords[n].weight = 1.0; n++; } } Gridding gridder; gridder.init(dstshape, dstextent, src_coords, gridkernel, kwidth); for (int islice = 0; islice < inshape3d(0); islice++) { ComplexData<2> image(dstshape); ComplexData<2> blade(inshape2d); blade = src(iblade,islice,all,all) * filtermask_center; image = gridder(blade); images(iblade,islice,all,all) = image; } } return images; }odin-1.8.5/odinreco/pilot.cpp0000644000175000017500000000617411322062351013037 00000000000000#include "pilot.h" #include "data.h" #include "controller.h" /////////////////////////////////////////////////////////////////////////// void RecoPilot::init() { slicedist=0.0; slicedist.set_description("Inter-slice distance"); append_arg(slicedist,"slicedist"); } /////////////////////////////////////////////////////////////////////////// void RecoPilot::transpose_inplane(ComplexData<5>& data, Geometry& geo, bool reverse_read, bool reverse_phase) { geo.transpose_inplane(reverse_read,reverse_phase); if(reverse_read) data.reverseSelf(4); if(reverse_phase) data.reverseSelf(3); data.transposeSelf(0,1,2,4,3); data.reference(data.copy()); } /////////////////////////////////////////////////////////////////////////// bool RecoPilot::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); ComplexData<4>& indata=rd.data(Rank<4>()); TinyVector inshape=indata.shape(); TinyVector outshape(1, 1, inshape(1), inshape(2), inshape(3)); // slice size will be adjusted later ODINLOG(odinlog,normalDebug) << "inshape/outshape=" << inshape << "/" << outshape << STD_endl; dvector orientations=controller.dim_values(userdef); int nimages=orientations.size(); if(nimages!=inshape(0)) { ODINLOG(odinlog,errorLog) << "size mismatch" << STD_endl; return false; } STD_map slicecount; for(int i=0; i& dataref=data[ior].data(Rank<5>()); outshape(1)=slicecount[sliceOrientation(ior)]; dataref.resize(outshape); // Modify protocol prot[ior]=controller.protocol(); Geometry& geo=prot[ior].geometry; geo.set_orientation(sliceOrientation(ior)); geo.set_nSlices(outshape(1)); geo.set_sliceDistance(slicedist); data[ior].override_protocol=&(prot[ior]); // modify coordinate data[ior].coord().index[userdef].set_numof(n_orientations); data[ior].coord().index[userdef]=ior; } // fill data UInt index[n_orientations]; for(int i=0; i& outdata=data[ior].data(Rank<5>()); outdata(0,int(index[ior]),all,all,all)=indata(i,all,all,all); index[ior]++; } STD_string series; int number; controller.protocol().study.get_Series(series, number); // transpose and feed rest of pipeline for(unsigned int ior=0; ior()), prot[ior].geometry, true,false);} if(ior==coronal) {seriesname=series+"_Coronal"; transpose_inplane(data[ior].data(Rank<5>()), prot[ior].geometry, true,true);} if(ior==axial) {seriesname=series+"_Axial";} prot[ior].study.set_Series(seriesname,number); if(!execute_next_step(data[ior],controller)) return false; } return true; } odin-1.8.5/odinreco/multifreq.cpp0000644000175000017500000002057411725203122013720 00000000000000#include "multifreq.h" #include "data.h" #include "controller.h" static const char* posted_freqs_str="multifreqs"; ///////////////////////////////////////////////////////////////////////////////////////////////////////// void RecoMultiFreq::init() { max_numof_freq=256; max_numof_freq.set_cmdline_option("mf").set_description("Maximum number of frequencies for multi-frequency reconstruction"); append_arg(max_numof_freq,"max_numof_freq"); } bool RecoMultiFreq::get_freqs(Data& result, const RecoCoord& fmapcoord, double adcdur, RecoController& controller) { Log odinlog(c_label(),"get_freqs"); bool calc_freqs=true; freqmutex.lock(); FreqMap::const_iterator it=freqmap.find(fmapcoord); if(it!=freqmap.end()) { result.reference(it->second.copy()); // deep copy for thread-safe access when using freqs calc_freqs=false; } freqmutex.unlock(); if(calc_freqs) { if(!controller.data_announced(posted_fmap_str)) { ODINLOG(odinlog,errorLog) << "fieldmap not available" << STD_endl; return false; } RecoData rdfieldmap(fmapcoord); if(!controller.inquire_data(posted_fmap_str, rdfieldmap)) return false; Data fieldmap(creal(rdfieldmap.data(Rank<3>()))); float minfreq=min(fieldmap); float maxfreq=max(fieldmap); float deltafreq=fabs(maxfreq-minfreq); stampmutex.lock(); double echoTrainDur=echoTimeStamps.maxvalue()-echoTimeStamps.minvalue(); stampmutex.unlock(); echoTrainDur+=adcdur; ODINLOG(odinlog,normalDebug) << "deltafreq/adcdur/echoTrainDur=" << deltafreq << "/" << adcdur << "/" << echoTrainDur << STD_endl; int nFreq=int(4.0*deltafreq*echoTrainDur/PII+0.5); // According to Man et al., MRM 37:785(1997) nFreq*=2; // slightly more to avoid Moire-type artifacts if(nFreq>max_numof_freq) nFreq=max_numof_freq; if(nFreq<=0) nFreq=1; fvector fv(nFreq); if(nFreq>1) fv.fill_linear(minfreq,maxfreq); else fv=0.0; // use zero frequency if multi-frequency interpolation is disabled result=fv; ODINLOG(odinlog,normalDebug) << "nFreq/result=" << nFreq << "/" << fv.printbody() << STD_endl; MutexLock lock(freqmutex); if(freqmap.find(fmapcoord)==freqmap.end()) { // Do this only once, otherwise post_data() will throw an error freqmap[fmapcoord].reference(result); // Cache result // post freqs to blackboard for later use by freqcomb RecoData rdposted(fmapcoord); rdposted.data(Rank<1>()).resize(nFreq); rdposted.data(Rank<1>())=float2real(result); controller.post_data(posted_freqs_str, rdposted); } } return true; } bool RecoMultiFreq::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); ComplexData<1>& indata=rd.data(Rank<1>()); unsigned int adcSize=indata.extent(0); double dt=rd.coord().dwellTime; // coord for indexing field maps RecoCoord fmapcoord=rd.coord(); RecoFieldMapUser::modify4fieldmap(fmapcoord); Data freqs; if(!get_freqs(freqs,fmapcoord,double(adcSize)*dt,controller)) return false; double reftime=0.0; // The absolute time within an echo train unsigned int iecho=rd.coord().echopos; unsigned int iepi=rd.coord().echotrain; stampmutex.lock(); if(echoTimeStamps.size(0)<2) iepi=0; // do not throw error if EPI start times are not provided (e.g. TWIX data), use zero instead if(iepi& modulated=rdcopy.data(Rank<1>()); modulated.resize(adcSize); rdcopy.coord().index[freq].set_numof(nfreq); rdcopy.coord().index[freq]=ifreq; for(unsigned int isample=0; isample odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { dvector echostart=context.controller.dim_values(echo); if(!echostart.size()) { echostart.resize(1); echostart=0.0; } ODINLOG(odinlog,normalDebug) << "echostart=" << echostart << STD_endl; dvector epistart=context.controller.dim_values(epi); if(!epistart.size()) { epistart.resize(1); epistart=0.0; } ODINLOG(odinlog,normalDebug) << "epistart=" << epistart << STD_endl; echoTimeStamps.redim(epistart.size(), echostart.size()); for(unsigned int iepi=0; iepi& cfreqs=rdfreqs.data(Rank<1>()); result.resize(cfreqs.shape()); result=creal(cfreqs); return true; } bool RecoFreqComb::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); const ComplexData<4>& allfreq=rd.data(Rank<4>()); int nfreq=allfreq.extent(0); TinyVector outshape(allfreq.extent(1), allfreq.extent(2), allfreq.extent(3)); ComplexData<3>& outdata=rd.data(Rank<3>()); outdata.resize(outshape); RecoCoord fmapcoord=rd.coord(); RecoFieldMapUser::modify4fieldmap(fmapcoord); Data freqs; if(!get_freqs(freqs, fmapcoord, controller)) return false; if(nfreq!=freqs.size()) { ODINLOG(odinlog,errorLog) << "nfreq=" << nfreq << "!=" << freqs.size() << STD_endl; return false; } Data fieldmap; if(rd.coord().index[cycle].get_mode()==RecoIndex::separate) { // for separate PROPELLER blades fmapcoord.index[cycle].set_mode(RecoIndex::separate); fmapcoord.index[cycle]=rd.coord().index[cycle]; } if(!get_fmap(fieldmap, outshape, fmapcoord, controller)) return false; // fieldmap.autowrite("fieldmap_"+fmapcoord.print(RecoIndex::filename)+".nii"); // Combine frequency values if(nfreq>1) { outdata=STD_complex(0.0); double deltafreq=fabs(freqs(1)-freqs(0)); for(int iphase3d=0; iphase3d Pixel is zero in reconstructed image float norm=0.0; STD_complex pixsum(0.0); for(int ifreq=0; ifreq odinlog(c_label(),"process"); int oldnrep=rd.coord().numof(repetition); int ncycle=rd.coord().numof(cycle); int newnrep=(oldnrep-1)*ncycle+1; ODINLOG(odinlog,normalDebug) << "oldnrep/ncycle/newnrep=" << oldnrep << "/" << ncycle << "/" << newnrep << STD_endl; rd.coord().index[repetition].set_numof(newnrep); int icycle=rd.coord().index[cycle]; int ioldrep=rd.coord().index[repetition]; int index=ioldrep*ncycle+icycle; ODINLOG(odinlog,normalDebug) << "index=" << index << STD_endl; ivector inewreplist; for(int i=0; i=0 && inewrep static const char* posted_phasemap_label="phasemap"; bool RecoPhaseMap::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); modify4blackboard(rd.coord()); ComplexData<2>& data=rd.data(Rank<2>()); TinyVector shape(data.shape()); int nechoes=shape(0); int nread=shape(1); ODINLOG(odinlog,normalDebug) << "PhaseMap" << "(" << rd.coord().print() << ")/" << shape << " complete" << STD_endl; // FFT in read direction data.partial_fft(TinyVector(false,true)); ComplexData<2> phasemap(shape); if(odd_even_echoes) { // phase correction for EPI // Calculate phase-difference for each odd and even pair of echoes Data phasediff(nechoes/2, nread); Data sigma(nechoes/2, nread); // Error for fit for(int iecho=0; iecho(expc(float2imag(phasediff))).phasemap(); // Linear fit to phase, weighted by signal magnitude for each odd-even-echo pair LinearFunction linf; Data slope(nechoes/2); Data fiterr(nechoes/2); Data offset(nechoes/2); Data phasediff_oneline(nread); for(int iecho=0; iecho slope_fit(nechoes/2); Data offset_fit(nechoes/2); for(int iecho=0; iecho oneline(nread); for(int iecho=0; iecho(cabs(oneline)), 1, 3.0))); } } // Post data for each echo separately on blackboard RecoData one_echo_phasemap; one_echo_phasemap.data(Rank<1>()).resize(nread); one_echo_phasemap.coord()=rd.coord(); for(int i=0; i())=phasemap(i,all); one_echo_phasemap.coord().index[echo]=i; controller.post_data(posted_phasemap_label, one_echo_phasemap); } // For debugging, apply phase correction to template data // and apss it to next functor data=data/phasemap; data.partial_fft(TinyVector(false,true),false); return execute_next_step(rd,controller); } ////////////////////////////////////////////////////////////// bool RecoPhaseMap::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { context.controller.announce_data(posted_phasemap_label); ODINLOG(odinlog,normalDebug) << "announced " << posted_phasemap_label << STD_endl; RecoCoord coord4count=context.coord; modify(coord4count); const CoordCountMap* countmap=context.controller.create_count_map(coord4count); if(!countmap) return false; odd_even_echoes=false; for(CoordCountMap::const_iterator it=countmap->begin(); it!=countmap->end(); ++it) { if(it->first.flags&recoReflectBit) { odd_even_echoes=true; break; } } ODINLOG(odinlog,normalDebug) << "odd_even_echoes=" << odd_even_echoes << STD_endl; } return RecoStep::query(context); } ////////////////////////////////////////////////////////////// bool RecoPhaseCorr::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); if(!controller.data_announced(posted_phasemap_label)) { ODINLOG(odinlog,errorLog) << posted_phasemap_label << " not available" << STD_endl; return false; } RecoData one_echo_phasemap; one_echo_phasemap.coord()=rd.coord(); RecoPhaseMap::modify4blackboard(one_echo_phasemap.coord()); // override (zero) echo/epi index for phasemap retrieval one_echo_phasemap.coord().index[echo]=rd.coord().echopos; one_echo_phasemap.coord().index[epi]=rd.coord().echotrain; if(!controller.inquire_data(posted_phasemap_label, one_echo_phasemap)) return false; ComplexData<1>& pmap=one_echo_phasemap.data(Rank<1>()); ComplexData<1>& adc=rd.data(Rank<1>()); if(pmap.size()!=adc.size()) { ODINLOG(odinlog,errorLog) << "Size mismatch: " << pmap.size() << " != " << adc.size() << STD_endl; return false; } // FFT forward adc.fft(true); // Phase correction Range all=Range::all(); adc(all)=adc(all)/pmap(all); // Blitz throws an error if arrays are used directly // FFT back adc.fft(false); return execute_next_step(rd,controller); } odin-1.8.5/odinreco/channel.cpp0000644000175000017500000000616111665172216013330 00000000000000#include "channel.h" #include "data.h" void RecoChannelSum::init() { Log odinlog(c_label(),"init"); phasecomb=false; phasecomb.set_cmdline_option("pc").set_description("Combine phase of channels using a phase correction"); append_arg(phasecomb,"phasecomb"); magnexp=0.0; magnexp.set_cmdline_option("pe").set_description("Exponent for magnitude weighting when calculating combined phase of all channels"); append_arg(magnexp,"magnexp"); } bool RecoChannelSum::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); TinyVector inshape(rd.data(Rank<4>()).shape()); TinyVector outshape(inshape(1), inshape(2), inshape(3)); ODINLOG(odinlog,normalDebug) << "inshape/outshape=" << inshape << "/" << outshape << STD_endl; ComplexData<4>& indata=rd.data(Rank<4>()); int nchan=indata.extent(0); ODINLOG(odinlog,normalDebug) << "nchan=" << nchan << STD_endl; ComplexData<3>& outdata=rd.data(Rank<3>()); outdata.resize(outshape); if(rd.mode==RecoData::real_data || rd.mode==RecoData::weighted_real_data) { outdata=STD_complex(0.0); for(int i=0; i index=outdata.create_index(i); float valsum=0.0; float relsum=0.0; for(int i=0; i mag(outshape); mag=0.0; Data magall(cabs(indata)); for(int i=0; i; template class RecoGrappaWeights >; template class RecoGrappaWeights; template class RecoGrappaWeights >; template class RecoGrappa; template class RecoGrappa;