odin-2.0.3/0000755000000000000000000000000013010330627007407 500000000000000odin-2.0.3/odinreco/0000755000000000000000000000000013010330626011210 500000000000000odin-2.0.3/odinreco/circmask.cpp0000644000000000000000000000133212732216523013440 00000000000000#include "circmask.h" #include "data.h" bool RecoCircMask::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); 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-2.0.3/odinreco/blackboard.h0000644000000000000000000000647712732216523013414 00000000000000/*************************************************************************** blackboard.h - description ------------------- begin : Mon Jan 24 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRstring postlabel; }; #endif odin-2.0.3/odinreco/phasecorr.h0000644000000000000000000000542412732216523013305 00000000000000/*************************************************************************** phasecorr.h - description ------------------- begin : Mon Jan 24 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/fieldmap.h0000644000000000000000000000411412732216523013073 00000000000000/*************************************************************************** fieldmap.h - description ------------------- begin : Mon Feb 25 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/reader_custom.h0000644000000000000000000000453412732216523014154 00000000000000/*************************************************************************** reader_custom.h - description ------------------- begin : Thu Oct 18 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(LDRblock&) {} 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-2.0.3/odinreco/Makefile.in0000644000000000000000000010441713010312546013205 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 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 halffour.h halffour.cpp homodyne.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 reader_ismrmrd.h reader_ismrmrd.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@ halffour.$(OBJEXT) homodyne.$(OBJEXT) \ @ONLY_LIBS_FALSE@ index.$(OBJEXT) messer.$(OBJEXT) \ @ONLY_LIBS_FALSE@ measindex.$(OBJEXT) mip.$(OBJEXT) \ @ONLY_LIBS_FALSE@ multifreq.$(OBJEXT) offset.$(OBJEXT) \ @ONLY_LIBS_FALSE@ oversampling.$(OBJEXT) phasecorr.$(OBJEXT) \ @ONLY_LIBS_FALSE@ phasecourse.$(OBJEXT) \ @ONLY_LIBS_FALSE@ qualitycontrol.$(OBJEXT) pilot.$(OBJEXT) \ @ONLY_LIBS_FALSE@ reader.$(OBJEXT) reader_odin.$(OBJEXT) \ @ONLY_LIBS_FALSE@ reader_custom.$(OBJEXT) \ @ONLY_LIBS_FALSE@ reader_ismrmrd.$(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) am__DEPENDENCIES_1 = @ONLY_LIBS_FALSE@odinreco_DEPENDENCIES = ../odindata/libodindata.la \ @ONLY_LIBS_FALSE@ $(am__DEPENDENCIES_1) \ @ONLY_LIBS_FALSE@ ../odinpara/libodinpara.la \ @ONLY_LIBS_FALSE@ ../tjutils/libtjutils.la \ @ONLY_LIBS_FALSE@ $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = 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) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(odinreco_SOURCES) DIST_SOURCES = $(am__odinreco_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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@AM_CPPFLAGS = $(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@halffour.h halffour.cpp \ @ONLY_LIBS_FALSE@homodyne.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@reader_ismrmrd.h reader_ismrmrd.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 $(DATALIBS) ../odinpara/libodinpara.la ../tjutils/libtjutils.la $(BASELIBS) # 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 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) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ 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) $(EXTRA_odinreco_DEPENDENCIES) @rm -f odinreco$(EXEEXT) $(AM_V_CXXLD)$(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)/halffour.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_ismrmrd.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@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | 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,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ 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-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ 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" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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 $(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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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 TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am 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 tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-man \ uninstall-man1 .PRECIOUS: Makefile # 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: @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-2.0.3/odinreco/sum.cpp0000644000000000000000000000066112732216523012454 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-2.0.3/odinreco/blade.h0000644000000000000000000001023212732216523012357 00000000000000/*************************************************************************** blade.h - description ------------------- begin : Thu Mar 15 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOBLADE_H #define RECOBLADE_H #include "step.h" #include "measindex.h" class RecoBladeGrid : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "gridblade";} STD_string description() const {return "grid kspace center of single blades";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,cycle,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoBladeGrid;} void init(); LDRbool fft; LDRfilter filtermask; // Phase-encoding lines actually measured RecoMeasIndex > measlines; }; ////////////////////////////////////////////////////////////// class RecoCycleRot : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "cyclerot";} STD_string description() const {return "In-plane rotation according to cycle index";} 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 RecoCycleRot;} void init() {} }; ////////////////////////////////////////////////////////////// class RecoBladeCorr : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "bladecorr";} STD_string description() const {return "Pre-processing of PROPELLER blades: phase correction";} 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 RecoBladeCorr;} void init(); LDRfilter phasecorr_filter; LDRfloat phasecorr_width; }; /////////////////////////////////////////////////////////////////////// class RecoBladeComb : public RecoStep { public: ~RecoBladeComb(); private: // implementing virtual functions of RecoStep STD_string label() const {return "bladecomb";} STD_string description() const {return "Pre-processing of PROPELLER blades: coordinate rotation for gridding";} bool process(RecoData& rd, RecoController& controller); RecoCoord input_coord() const {return RecoCoord::coord_with_mode(RecoIndex::collected,cycle,line3d,line,readout);} void modify_coord(RecoCoord& coord) const {coord.set_mode(RecoIndex::separate,cycle,line3d,line);} bool query(RecoQueryContext& context); RecoStep* allocate() const {return new RecoBladeComb;} void init(); LDRbool keyhole; LDRbool corrweight; LDRfilter keyhole_filter; LDRfilter kspaceweight_filter; LDRfloat transition; LDRfloat kspaceweight_width; STD_map trajmap; // caching trajectories, one for each keyhole index Mutex trajmutex; // Phase-encoding lines actually measured RecoMeasIndex > measlines; }; #endif odin-2.0.3/odinreco/channel.cpp0000644000000000000000000000621612732216523013262 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(unsigned int i=0; i index=outdata.create_index(i); float valsum=0.0; float relsum=0.0; for(int ichan=0; ichan mag(outshape); mag=0.0; Data magall(cabs(indata)); for(int i=0; i bool BladeGrid::init(const TinyVector& inshape, const TinyVector fov, const TinyVector image_size, const float os_factor, const LDRfilter& filterkernel) { Log odinlog("BladeGrid","init"); // 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(); LDRfilter 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-2.0.3/odinreco/t1fit.cpp0000644000000000000000000001505612732216523012703 00000000000000#include "t1fit.h" #include "data.h" #include "controller.h" #include /////////////////////////////////////////////////////////////////////////// // 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; FunctionFitDerivative irfit; if(!irfit.init(irfunc,ntis)) return false; FunctionFitDerivative irabsfit; if(!irabsfit.init(irabsfunc,ntis)) return false; 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-2.0.3/odinreco/channel.h0000644000000000000000000000331112732216523012720 00000000000000/*************************************************************************** channel.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRbool phasecomb; LDRfloat magnexp; }; #endif odin-2.0.3/odinreco/index.h0000644000000000000000000002754112732216523012432 00000000000000/*************************************************************************** index.h - description ------------------- begin : Mon Jan 27 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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, will be converted from 'relCenterPos' in functor 'adc_pad' */ unsigned short adcstart; /** * Last index in readout direction actually measured, will be converted from 'relCenterPos' in functor 'adc_pad' */ 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-2.0.3/odinreco/collector.cpp0000644000000000000000000001145312732216523013637 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 >; template class RecoCollector<3, RecoDim<3, line3d, line, readout>, 5, RecoDim<5, cycle, slice, echo, epi, channel>, true >; odin-2.0.3/odinreco/fft.h0000644000000000000000000000306112732216523012071 00000000000000/*************************************************************************** fft.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRbool forward; }; #endif odin-2.0.3/odinreco/splitter_code.h0000644000000000000000000000445312732216523014160 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-2.0.3/odinreco/zerofill.h0000644000000000000000000000323112732216523013137 00000000000000/*************************************************************************** zerofill.h - description ------------------- begin : Wed Oct 10 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRint minread; LDRint minphase; LDRint minslice; }; #endif odin-2.0.3/odinreco/switch.cpp0000644000000000000000000001423712732216523013155 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 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& gridpoint=(*traj)(iseg,ipt); const TinyVector& kpoint=gridpoint.coord; GriddingPoint& srccoord=srccoords[iseg*npts+ipt]; TinyVector& srcpoint=srccoord.coord; 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(unsigned 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(unsigned 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-2.0.3/odinreco/adc.cpp0000644000000000000000000001135612732216523012402 00000000000000#include "adc.h" #include "data.h" #include "controller.h" bool RecoAdcReflect::process(RecoData& rd, RecoController& controller) { if(rd.coord().flags&recoReflectBit) { // reverseSelf will modify ascending order of the Blitz array which will screw up the rest of the reco so we will apply it to a local copy ComplexData<1>& 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(int(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"); 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-2.0.3/odinreco/fft.cpp0000644000000000000000000000056112732216523012426 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-2.0.3/odinreco/dti.cpp0000644000000000000000000000131712732216523012427 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); LDRtriple 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-2.0.3/odinreco/grappa.cpp0000644000000000000000000000066312732216523013124 00000000000000#include "grappa.h" #include "grappa_code.h" // Instantiations used in step.cpp template class RecoGrappaWeights; template class RecoGrappaWeights >; template class RecoGrappaWeights; template class RecoGrappaWeights >; template class RecoGrappa; template class RecoGrappa; odin-2.0.3/odinreco/grappa.h0000644000000000000000000001045112732216523012565 00000000000000/*************************************************************************** grappa.h - description ------------------- begin : Fri Feb 2 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRint reduction_factor; LDRint neighbours_read; LDRint neighbours_phase; LDRfloat svd_trunc; LDRfloat 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(); LDRint reduction_factor; LDRbool 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-2.0.3/odinreco/main.cpp0000644000000000000000000000627012732216523012576 00000000000000#include "controller.h" #include "reader_odin.h" #include "reader_custom.h" #include "reader_ismrmrd.h" //////////////////////////////////////////////////// // Quick hack to include reader for Twix data #ifdef IDEA_PLUGIN #include "../platforms/IDEA_n4/twix/reader_twix.cpp" #endif //////////////////////////////////////////////////// void usage(LDRblock& opts) { STD_string doctxt= "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 -f and third-party libraries available to ODIN). " "The filename of each file starts with the given output prefix. "; STD_cout << STD_endl; STD_cout << "odinreco: Automatic reconstruction for ODIN sequences" << STD_endl; STD_cout << STD_endl; STD_cout << justificate(doctxt); STD_cout << "Usage: odinreco [ options ] -r " << 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"); LDRblock opts; RecoController controller(opts); RecoReaderOdin reader_odin(opts); RecoReaderCustom reader_custom(opts); #ifdef IDEA_PLUGIN RecoReaderTwix reader_twix(opts); #endif #ifdef ISMRMRDSUPPORT RecoReaderISMRMRD reader_ismrm(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]; LDRfileName 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 #ifdef ISMRMRDSUPPORT if(input_filename.get_suffix()=="h5") reader=&reader_ismrm; #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)) { ODINLOG(odinlog,errorLog) << "reader->init(" << input_filename << ") failed" << STD_endl; return -1; } if(!controller.init(reader,opts,argc,argv)) { ODINLOG(odinlog,errorLog) << "controller.init(...) failed" << STD_endl; return -1; } if(!controller.start()) { ODINLOG(odinlog,errorLog) << "controller.start() failed" << STD_endl; return -1; } Profiler::dump_final_result(); return 0; } odin-2.0.3/odinreco/grid.h0000644000000000000000000000705712732216523012250 00000000000000/*************************************************************************** grid.h - description ------------------- begin : Wed Feb 21 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRbool deapo_shift; LDRfilter kernel; LDRfloat kernelwidth; LDRfloat gridScale; 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; public: // to accessed by RecoDeapodize static STD_string postfix() {return itos(NDim)+"d";} }; ///////////////////////////////////////////////////////////////////////////////// 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 RecoGrid::postfix();} }; ///////////////////////////////////////////////////////////////////////////////// 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-2.0.3/odinreco/messer.h0000644000000000000000000000316112732216523012611 00000000000000/*************************************************************************** messer.h - description ------------------- begin : Thu Apr 9 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/index.cpp0000644000000000000000000000211712732216523012755 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 #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"); 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(unsigned 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-2.0.3/odinreco/driftcorr.cpp0000644000000000000000000001545612732216523013656 00000000000000#include "driftcorr.h" #include "data.h" #include "controller.h" void modify4repdrift(RecoCoord& coord) { for(int idim=0; idim odinlog(c_label(),"process"); ComplexData<8>& indata=rd.data(Rank<8>()); int irep=rd.coord().index[repetition]; ODINLOG(odinlog,normalDebug) << "irep=" << irep << STD_endl; // Data(cabs(indata)).autowrite("driftdata_cabs_"+itos(irep)+".nii"); // Data(phase(indata)).autowrite("driftdata_phase_"+itos(irep)+".nii"); STD_complex cplxsum=sum(indata); float cplxphase=phase(cplxsum); // ODINLOG(odinlog,infoLog) << "cabs(cplxsum)=" << cabs(cplxsum) << STD_endl; RecoCoord driftcoord=rd.coord(); modify4repdrift(driftcoord); STD_complex postval; if(irep>0) { // get data of first repetition RecoCoord repcoord(driftcoord); repcoord.index[repetition]=0; RecoData rdfirstrep(repcoord); ODINLOG(odinlog,normalDebug) << "Inquiring frequency drift of irep=0" << STD_endl; if(!controller.inquire_data(posted_repdrift_str, rdfirstrep)) return false; ODINLOG(odinlog,normalDebug) << "done" << STD_endl; if(rdfirstrep.data(Rank<1>()).size()!=1) { ODINLOG(odinlog,errorLog) << "Wrong size of 1st " << posted_repdrift_str << STD_endl; return false; } float firstrepphase=creal(rdfirstrep.data(Rank<1>())(0)); // get data of previous repetition repcoord.index[repetition]=irep-1; RecoData rdprevrep(repcoord); ODINLOG(odinlog,normalDebug) << "Inquiring frequency drift of irep-1=" << irep-1 << STD_endl; if(!controller.inquire_data(posted_repdrift_str, rdprevrep)) return false; ODINLOG(odinlog,normalDebug) << "done" << STD_endl; if(rdprevrep.data(Rank<1>()).size()!=1) { ODINLOG(odinlog,errorLog) << "Wrong size of previous " << posted_repdrift_str << STD_endl; return false; } float prevrepphase=creal(rdprevrep.data(Rank<1>())(0)); ODINLOG(odinlog,normalDebug) << "firstrepphase/prevrepphase[" << irep << "]=" << firstrepphase << "/" << prevrepphase << STD_endl; // unwrap phase float prevabs=fabs(prevrepphase); int prevmod=0; if(prevabs>PII) { prevmod=int((prevabs-PII)/(2.0*PII))+1; if(prevrepphase<0.0) prevmod=-prevmod; } cplxphase+=prevmod*2.0*PII; ODINLOG(odinlog,normalDebug) << "prevmod[" << irep << "]=" << prevmod << STD_endl; float diff=cplxphase-prevrepphase; if(diff>PII) cplxphase-=2.0*PII; if(diff<-PII) cplxphase+=2.0*PII; float cplxphase_zerointercept=cplxphase-firstrepphase; float tedrift; if(driftcalcTE>0.0) tedrift=driftcalcTE; else tedrift=controller.protocol().seqpars.get_EchoTime(); ODINLOG(odinlog,normalDebug) << "tedrift=" << tedrift << STD_endl; float driftfreq=secureDivision(cplxphase_zerointercept,tedrift); postval=STD_complex(cplxphase, driftfreq); // store current phase and field drift } else { postval=STD_complex(cplxphase, 0); // store initial phase } ODINLOG(odinlog,normalDebug) << "postval[" << irep << "]=" << postval << STD_endl; // post phase to blackboard for later use RecoData rdposted(driftcoord); rdposted.data(Rank<1>()).resize(1); rdposted.data(Rank<1>())(0)=postval; ODINLOG(odinlog,normalDebug) << "Posting frequency drift of irep=" << irep << STD_endl; controller.post_data(posted_repdrift_str, rdposted); return execute_next_step(rd,controller); } bool RecoDriftCalc::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { context.controller.announce_data(posted_repdrift_str); } if(context.mode==RecoQueryContext::finalize) { int nrep=context.coord.index[repetition].get_numof(); ODINLOG(odinlog,normalDebug) << "nrep=" << nrep << STD_endl; if(nrep>1 && driftcalcFile!="") { Data driftarr(nrep); // get data of all repetitions RecoCoord repcoord; for(int irep=0; irep()).size()!=1) { ODINLOG(odinlog,errorLog) << "Wrong size of " << posted_repdrift_str << STD_endl; return false; } driftarr(irep)=cimag(rdrep.data(Rank<1>())(0)); } driftarr.write_asc_file(driftcalcFile); } } return RecoStep::query(context); } ///////////////////////////////////////////////////////////////////////// bool RecoDriftCorr::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); int irep=rd.coord().index[repetition]; if(irep>1) { double freq=0.0; RecoCoord driftcoord=rd.coord(); modify4repdrift(driftcoord); // get data of current repetition RecoCoord repcoord(driftcoord); repcoord.index[repetition]=irep-1; // use freq from previous repetition to avoid deadlocks RecoData rddrift(repcoord); ODINLOG(odinlog,normalDebug) << "Inquiring frequency drift of irep-1=" << irep-1 << STD_endl; if(!controller.inquire_data(posted_repdrift_str, rddrift)) return false; ODINLOG(odinlog,normalDebug) << "done" << STD_endl; if(rddrift.data(Rank<1>()).size()!=1) { ODINLOG(odinlog,errorLog) << "Wrong size of current " << posted_repdrift_str << STD_endl; return false; } freq=cimag(rddrift.data(Rank<1>())(0)); if(freq) { ComplexData<1>& 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& weight); // Phase-encoding lines actually measured RecoMeasIndex > measlines; RecoMeasIndex > measlines3d; }; #endif odin-2.0.3/odinreco/store.cpp0000644000000000000000000001330112732216523012777 00000000000000#include "store.h" #include "data.h" #include "controller.h" STD_string RecoStore::default_format() { STD_string result="jdx"; #ifdef NIFTISUPPORT result="nii"; #elif defined DICOMSUPPORT result="dcm"; #endif return result; } void RecoStore::init() { Log 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-2.0.3/odinreco/phasecourse.cpp0000644000000000000000000000307412732216523014172 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-2.0.3/odinreco/zerofill.cpp0000644000000000000000000000444712732216523013504 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-2.0.3/odinreco/grid.cpp0000644000000000000000000000031012732216523012564 00000000000000#include "grid.h" #include "grid_code.h" // Instantiations used in step.cpp template class RecoGrid<1>; template class RecoGrid<2>; template class RecoDeapodize<1>; template class RecoDeapodize<2>; odin-2.0.3/odinreco/phasecourse.h0000644000000000000000000000324712732216523013641 00000000000000/*************************************************************************** phasecourse.h - description ------------------- begin : Thu May 28 2009 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/epinavcorr.h0000644000000000000000000000524612732216523013471 00000000000000/*************************************************************************** epinavcorr.h - description ------------------- begin : Fr Sep 19 2008 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 coord.set_mode(RecoIndex::ignore, line, freq); // irrelevant to EPI navigator correction coord.set_mode(RecoIndex::separate, echo); // override collected mode } 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-2.0.3/odinreco/reader_ismrmrd.h0000644000000000000000000000637712732216523014326 00000000000000/*************************************************************************** reader_ismrmrd.h - description ------------------- begin : Fri Oct 2 2015 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOREADERISMRMRD_H #define RECOREADERISMRMRD_H #include "reader.h" #ifdef ISMRMRDSUPPORT namespace ISMRMRD { class Dataset; // forward declaration class AcquisitionHeader; // forward declaration class Limit; // forward declaration } /** * @addtogroup odinreco * @{ */ /** * Raw-data reader for ISRMRM raw data, see http://ismrmrd.github.io/ */ class RecoReaderISMRMRD : public virtual RecoReaderInterface { public: RecoReaderISMRMRD(LDRblock&) : dset(0) {} ~RecoReaderISMRMRD(); 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; ISMRMRD::Dataset* dset; mutable STD_vector coord_vec_cache; // Vector to hold reco coordinates (indices) KspaceTraj kspaceTraj_cache; unsigned int ismrmrd_nacq; // number of ADCs in ISMRMRD dataset unsigned int ismrmrd_count; // counter for ADCs in ISMRMRD dataset unsigned int coord_count; // counter for pipeline ADCs // data used during reco unsigned int chancount; // counter for channels ComplexData<2> rawdata; // cache rawdata because all channels are loaded at once unsigned int pre_discard_cache; unsigned int post_discard_cache; unsigned int nsamples_raw_cache; unsigned int nchan_cache; static void print_flags(ISMRMRD::AcquisitionHeader& acqhead); static bool ignore_acq(ISMRMRD::AcquisitionHeader& acqhead); static bool pe_offset(const ISMRMRD::Limit& limit, unsigned int& offset, float& partfour_prot); }; /** @} */ #endif // ISMRMRDSUPPORT #endif odin-2.0.3/odinreco/conjphase.h0000644000000000000000000000331212732216523013263 00000000000000/*************************************************************************** conjphase.h - description ------------------- begin : Wed Jun 6 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/t1fit.h0000644000000000000000000000330712732216523012344 00000000000000/*************************************************************************** t1fit.h - description ------------------- begin : Thu Mar 15 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRstring fittype; LDRfloat masklevel; LDRfloat maxt1; }; #endif odin-2.0.3/odinreco/sum.h0000644000000000000000000000460512732216523012123 00000000000000/*************************************************************************** sum.h - description ------------------- begin : Thu Mar 8 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/controller.cpp0000644000000000000000000011151512732216523014034 00000000000000#include "controller.h" #include "data.h" #include "step.h" #include "reader.h" #include "measindex.h" #include "fieldmap.h" // for posted_fmap_str RecoController::RecoController(LDRblock& 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); dumpGrappaTemplate=false; dumpGrappaTemplate.set_cmdline_option("gt").set_description("Store GRAPPA template images"); parblock.append(dumpGrappaTemplate); disablePhaseCorr=false; disablePhaseCorr.set_cmdline_option("dt").set_description("Disable template-based phase correction"); parblock.append(disablePhaseCorr); 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); disableDriftCorr=false; disableDriftCorr.set_cmdline_option("dd").set_description("Disable field-drift correction"); parblock.append(disableDriftCorr); 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); /* driftcorrFile=""; driftcorrFile.set_cmdline_option("dcr").set_description("Load field drift from this file"); parblock.append(driftcorrFile); */ driftcorrSel=""; driftcorrSel.set_cmdline_option("dcs").set_description("Index selection string in recipe used for drift correction (space separated list of 'dim=selection', e.g. te=2)"); parblock.append(driftcorrSel); 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)) { ODINLOG(odinlog,normalDebug) << "Returning " << label << "(" << data.coord().print() << ")" << STD_endl; 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(); ODINLOG(odinlog,normalDebug) << "Returning " << label << "(" << data.coord().print() << ")" << STD_endl; 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] << "/" << args << "<" << STD_endl; ODINLOG(odinlog,normalDebug) << "functorstr=>" << functorstr << "<" << 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, bool& half_fourier) const { Log odinlog("RecoController","get_kspace_sampling_pattern"); reduction_factor=1; partial_fourier=false; half_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; float center=0.5*float(maxindex); ODINLOG(odinlog,normalDebug) << "startindex/maxindex/center[" << recoDimLabel[Dim] << "]=" << startindex << "/" << maxindex << "/" << center << STD_endl; if(fabs(float(startindex)-center)<=1.0) half_fourier=true; } } if(reduction_factor<1) reduction_factor=1; ODINLOG(odinlog,normalDebug) << "reduction_factor/partial_fourier/half_fourier[" << recoDimLabel[Dim] << "]=" << reduction_factor << "/" << partial_fourier << "/" << half_fourier << STD_endl; 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; bool half_fourier=false; if(!get_kspace_sampling_pattern(mask,reduction_factor, partial_fourier, half_fourier)) return false; unsigned int reduction_factor3d=0; bool partial_fourier3d=false; bool half_fourier3d=false; if(!get_kspace_sampling_pattern(mask,reduction_factor3d, partial_fourier3d, half_fourier3d)) return false; if(half_fourier3d) { ODINLOG(odinlog,errorLog) << "Not yet implemented: half Fourier reconstruction in 2nd phase encoding direction" << STD_endl; return false; } 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; } bool apply_driftcorr=(numof_cache[repetition]>1 && !disableDriftCorr); STD_string driftcorrstr; if(apply_driftcorr) 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]) { if(!disablePhaseCorr) 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(has_templcorr_cache[fieldmap_template] || ext_fieldmap) { if(disableMultiFreq) { corrstr+="templtype=F { }"; // throw away field map data } else { 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+")"; if(dumpGrappaTemplate) { corrstr+=" | chansplit | fft | slicecoll | image | store(grappatemplate)"; } 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) { if(has_relcenter_cache || partial_fourier3d) {fftstr="homodyne | ";} if(!has_blade) { if(half_fourier) {fftstr="halffour | fft | ";} else if(partial_fourier) {fftstr="homodyne | ";} } } 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 kspaceprep="zerofill | filter | "; if(dumpKspace) kspaceprep=""; if(numof_cache[dti]>1) pp3dpost+="dti | "; STD_string phasecoursestr; if(phaseCourse) { phasecoursestr="switch( { chanrepcoll | phasecourse | repsplit | "+ freqcomb_and_oversampling + "slicecoll | image | " + slicetimestr + "store(phasecourse) } ) | "; } STD_string driftcalcstr; if(apply_driftcorr) { // STD_string driftrecipe=averagestr + " kspace | fft | driftcoll | driftcalc"; // FFT gives better results than without STD_string driftrecipe=averagestr + " kspace | driftcoll | driftcalc"; // but not with GRAPPA ? STD_map selmap; if(!create_selection_map(driftcorrSel, selmap)) return false; if(selmap.size()) { // Apply selected dimensions to recipe recursively driftcalcstr=driftrecipe; for(STD_map::const_iterator it=selmap.begin(); it!=selmap.end(); ++ it) { driftcalcstr=STD_string("switch(")+recoDimLabel[it->first]+"="+itos(it->second)+"{"+driftcalcstr+"})"; } driftcalcstr+=" | "; } else { driftcalcstr="switch( { " + averagestr + " kspace | fft | driftcoll | driftcalc } ) | "; // using switch to branch off drift calculation pipeline } } result = driftcalcstr + 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(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::create_selection_map(const STD_string& selstr, STD_map& selmap, RecoCoord* initcoord) const { Log odinlog("RecoController","create_selection_map"); // Parse selected dimensions selmap.clear(); svector seltoks(tokens(selstr)); for(unsigned int isel=0; isel0) { (new TimeOutThread(timeout))->start(); } #endif // Parse selected dimensions RecoCoord initcoord; STD_map selmap; if(!create_selection_map(select, selmap, &initcoord)) return false; /* svector seltoks(tokens(select)); for(unsigned int isel=0; isel& 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;} ComplexData<7>& data(Rank<7>) const {return data7;} ComplexData<8>& data(Rank<8>) const {return data8;} /** * 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; mutable ComplexData<7> data7; mutable ComplexData<8> data8; }; /** @} */ #endif odin-2.0.3/odinreco/filter.h0000644000000000000000000000323212732216523012577 00000000000000/*************************************************************************** filter.h - description ------------------- begin : Fri Sep 14 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRfilter filter; LDRfloat plateau; }; #endif odin-2.0.3/odinreco/swi.h0000644000000000000000000000305312732216523012115 00000000000000/*************************************************************************** swi.h - description ------------------- begin : Fri Sep 14 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/b1fit.cpp0000644000000000000000000000631612732216523012660 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-2.0.3/odinreco/circmask.h0000644000000000000000000000310712732216523013107 00000000000000/*************************************************************************** circmask.h - description ------------------- begin : Thu Sep 3 2009 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/slicetime.h0000644000000000000000000000317312732216523013274 00000000000000/*************************************************************************** slicetime.h - description ------------------- begin : Sun Jun 3 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/slidingwindow.cpp0000644000000000000000000000213412732216523014526 00000000000000#include "slidingwindow.h" #include "data.h" bool RecoSlidingWindow::process(RecoData& rd, RecoController& controller) { Log 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 odinlog(c_label(),"process"); 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-2.0.3/odinreco/epinavcorr.cpp0000644000000000000000000001035312732216523014017 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-2.0.3/odinreco/reader_custom.cpp0000644000000000000000000001205112732216523014500 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, 2000.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) 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 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.0; //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-2.0.3/odinreco/measindex.cpp0000644000000000000000000000003012732216523013613 00000000000000#include "measindex.h" odin-2.0.3/odinreco/pilot.h0000644000000000000000000000342612732216523012446 00000000000000/*************************************************************************** pilot.h - description ------------------- begin : Tue Mar 14 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOPILOT_H #define RECOPILOT_H #include "step.h" class RecoPilot : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "pilot";} STD_string description() const {return "Modify geometry for pilot output";} 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).set_mode(RecoIndex::collected,repetition,slice);} RecoStep* allocate() const {return new RecoPilot;} void init(); void transpose_inplane(ComplexData<5>& data, Geometry& geo, bool reverse_read, bool reverse_phase); LDRfloat slicedist; }; #endif odin-2.0.3/odinreco/collector.h0000644000000000000000000000755512732216523013314 00000000000000/*************************************************************************** collector.h - description ------------------- begin : Sun Jan 14 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/pilot.cpp0000644000000000000000000000617412732216523013004 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-2.0.3/odinreco/b1fit.h0000644000000000000000000000334312732216523012322 00000000000000/*************************************************************************** b1fit.h - description ------------------- begin : Tue Oct 16 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/Makefile.am0000644000000000000000000000705412732216523013203 00000000000000if ONLY_LIBS else AM_CPPFLAGS = $(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 \ halffour.h halffour.cpp \ homodyne.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 \ reader_ismrmrd.h reader_ismrmrd.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 $(DATALIBS) ../odinpara/libodinpara.la ../tjutils/libtjutils.la $(BASELIBS) # 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: 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-2.0.3/odinreco/fmri.cpp0000644000000000000000000000500212732216523012577 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-2.0.3/odinreco/bladegrid.h0000644000000000000000000000310612732216523013227 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 LDRfilter& filterkernel); ComplexData<4> operator () (const ComplexData<4>& src, const dvector& angles) const; private: Data filtermask_center; TinyVector dstextent; TinyVector dstshape; TinyVector kmax; }; #endif odin-2.0.3/odinreco/sum_code.h0000644000000000000000000000434312732216523013114 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-2.0.3/odinreco/expfit.h0000644000000000000000000000331012732216523012606 00000000000000/*************************************************************************** expfit.h - description ------------------- begin : Thu Mar 15 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOEXPFIT_H #define RECOEXPFIT_H #include "step.h" class RecoExpFit : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "expfit";} STD_string description() const {return "Fit exponential decay constant using x-values associated with 'userdef' dimension.";} 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 RecoExpFit;} void init(); LDRbool invert; LDRfloat masklevel; }; #endif odin-2.0.3/odinreco/reader.cpp0000644000000000000000000000002412732216523013103 00000000000000#include "reader.h" odin-2.0.3/odinreco/refgain.cpp0000644000000000000000000001313012732216523013256 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; FunctionFitDerivative refgfit; if(!refgfit.init(refgf,nrefg)) return false; 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 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++; 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,10000,0.001); 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(getenv_nonnull("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-2.0.3/odinreco/dti.h0000644000000000000000000000303312732216523012071 00000000000000/*************************************************************************** dti.h - description ------------------- begin : Thu Oct 29 2009 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/halffour.cpp0000644000000000000000000000331012732216523013450 00000000000000#include "halffour.h" #include bool RecoHalfFour::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 nread=shape(2); int nline=shape(1); int startindex=nline/2; int nline3d=shape(0); // Apply phase correction using the central line data.partial_fft(TinyVector(false,false,true)); // FFT in read ComplexData<1> centline(data(nline3d/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=nline-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(idst3d,idst,all)=oneline; } } } if(!(nread%2)) data(all,0,all)=STD_complex(0.0); // zero-fill garbage from cyclic shift return execute_next_step(rd,controller); } odin-2.0.3/odinreco/offset.h0000644000000000000000000000313612732216523012603 00000000000000/*************************************************************************** offset.h - description ------------------- begin : Wed Feb 7 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/qualitycontrol.cpp0000644000000000000000000000620312732216523014737 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-2.0.3/odinreco/qualitycontrol.h0000644000000000000000000000342712732216523014411 00000000000000/*************************************************************************** qualitycontrol.h - description ------------------- begin : Tue Feb 28 2011 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/measindex.h0000644000000000000000000001116612732216523013274 00000000000000/*************************************************************************** measindex.h - description ------------------- begin : Mon Apr 2 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOMEASINDEX_H #define RECOMEASINDEX_H #include "controller.h" /** * Helper template class to get info about indices actually measured in dimension 'dim'. * Implement 'Ignore' (and Separate) by a specialization of 'RecoDim' to specify dimensions * to be ignored (separate) before adding/retrieving index from map. */ template > 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-2.0.3/odinreco/switch.h0000644000000000000000000000441312732216523012615 00000000000000/*************************************************************************** switch.h - description ------------------- begin : Mon Jan 22 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRstring 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-2.0.3/odinreco/reader_odin.cpp0000644000000000000000000004043012732216523014121 00000000000000#include "reader_odin.h" #define SWAB_SUFFIX "swab" RecoReaderOdin::RecoReaderOdin(LDRblock& parblock) : rawdata_fileptr(NULL) { //, rawdata_bytecount(0) { fifoFile.set_cmdline_option("pf").set_description("File name of FIFO (named pipe) to obtain the raw data from"); parblock.append(fifoFile); padZero.set_cmdline_option("pz").set_description("Pad missing raw data (of interrupted measurement) with zeroes"); parblock.append(padZero); } RecoReaderOdin::~RecoReaderOdin() { if(rawdata_fileptr!=NULL) fclose(rawdata_fileptr); } bool RecoReaderOdin::concat_data(STD_string& rawfile, const STD_string& scandir, const STD_string& fnameprefix) { Log 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 LDRkSpaceCoords& coords=recoInfo.get_kSpaceCoords(); if(!coords.size()) { ODINLOG(odinlog,errorLog) << "LDRkSpaceCoords 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]; } // 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))); } STD_string scandir=LDRfileName(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; if(prot_cache.seqpars.get_EchoTime()<=0.0) { LDRfloatArr tes; tes.set_label("SliceOrder"); // separately instead of using constructor for GCC3.2 tes.load(protfile); ODINLOG(odinlog,normalDebug) << "tes" << tes << STD_endl; if(tes.total()>0 && tes[0]>0.0) { prot_cache.seqpars.set_EchoTime(tes[0]); ODINLOG(odinlog,infoLog) << "Using TE=" << tes[0] << " from old-style TE array" << 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(LDRfileName(scandir).get_basename().c_str()); // Try passed in scandir number first } if(seriesno<=0) { seriesno=atoi(LDRfileName(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; 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=ODIN_FOPEN(rawdata_filename.c_str(),modestring(readMode)); if(rawdata_fileptr==NULL) { ODINLOG(odinlog,errorLog) << "fopen(" << rawdata_filename << "): " << lasterr() << STD_endl; return false; } // rawdata_bytecount=0; int offset_bytes=recoInfo.get_RawHeaderSize(); if(offset_bytes>0) { // Only if neccessary, to allow reading from a named pipe if(ODIN_FSEEK(rawdata_fileptr, offset_bytes, SEEK_SET)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; return false; } // rawdata_bytecount+=offset_bytes; } } 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; ODINLOG(odinlog,errorLog) << "ftell=" << ODIN_FTELL(rawdata_fileptr) << STD_endl; result=false; break; } currpos+=freadresult; toberead=nitems-currpos; } // rawdata_bytecount+=2*rawtypesize*block.size(); // LONGEST_INT ftellcount=FTELL(rawdata_fileptr); // if(rawdata_bytecount!=ftellcount) { // ODINLOG(odinlog,errorLog) << "file pointer out of sync: rawdata_bytecount/ftellcount=" << rawdata_bytecount << "/" << ftellcount << STD_endl; // return false; // } 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(ODIN_FSEEK(rawdata_fileptr, skip_bytes, SEEK_CUR)) { ODINLOG(odinlog,errorLog) << "fseek: " << lasterr() << STD_endl; return false; } // rawdata_bytecount+=skip_bytes; } } // 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 driftcache; Mutex mutex; }; #endif odin-2.0.3/odinreco/multifreq.cpp0000644000000000000000000002060112732216523013654 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!=int(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\/\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\-dce\fR: TE used for field drift calculations, if non\-zero [ms] (default=0.0ms) .HP \fB\-dcs\fR: Index selection string in recipe used for drift correction (space separated list of 'dim=selection', e.g. te=2) .HP \fB\-dcw\fR: Store field drift to file with this prefix .HP \fB\-dd\fR: Disable field\-drift correction .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\-dt\fR: Disable template\-based phase 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 analyze asc coi dat dcm double float gz hdr idx ima interfile jdx mag mhd nii .PP ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk xml xpro' (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.0) .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\-gt\fR: Store GRAPPA template images .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=1) .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-2.0.3/odinreco/dump.h0000644000000000000000000000305712732216523012264 00000000000000/*************************************************************************** dump.h - description ------------------- begin : Mon Oct 13 2008 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRstring prefix; LDRstring format; }; #endif odin-2.0.3/odinreco/step.cpp0000644000000000000000000002162212732216523012623 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 "halffour.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 RecoCollector<3, RecoDim<3, line3d, line, readout>, 5, RecoDim<5, cycle, slice, echo, epi, channel>, true > ("driftcoll")); 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 RecoHalfFour()); 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 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-2.0.3/odinreco/fieldmap.cpp0000644000000000000000000002717612732216523013443 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++; } } } LDRfilter 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 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-2.0.3/odinreco/reader_ismrmrd.cpp0000644000000000000000000005011312732216523014644 00000000000000#include "reader_ismrmrd.h" #ifdef ISMRMRDSUPPORT #include #include void RecoReaderISMRMRD::print_flags(ISMRMRD::AcquisitionHeader& acqhead) { Log odinlog("RecoReaderISMRMRD","print_flags"); if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP1)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP1" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_ENCODE_STEP1)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_ENCODE_STEP1" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP2)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_ENCODE_STEP2" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_ENCODE_STEP2)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_ENCODE_STEP2" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_AVERAGE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_AVERAGE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_AVERAGE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_AVERAGE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_SLICE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_SLICE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_SLICE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_SLICE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_CONTRAST)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_CONTRAST" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_CONTRAST)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_CONTRAST" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_PHASE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_PHASE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_PHASE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_PHASE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_REPETITION)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_REPETITION" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_REPETITION)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_REPETITION" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_SET)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_SET" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_SET)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_SET" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_FIRST_IN_SEGMENT)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_FIRST_IN_SEGMENT" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_SEGMENT)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_SEGMENT" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_NOISE_MEASUREMENT" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_PARALLEL_CALIBRATION_AND_IMAGING" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_REVERSE)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_REVERSE" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NAVIGATION_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_NAVIGATION_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_PHASECORR_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_PHASECORR_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_LAST_IN_MEASUREMENT)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_LAST_IN_MEASUREMENT" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_HPFEEDBACK_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_HPFEEDBACK_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_DUMMYSCAN_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_DUMMYSCAN_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_RTFEEDBACK_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_RTFEEDBACK_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_IS_SURFACECOILCORRECTIONSCAN_DATA" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER1)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER1" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER2)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER2" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER3)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER3" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER4)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER4" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER5)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER5" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER6)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER6" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER7)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER7" << STD_endl;} if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_USER8)) {ODINLOG(odinlog,normalDebug) << "ISMRMRD_ACQ_USER8" << STD_endl;} } //////////////////////////////////////////////////////////////////////////// bool RecoReaderISMRMRD::ignore_acq(ISMRMRD::AcquisitionHeader& acqhead) { Log odinlog("RecoReaderISMRMRD","ignore_acq"); bool result=false; if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_NOISE_MEASUREMENT)) result=true; if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_DUMMYSCAN_DATA)) result=true; return result; } //////////////////////////////////////////////////////////////////////////// bool RecoReaderISMRMRD::pe_offset(const ISMRMRD::Limit& limit, unsigned int& offset, float& partfour_prot) { Log odinlog("RecoReaderISMRMRD","pe_offset"); ODINLOG(odinlog,infoLog) << "enclimits_1=" << limit.minimum << "-" << limit.center << "-" << limit.maximum << STD_endl; offset=0; float center_float=STD_max(float(0.0),float(limit.center-0.5)); // use float to place center between two sampling points float pre_center=center_float-float(limit.minimum); float post_center=float(limit.maximum)-center_float; if(pre_center<0 || post_center<0) { ODINLOG(odinlog,errorLog) << "pre_center/post_center=" << pre_center << "/" << post_center << STD_endl; return false; } if(post_center odinlog("RecoReaderISMRMRD","init"); dset=new ISMRMRD::Dataset(input_filename.c_str(), "dataset", false); STD_string xmlstr; dset->readHeader(xmlstr); ISMRMRD::IsmrmrdHeader xmlhdr; ISMRMRD::deserialize(xmlstr.c_str(),xmlhdr); ODINLOG(odinlog,normalDebug) << "xmlstr: " << xmlstr << STD_endl; if(xmlhdr.encoding.size()!=1) { ODINLOG(odinlog,errorLog) << "Implememnt me: xmlhdr.encoding.size()=" << xmlhdr.encoding.size() << STD_endl; return false; } ///////////////////////////////////////////////////////////////////////////////////// // 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 ISMRMRD::SubjectInformation& xmlsubj=xmlhdr.subjectInformation.get(); ISMRMRD::Encoding& enc=xmlhdr.encoding[0]; ISMRMRD::EncodingSpace& recospace=enc.reconSpace; ISMRMRD::EncodingSpace& encspace=enc.encodedSpace; STD_string patid="Unknown"; if(xmlsubj.patientID) patid=xmlsubj.patientID.get(); STD_string patname="Unknown"; if(xmlsubj.patientName) patname=xmlsubj.patientName.get(); STD_string patbirth="00000000"; if(xmlsubj.patientBirthdate) patbirth=xmlsubj.patientBirthdate.get(); char patgender='O'; if(xmlsubj.patientGender && xmlsubj.patientGender.get().size()>0) patbirth=xmlsubj.patientGender.get()[0]; float patweight=0.0; if(xmlsubj.patientWeight_kg) patweight=xmlsubj.patientWeight_kg.get(); // Study information, which is stored together with the raw data prot_cache.study.set_Patient(patid, patname, patbirth, patgender, patweight, 1234.0); // prot_cache.study.set_Context("RecoReaderISMRMRD","DrNo"); // prot_cache.study.set_Series("Test",7); ODINLOG(odinlog,normalDebug) << "study: " << prot_cache.study << STD_endl; if(xmlhdr.sequenceParameters) { ISMRMRD::SequenceParameters& sequencepars=xmlhdr.sequenceParameters.get(); if(sequencepars.TR && sequencepars.TR.get().size()>0) prot_cache.seqpars.set_RepetitionTime(sequencepars.TR.get()[0]); if(sequencepars.TE && sequencepars.TE.get().size()>0) prot_cache.seqpars.set_EchoTime(sequencepars.TE.get()[0]); if(sequencepars.flipAngle_deg && sequencepars.flipAngle_deg.get().size()>0) prot_cache.seqpars.set_FlipAngle(sequencepars.flipAngle_deg.get()[0]); if(sequencepars.sequence_type) prot_cache.seqpars.set_Sequence(sequencepars.sequence_type.get()); // TODO: sequencepars.echo_spacing } // 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,recospace.fieldOfView_mm.x); prot_cache.geometry.set_FOV(phaseDirection,recospace.fieldOfView_mm.y); double slicedist=secureDivision(recospace.fieldOfView_mm.z, recospace.matrixSize.z); prot_cache.geometry.set_sliceDistance(slicedist); prot_cache.geometry.set_sliceThickness(slicedist); // no gap ///////////////////////////////////////////////////////////////////////////////////// // adjust size that will be returned by reader, this is required for gridding (e.g. ramp-sampling correction) size_cache(0)=recospace.matrixSize.z; // 2nd phase encoding direction size_cache(1)=recospace.matrixSize.y; size_cache(2)=recospace.matrixSize.x; // This will shift the image in 3D-space according to the offsets // given in relative units of the FOV reloffset_cache=TinyVector(0.0,0.0,0.0); // shift image in phase and read direction by 0.05*FOV and 0.1*FOV, respectively ISMRMRD::EncodingLimits& enclimits=enc.encodingLimits; float relcenter=-1.0; if(enclimits.kspace_encoding_step_0) { ODINLOG(odinlog,infoLog) << "enclimits_0=" << enclimits.kspace_encoding_step_0.get().minimum << "-" << enclimits.kspace_encoding_step_0.get().center << "-" << enclimits.kspace_encoding_step_0.get().maximum << STD_endl; relcenter=secureDivision(enclimits.kspace_encoding_step_0.get().center,enclimits.kspace_encoding_step_0.get().maximum); } unsigned int lineoffset=0; float partfour_prot; if(enclimits.kspace_encoding_step_1) { if(!pe_offset(enclimits.kspace_encoding_step_1.get(), lineoffset, partfour_prot)) return false; prot_cache.seqpars.set_PartialFourier(partfour_prot); } unsigned int line3doffset=0; if(enclimits.kspace_encoding_step_2) { if(!pe_offset(enclimits.kspace_encoding_step_2.get(), line3doffset, partfour_prot)) return false; } STD_list coordlist; unsigned int ismrmrd_nacq=dset->getNumberOfAcquisitions(); ODINLOG(odinlog,infoLog) << "ismrmrd_nacq=" << ismrmrd_nacq << STD_endl; float oversampling_factor=secureDivision(encspace.matrixSize.x,recospace.matrixSize.x); ODINLOG(odinlog,infoLog) << "oversampling_factor=" << oversampling_factor << STD_endl; typedef STD_map > TrajMap; TrajMap trajmap; int npts_traj=0; int offset_traj=0; typedef STD_map TrajChecksumMap; TrajChecksumMap checksumcache; // for integrity check for(unsigned int iadc=0; iadcreadAcquisition(iadc, acq); ISMRMRD::AcquisitionHeader acqhead=acq.getHead(); // creating copy because AcquisitionHeader::isFlagSet() is non-const const ISMRMRD::EncodingCounters& acqindex=acqhead.idx; unsigned int trajdims=acq.trajectory_dimensions(); if(trajdims) { ODINLOG(odinlog,normalDebug) << "trajectory_dimensions=" << acq.trajectory_dimensions() << STD_endl; int trajelements=acq.getNumberOfTrajElements()/trajdims; ODINLOG(odinlog,normalDebug) << "trajelements[" << iadc << "]=" << trajelements << "/" << trajelements << STD_endl; int nsamples=acqhead.number_of_samples-acqhead.discard_pre-acqhead.discard_post; if(trajelements < nsamples) { ODINLOG(odinlog,errorLog) << "size mismatch: trajelements(" << trajelements<< ") < nsamples(" << nsamples<< ")" << STD_endl; return false; } // cache for later use npts_traj=nsamples; offset_traj=acqhead.discard_pre; float* trajptr=acq.getTrajPtr(); if(trajptr) { Data trajarr(Array(trajptr, TinyVector(trajelements,trajdims), duplicateData)); // create copy because trajectory array changes in place float trajchecksum=sum(trajarr)+trajelements+trajdims; // (check)sum for integrity check ODINLOG(odinlog,normalDebug) << "trajptr/trajchecksum/kspace_encode_step_1=" << trajptr << "/" << trajchecksum << "/" << acqindex.kspace_encode_step_1 << STD_endl; trajmap[acqindex.kspace_encode_step_1].reference(trajarr); TrajChecksumMap::const_iterator it=checksumcache.find(acqindex.kspace_encode_step_1); if(it!=checksumcache.end()) { if(it->second!=trajchecksum) { // integrity check whether consecutive trajectories with same cycle index are the same ODINLOG(odinlog,errorLog) << "sum mismatch: trajchecksum(" << trajchecksum << ") != checksumcache(" << it->second << ")" << STD_endl; return false; } } else { checksumcache[acqindex.kspace_encode_step_1]=trajchecksum; } } else { ODINLOG(odinlog,errorLog) << "TrajPtr missing" << STD_endl; return false; } } if(!ignore_acq(acqhead)) { RecoCoord coord; unsigned int nchan=acqhead.active_channels; for(unsigned int ichan=0; ichan=0.0 && relcenter<=1.0) coord.relCenterPos=relcenter; if(acqhead.isFlagSet(ISMRMRD::ISMRMRD_ACQ_IS_REVERSE)) coord.flags=coord.flags|recoReflectBit; coordlist.push_back(coord); ODINLOG(odinlog,normalDebug) << "coord[" << iadc << "]=" << coord.print(RecoIndex::all) << STD_endl; } } } // Convert list to vector coord_vec_cache.resize(coordlist.size()); unsigned int ivec=0; for(STD_list::iterator it=coordlist.begin(); it!=coordlist.end(); ++it) { RecoCoord& coord=(*it); // if(has_patref_integrated && coord.index[templtype]==grappa_template) coord.index[templtype] = no_template; // Do not assume separate GRAPPA calibration scan coord_vec_cache[ivec]=coord; ivec++; } ODINLOG(odinlog,infoLog) << "#ADCs=" << coord_vec_cache.size() << STD_endl; // convert trajectories int ntrajs=trajmap.size(); if(ntrajs) { TinyVector kscale; kscale(2)=secureDivision(2.0*PII*encspace.matrixSize.x,encspace.fieldOfView_mm.x); kscale(1)=secureDivision(2.0*PII*encspace.matrixSize.y,encspace.fieldOfView_mm.y); kscale(0)=secureDivision(2.0*PII*encspace.matrixSize.z,encspace.fieldOfView_mm.z); ODINLOG(odinlog,infoLog) << "kscale=" << kscale << STD_endl; kspaceTraj_cache.resize(ntrajs,npts_traj); for(int itraj=0; itraj& trajarr=it->second; int ntrajdim=trajarr.extent(1); for(int ipt=0; ipt kvec; kvec=0.0; for(int idim=0; idim=coord_vec_cache.size()) return false; // This check is necessary for proper multi-threading // Return the next raw data ADC coord=coord_vec_cache[coord_count]; // Load next block of raw data if(!chancount) { ISMRMRD::AcquisitionHeader acqhead; do { ISMRMRD::Acquisition acq; dset->readAcquisition(ismrmrd_count, acq); acqhead=acq.getHead(); // creating copy because AcquisitionHeader::isFlagSet() is non-const nsamples_raw_cache=acqhead.number_of_samples; nchan_cache=acqhead.active_channels; ODINLOG(odinlog,normalDebug) << "nsamples_raw/nchan=" << nsamples_raw_cache << "/" << nchan_cache << STD_endl; pre_discard_cache=acqhead.discard_pre; post_discard_cache=acqhead.discard_post; ODINLOG(odinlog,normalDebug) << "pre_discard_cache/post_discard_cache=" << pre_discard_cache << "/" << post_discard_cache << STD_endl; STD_complex* cplxptr=acq.getDataPtr(); rawdata.reference(Array(cplxptr, TinyVector(nchan_cache,nsamples_raw_cache), neverDeleteData).copy()); ismrmrd_count++; } while(ignore_acq(acqhead)); // Continue if current ADC should be ignored } // crop raw data unsigned int nsamples_cropped=nsamples_raw_cache-pre_discard_cache-post_discard_cache; ODINLOG(odinlog,normalDebug) << "nsamples_cropped=" << nsamples_cropped << STD_endl; adc.resize(nsamples_cropped); adc=rawdata(chancount,Range(pre_discard_cache,pre_discard_cache+nsamples_cropped-1)); coord_count++; chancount++; if(chancount>=nchan_cache) { // get next raw data if channels complete chancount=0; } return true; } dvector RecoReaderISMRMRD::dim_values(recoDim dim) const { // Return values associated with dimension 'dim', i.e. the TEs of a multi-echo readout, if available return dvector(); } STD_string RecoReaderISMRMRD::cmdline_opts() const { // Return extra command-line options of the reco return ""; } #endif // HDFSUPPORT odin-2.0.3/odinreco/messer.cpp0000644000000000000000000001154712732216523013153 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-2.0.3/odinreco/fmri.h0000644000000000000000000000323012732216523012245 00000000000000/*************************************************************************** fmri.h - description ------------------- begin : Thu Apr 30 2009 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRint stimsize; LDRint restsize; }; #endif odin-2.0.3/odinreco/reader_odin.h0000644000000000000000000000677012732216523013577 00000000000000/*************************************************************************** reader_odin.h - description ------------------- begin : Thu Oct 18 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOREADERODIN_H #define RECOREADERODIN_H #include "reader.h" /** * @addtogroup odinreco * @{ */ /** * Raw-data reader for data acquired with odin sequences */ class RecoReaderOdin : public virtual RecoReaderInterface { public: RecoReaderOdin(LDRblock& parblock); ~RecoReaderOdin(); 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; 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); LDRstring fifoFile; LDRbool 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; // LONGEST_INT rawdata_bytecount; // for debugging 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-2.0.3/odinreco/filter.cpp0000644000000000000000000000302012732216523013125 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(unsigned 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-2.0.3/odinreco/odinreco.h0000644000000000000000000001456612732216523013130 00000000000000/*************************************************************************** odinreco.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 of ODIN raw data, * 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/'. * * For other formats, e.g. the ISMRM Raw Data Format (ISMRMRD) or Siemens raw data, * specify the raw data file using the option '-r': * \verbatim odinreco -r simple_gre.h5 \endverbatim * * 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-2.0.3/odinreco/reader.h0000644000000000000000000000664312732216523012565 00000000000000/*************************************************************************** reader.h - description ------------------- begin : Mon Jan 8 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOREADER_H #define RECOREADER_H #include #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-2.0.3/odinreco/dump.cpp0000644000000000000000000000315712732216523012620 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-2.0.3/odinreco/data.cpp0000644000000000000000000000207112732216523012556 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(); if(dim==7) data7.free(); if(dim==8) data8.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()); data7.reference(rd.data7.copy()); data8.reference(rd.data8.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-2.0.3/odinreco/blade.cpp0000644000000000000000000004726112732216523012726 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(unsigned int i=0; i 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(unsigned 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(int(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)); unsigned int nblades=inshape(0); dvector angles=controller.dim_values(cycle); ODINLOG(odinlog,normalDebug) << "angles=" << angles.printbody() << STD_endl; if(nblades!=angles.size()) { ODINLOG(odinlog,errorLog) << "nblades(" << nblades << ") != nangles(" << angles.size() << ")" << STD_endl; return false; } 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 LDRfilter 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(unsigned int i=0; i 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 (unsigned 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 (unsigned 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(unsigned 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-2.0.3/odinreco/oversampling.cpp0000644000000000000000000000200112732216523014344 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-2.0.3/odinreco/phasecorr.cpp0000644000000000000000000001420512732216523013635 00000000000000#include "phasecorr.h" #include "data.h" #include "controller.h" #include 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-2.0.3/odinreco/oversampling.h0000644000000000000000000000317012732216523014021 00000000000000/*************************************************************************** oversampling.h - description ------------------- begin : Thu Feb 22 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/blackboard.cpp0000644000000000000000000000731112732216523013733 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-2.0.3/odinreco/slicetime.cpp0000644000000000000000000000246412732216523013631 00000000000000#include "slicetime.h" #include "data.h" #include "controller.h" #include bool RecoSliceTime::process(RecoData& rd, RecoController& controller) { Log odinlog(c_label(),"process"); Range all=Range::all(); STD_string sliceorderstr=controller.dim_values(slice).printbody(); ODINLOG(odinlog,normalDebug) << "sliceorderstr=" << sliceorderstr << STD_endl; FilterChain filterchain("-slicetime \""+sliceorderstr+"\""); // re-use filter step ComplexData<5>& indata=rd.data(Rank<5>()); TinyVector inshape=indata.shape(); int nrep=inshape(0); int nslices=inshape(1); int nphase3d=inshape(2); int nphase=inshape(3); int nread=inshape(4); if(nrep>1 && nslices>1) { TinyVector shape4filter(nrep,nslices,nphase,nread); Data rdata(shape4filter); Data idata(shape4filter); Protocol protcopy(controller.protocol()); for(int iphase3d=0; iphase3d& weight) { Log odinlog(c_label(),"weight_data"); ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); int npts=shape(dimindex); int startindex=0; if(dimindex==2) { if(rd.coord().adcend<(npts-1)) { ODINLOG(odinlog,errorLog) << "Not implemented: Interpolation at end of readout" << STD_endl; return false; } startindex=rd.coord().adcstart; } else { ivector indexvec; if(dimindex==0) indexvec=measlines3d.get_indices(rd.coord()); if(dimindex==1) indexvec=measlines.get_indices(rd.coord()); startindex=indexvec.minvalue(); } int endindex=npts-1-startindex; symrange=Range(startindex,endindex); ODINLOG(odinlog,normalDebug) << "startindex/endindex[" << dimindex << "]=" << startindex << "/" << endindex << STD_endl; weight.resize(npts); weight=STD_complex(1.0); if(startindex<=0) return true; // no homodyne reco required, end here float center=0.5*float(npts-1); ODINLOG(odinlog,normalDebug) << "center[" << dimindex << "]=" << center << STD_endl; if(float(startindex)>=center) { // Not true homodyne reco ODINLOG(odinlog,errorLog) << "startindex=" << startindex << " larger than or equal center=" << center << STD_endl; return false; } fvector transition(endindex-startindex+1); transition.fill_linear(0.0,1.0); for(int i=0; i odinlog(c_label(),"process"); // Range all=Range::all(); if(rd.interpolated) { measlines.update(*(rd.interpolated)); // take previously interpolated coords into account measlines3d.update(*(rd.interpolated)); // take previously interpolated coords into account } ComplexData<3>& data=rd.data(Rank<3>()); TinyVector shape=data.shape(); Range symrange3d; ComplexData<1> weight3d; if(!weight_and_range(0, rd, symrange3d, weight3d)) return false; Range symrange; ComplexData<1> weight; if(!weight_and_range(1, rd, symrange, weight)) return false; Range symrangeread; ComplexData<1> weightread; if(!weight_and_range(2, rd, symrangeread, weightread)) return false; // symmetric data for phase correction ComplexData<3> symmetric(shape); symmetric=STD_complex(0.0); symmetric(symrange3d,symrange,symrangeread)=data(symrange3d,symrange,symrangeread); // Data(cabs(symmetric)).autowrite("symmetric.nii"); symmetric.fft(); // Data(cabs(symmetric)).autowrite("symmetric_fft_cabs.nii"); // Data(phase(symmetric)).autowrite("symmetric_fft_phase.nii"); for(int iphase3d=0; iphase3d realpart(shape); realpart=float2real(creal(data)); data.reference(realpart); return execute_next_step(rd,controller); } /////////////////////////////////////////////////////// bool RecoHomodyne::query(RecoQueryContext& context) { Log odinlog(c_label(),"query"); if(context.mode==RecoQueryContext::prep) { if(!measlines.init(context.coord, context.controller)) return false; if(!measlines3d.init(context.coord, context.controller)) return false; } return RecoStep::query(context); } odin-2.0.3/odinreco/mip.h0000644000000000000000000000311412732216523012076 00000000000000/*************************************************************************** mip.h - description ------------------- begin : Tue Dec 4 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRint neighbors; }; #endif odin-2.0.3/odinreco/collector_code.h0000644000000000000000000000623112732216523014274 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-2.0.3/odinreco/adc.h0000644000000000000000000000761312732216523012050 00000000000000/*************************************************************************** adc.h - description ------------------- begin : Mon Jan 22 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/halffour.h0000644000000000000000000000315512732216523013124 00000000000000/*************************************************************************** halffour.h - description ------------------- begin : Tue Oct 20 2015 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOHALFFOUR_H #define RECOHALFFOUR_H #include "step.h" #include "measindex.h" class RecoHalfFour : public RecoStep { // implementing virtual functions of RecoStep STD_string label() const {return "halffour";} STD_string description() const {return "Mirror k-space of half-Fourier acquisition";} 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 RecoHalfFour;} void init() {} }; #endif odin-2.0.3/odinreco/splitter.cpp0000644000000000000000000000041712732216523013515 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-2.0.3/odinreco/odinreco.cpp0000644000000000000000000000017612732216523013453 00000000000000#include "odinreco.h" #include const char* Reco::get_compName() {return "Reco";} LOGGROUNDWORK(Reco) odin-2.0.3/odinreco/expfit.cpp0000644000000000000000000000421512732216523013146 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-2.0.3/odinreco/slidingwindow.h0000644000000000000000000000305512732216523014176 00000000000000/*************************************************************************** slidingwindow.h - description ------------------- begin : Tue Sep 8 2009 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/conjphase.cpp0000644000000000000000000000661412732216523013626 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(unsigned 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 #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(); LDRstring extension; LDRstring prefix; LDRstring formats; LDRstring imageproc; LDRbool 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-2.0.3/odinreco/step.h0000644000000000000000000001150512732216523012267 00000000000000/*************************************************************************** step.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinreco/refgain.h0000644000000000000000000000323612732216523012731 00000000000000/*************************************************************************** refgain.h - description ------------------- begin : Thu Feb 22 2007 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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(); LDRfloat pulsedur; LDRfloat pulsegain; }; #endif odin-2.0.3/odinreco/controller.h0000644000000000000000000001710312732216523013477 00000000000000/*************************************************************************** controller.h - description ------------------- begin : Sat Dec 30 2006 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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 RECOCONTROLLER_H #define RECOCONTROLLER_H #include #include #include #include #include /** * @addtogroup odinreco * @{ */ class RecoReaderInterface; // forward declaration class RecoStep; // forward declaration //////////////////////////////////////////////////////////////// /** * Class to manage reconstruction process. */ class RecoController { public: /** * Creates uninitialized reconstruction controller. Appends parameters to 'parblock'. */ RecoController(LDRblock& parblock); ~RecoController(); /** * Initializes reconstruction process controller to use reco input 'reader' * and option block 'opts'. Returns 'true' only if sucessful. */ bool init(RecoReaderInterface* reader, LDRblock& opts, int argc, char* argv[]); /** * Starts reconstruction process using 'firststep' as the start of the * reconstruction pipeline. * Returns 'true' only if sucessful. */ bool start(); /** * Returns vector of values associated with a certain dimension. */ dvector dim_values(recoDim dim) const; /** * Returns the relative spatial offset the image should be shifted after reconstruction. * The result contains the offsets in (phase3d,phase,read) direction. */ TinyVector 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 LDRint jobs; LDRstring recipe; LDRstring recipeFile; LDRstring select; LDRint timeout; LDRint maxrecursion; LDRbool conjPhaseFT; LDRbool slidingWindow; LDRbool keyhole; LDRbool sepChannels; LDRbool dumpKspace; LDRbool dumpGrappaTemplate; LDRbool disablePhaseCorr; LDRbool disableHomodyne; LDRbool disableMultiFreq; LDRbool disableDriftCorr; LDRbool disableSliceTime; LDRbool disableGrappa; LDRbool phaseCourse; LDRbool qcspike; LDRstring preproc3d; LDRstring postproc3d; LDRstring dumpRawPrefix; LDRstring fieldmapFile; // LDRstring driftcorrFile; LDRstring driftcorrSel; 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, bool& half_fourier) const; bool autorecipe(const RecoCoord& mask, STD_string& result) const; bool create_selection_map(const STD_string& selstr, STD_map& selmap, RecoCoord* initcoord=0) 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-2.0.3/config.guess0000755000000000000000000012536413010312545011661 00000000000000#! /bin/sh # Attempt to guess a canonical system name. # Copyright 1992-2016 Free Software Foundation, Inc. timestamp='2016-04-02' # 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 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 . # # 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. This Exception is an additional permission under section 7 # of the GNU General Public License, version 3 ("GPLv3"). # # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # 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 # # Please send patches to . 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 1992-2016 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 case "${UNAME_SYSTEM}" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu eval $set_cc_for_build cat <<-EOF > $dummy.c #include #if defined(__UCLIBC__) LIBC=uclibc #elif defined(__dietlibc__) LIBC=dietlibc #else LIBC=gnu #endif EOF eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` ;; esac # 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 tuples: *-*-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=`(uname -p 2>/dev/null || \ /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 ;; earmv*) arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` machine=${arch}${endian}-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*|earm*|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 # Determine ABI tags. case "${UNAME_MACHINE_ARCH}" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` ;; 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/[-_].*//' | cut -d. -f1,2` ;; 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}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:LibertyBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${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 ;; *:Sortix:*:*) echo ${UNAME_MACHINE}-unknown-sortix 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` # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; 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:*:[4567]) 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/lslpp ] ; then IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` 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:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` case ${UNAME_PROCESSOR} in amd64) echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; *) echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; *:MINGW64*:*) echo ${UNAME_MACHINE}-pc-mingw64 exit ;; *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; *:MSYS*:*) echo ${UNAME_MACHINE}-pc-msys 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-${LIBC}`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 "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} exit ;; i*86:Minix:*:*) echo ${UNAME_MACHINE}-pc-minix exit ;; aarch64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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=gnulibc1 ; fi echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; arc:Linux:*:* | arceb:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${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-${LIBC} else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi else echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf fi fi exit ;; avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; cris:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; crisv32:Linux:*:*) echo ${UNAME_MACHINE}-axis-linux-${LIBC} exit ;; e2k:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; frv:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; hexagon:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; i*86:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; ia64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; k1om:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m32r*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; m68*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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-${LIBC}"; exit; } ;; openrisc*:Linux:*:*) echo or1k-unknown-linux-${LIBC} exit ;; or32:Linux:*:* | or1k*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; padre:Linux:*:*) echo sparc-unknown-linux-${LIBC} exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) echo hppa64-unknown-linux-${LIBC} 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-${LIBC} ;; PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; *) echo hppa-unknown-linux-${LIBC} ;; esac exit ;; ppc64:Linux:*:*) echo powerpc64-unknown-linux-${LIBC} exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-${LIBC} exit ;; ppc64le:Linux:*:*) echo powerpc64le-unknown-linux-${LIBC} exit ;; ppcle:Linux:*:*) echo powerpcle-unknown-linux-${LIBC} exit ;; s390:Linux:*:* | s390x:Linux:*:*) echo ${UNAME_MACHINE}-ibm-linux-${LIBC} exit ;; sh64*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sh*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; tile*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} exit ;; vax:Linux:*:*) echo ${UNAME_MACHINE}-dec-linux-${LIBC} exit ;; x86_64:Linux:*:*) echo ${UNAME_MACHINE}-pc-linux-${LIBC} exit ;; xtensa*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-${LIBC} 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 configure 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 ;; x86_64:Haiku:*:*) echo x86_64-unknown-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 ;; SX-ACE:SUPER-UX:*:*) echo sxace-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 eval $set_cc_for_build if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then 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 case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub # that puts up a graphical alert prompting to install # developer tools. Any system running Mac OS X 10.7 or # later (Darwin 11 and later) is required to have a 64-bit # processor. This is not true of the ARM version of Darwin # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi 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 ;; NEO-?:NONSTOP_KERNEL:*:*) echo neo-tandem-nsk${UNAME_RELEASE} 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 ;; x86_64:VMkernel:*:*) echo ${UNAME_MACHINE}-unknown-esx exit ;; amd64:Isilon\ OneFS:*:*) echo x86_64-unknown-onefs exit ;; esac 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-2.0.3/odinqt/0000755000000000000000000000000013010330625010703 500000000000000odin-2.0.3/odinqt/complex1d.h0000644000000000000000000000743512732216521012711 00000000000000/*************************************************************************** complex1d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/Makefile.in0000644000000000000000000006570213010312546012704 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am \ $(am__library_include_HEADERS_DIST) $(am__DIST_COMMON) 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__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } 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 ldrwidget.h ldrwidget.cpp \ ldrwidget_moc.cpp ldrblockwidget.h ldrblockwidget.cpp \ ldrblockwidget_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 ldrwidget.lo \ @GUI_ENABLED_TRUE@ ldrwidget_moc.lo ldrblockwidget.lo \ @GUI_ENABLED_TRUE@ ldrblockwidget_moc.lo libodinqt_la_OBJECTS = $(am_libodinqt_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = libodinqt_la_LINK = $(LIBTOOL) $(AM_V_lt) --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) AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = 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) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(libodinqt_la_SOURCES) DIST_SOURCES = $(am__libodinqt_la_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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 ldrwidget.h \ ldrblockwidget.h HEADERS = $(library_include_HEADERS) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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@AM_CPPFLAGS = $(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@ldrwidget.h \ @GUI_ENABLED_TRUE@ldrblockwidget.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@ldrwidget.h ldrwidget.cpp ldrwidget_moc.cpp \ @GUI_ENABLED_TRUE@ldrblockwidget.h ldrblockwidget.cpp ldrblockwidget_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 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) @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 " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ 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)'; \ locs=`for p in $$list; do echo $$p; done | \ sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ sort -u`; \ test -z "$$locs" || { \ echo rm -f $${locs}; \ rm -f $${locs}; \ } libodinqt.la: $(libodinqt_la_OBJECTS) $(libodinqt_la_DEPENDENCIES) $(EXTRA_libodinqt_la_DEPENDENCIES) $(AM_V_CXXLD)$(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)/ldrblockwidget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldrblockwidget_moc.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldrwidget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldrwidget_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@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-library_includeHEADERS: $(library_include_HEADERS) @$(NORMAL_INSTALL) @list='$(library_include_HEADERS)'; test -n "$(library_includedir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(library_includedir)'"; \ $(MKDIR_P) "$(DESTDIR)$(library_includedir)" || exit 1; \ fi; \ 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|^.*/||'`; \ dir='$(DESTDIR)$(library_includedir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ 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-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ 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" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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 TAGS all all-am check check-am clean clean-generic \ clean-libLTLIBRARIES clean-libtool clean-local cscopelist-am \ ctags ctags-am 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 tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ uninstall-library_includeHEADERS .PRECIOUS: Makefile # 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-2.0.3/odinqt/intedit.h0000644000000000000000000000557412732216521012457 00000000000000/*************************************************************************** intedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/intedit.cpp0000644000000000000000000000561312732216521013004 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-2.0.3/odinqt/boolbutton.h0000644000000000000000000000325612732216521013201 00000000000000/*************************************************************************** boolbutton.h - description ------------------- begin : Sun Jul 16 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/float1d.cpp0000644000000000000000000000362012732216521012672 00000000000000/*************************************************************************** float1d.cpp - description ------------------- begin : Tue Jul 11 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/complex1d.cpp0000644000000000000000000002056212732216521013240 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-2.0.3/odinqt/float3d.h0000644000000000000000000000675312732216521012353 00000000000000/*************************************************************************** float3d.h - description ------------------- begin : Thu Nov 10 2005 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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, bool disable_scale, 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_legend(const char* fname, const char* format) const {label->write_legend(fname, format);} 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-2.0.3/odinqt/plot.cpp0000644000000000000000000004766312732216521012335 00000000000000#include // for mouse events #include "plot.h" #include #include #include #include #include #if QWT_VERSION < 0x060000 #include #else #include #include #endif #if QWT_VERSION > 0x04FFFF #include #include #include #include #include #include #else #include #endif #if QWT_VERSION < 0x060000 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); } }; #endif // QWT_VERSION < 0x060000 //////////////////////////////////////////////////////////////////////////// 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); /* // still necessary? #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()); #if QWT_VERSION < 0x060000 qwtplotter->setCanvasBackground(_ARRAY_BACKGROUND_COLOR_); #else qwtplotter->setCanvasBackground(QBrush(QColor(_ARRAY_BACKGROUND_COLOR_))); #endif #if QWT_VERSION > 0x04FFFF plotgrid=new QwtPlotGrid(); ODINLOG(odinlog,normalDebug) << "plotgrid=" << plotgrid << STD_endl; #endif 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); #if QWT_VERSION < 0x060100 plotgrid->setMajPen(gridpen); plotgrid->setMinPen(gridpen); #else plotgrid->setMajorPen(gridpen); plotgrid->setMinorPen(gridpen); #endif #else qwtplotter->setGridPen(gridpen); qwtplotter->setGridMajPen(gridpen); qwtplotter->setGridMinPen(gridpen); #endif enable_grid(true); #if QWT_VERSION > 0x04FFFF plotgrid->attach(qwtplotter); #endif #if QWT_VERSION < 0x04FFFF qwtplotter->enableLegend(false); qwtplotter->enableOutline(false); #endif QwtPlotCanvas* canv=(QwtPlotCanvas*)qwtplotter->canvas(); // cast required for qwt 6.1 (and higher?) canvas_framewidth=canv->lineWidth(); picker=new GuiPlotPicker(canv,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.setFont(QFont(_FONT_TYPE_, _FONT_SIZE_)); txt.setRenderFlags(alignment); qwtplotter->setAxisTitle(axisId,txt); #else qwtplotter->setAxisTitle(axisId,label); qwtplotter->setAxisTitleFont(axisId,QFont(_FONT_TYPE_, _FONT_SIZE_)); 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(); #if QWT_VERSION < 0x060000 curve->setAxis(QwtPlot::xBottom, yaxis); #else curve->setAxes(QwtPlot::xBottom, yaxis); #endif 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; 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 int axis=QwtPlot::xBottom; if(horizontal) axis=QwtPlot::yLeft; 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=new QwtSymbol(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) { #if QWT_VERSION < 0x060000 qpc->setSymbol(*symb); qpc->setRawData(x, y, n); #else qpc->setSymbol(symb); qpc->setRawSamples(x, y, n); #endif } #else qwtplotter->setCurveSymbol(curveid,*symb); qwtplotter->setCurveRawData(curveid, x, y, n); #endif #if QWT_VERSION < 0x060000 delete symb; // qwt6 deletes symbol itself #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 #if QWT_VERSION < 0x060100 double new_lbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->lowerBound(); double new_hbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft)->upperBound(); #else double new_lbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft).lowerBound(); double new_hbound=qwtplotter->axisScaleDiv(QwtPlot::yLeft).upperBound(); #endif #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 #if QWT_VERSION < 0x060000 qwtplotter->clear(); // do this after detaching curves #else // qwtplotter->detachItems(); // does not work with QwtPlotGrid #endif } 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() { #if QWT_VERSION < 0x060000 picker->setSelectionFlags(QwtPicker::RectSelection | QwtPicker::CornerToCorner | QwtPicker::DragSelection); #else picker->setStateMachine(new QwtPickerDragRectMachine); #endif picker->setRubberBand(QwtPicker::RectRubberBand); } void GuiPlot::set_line_outline_style(bool horizontal) { #if QWT_VERSION < 0x060000 picker->setSelectionFlags(QwtPicker::PointSelection | QwtPicker::DragSelection); #else picker->setStateMachine(new QwtPickerDragPointMachine); #endif 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 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 { Log odinlog("GuiPlot","print"); #if QWT_VERSION < 0x060000 GuiPlotPrintFilter pfilter(baseline_id_cache); qwtplotter->print(painter,rect,pfilter); #else QwtPlotRenderer renderer; renderer.render(qwtplotter, painter, QRectF(rect)); #endif } 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); // ? wheel->setValue(newval); } QWidget* GuiWheel::get_widget() {return wheel;} void GuiWheel::emit_valueChanged(double newval) {emit valueChanged(newval);} GuiWheel::~GuiWheel() { delete wheel; } odin-2.0.3/odinqt/float2d.cpp0000644000000000000000000004262312732216521012701 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, bool disable_scale, 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; maplegend_pixmap=0; scale_size_cache=-1; // -1 means that it has to be initialized by get_scale_size() 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; ODINLOG(odinlog,normalDebug) << "lowbound/uppbound=" << lowbound << "/" << uppbound << STD_endl; disable_scale_cache=disable_scale; roi_mask=new float[nx_cache*ny_cache]; profile_x=new float[nx_cache]; for(i=0;isetFixedSize( (nx*coarseFactor+get_scale_size())+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, get_scale_size()); GuiImage img( imagebuff, nx_cache*coarseFactor_cache+get_scale_size(), ny_cache*coarseFactor_cache, colormap_cache); pixmap = img.create_pixmap(); GuiPainter gp(pixmap); draw_scale_text(gp, nx_cache*coarseFactor_cache, 3*_FONT_SIZE_/2, uppbound_cache); draw_scale_text(gp, nx_cache*coarseFactor_cache, 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) { Log odinlog("floatLabel2D","scale_width"); int low_length=ftos(lowbound,LEGEND_DIGITS).length(); int upp_length=ftos(uppbound,LEGEND_DIGITS).length(); ODINLOG(odinlog,normalDebug) << "low_length/upp_length=" << low_length << "/" << upp_length << STD_endl; return STD_max(low_length,upp_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 xpos, int ypos, float val) const { draw_text(gp, xpos, 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; } int floatLabel2D::get_scale_size() const { if(disable_scale_cache) return 0; if(scale_size_cache<0) scale_size_cache=scale_width(lowbound_cache, uppbound_cache); return scale_size_cache; } void floatLabel2D::write_legend(const char* fname, const char* format) const { Log odinlog("floatLabel2D","write_legend"); int width=scale_width(lowbound_cache, uppbound_cache); int nx_aligned_scale=((width+3)/4)*4; // 32-bit aligned lines for QImage int buffsize_scale=nx_aligned_scale*ny_cache*coarseFactor_cache; ODINLOG(odinlog,normalDebug) << "width/nx_aligned_scale/buffsize_scale=" << width << "/" << nx_aligned_scale << "/" << buffsize_scale << STD_endl; unsigned char* imagebuff_scale=(unsigned char*)new int[buffsize_scale/sizeof(int)+1]; // get 32-bit aligned data for QImage for(int i=0; isave(fname, toupperstr(format).c_str()); delete legend_pixmap; delete[] imagebuff_scale; } QLabel* floatLabel2D::get_map_legend(QWidget *parent) const { QLabel* result=new QLabel(parent); int width=6*_FONT_SIZE_; int height=ny_cache*coarseFactor_cache; maplegend_pixmap = new QPixmap(width,height); GuiPainter *maplegend_painter = new GuiPainter(maplegend_pixmap); QColor qc; QColor qc_txt("Black"); for(int iy=0; iyfillRect (0,iy,width,1,qc); draw_text(*maplegend_painter, 0, 1.5*_FONT_SIZE_, ftos(uppbound_map_cache,LEGEND_DIGITS).c_str()); draw_text(*maplegend_painter, 0, ny_cache*coarseFactor_cache-_FONT_SIZE_/2, ftos(lowbound_map_cache,LEGEND_DIGITS).c_str()); } result->setPixmap(*maplegend_pixmap); return result; } void floatLabel2D::write_map_legend(const char* fname, const char* format) const { if(maplegend_pixmap && fname) maplegend_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-2.0.3/odinqt/boolbutton.cpp0000644000000000000000000000216412732216521013531 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-2.0.3/odinqt/ldrblockwidget.cpp0000644000000000000000000002310612732216521014341 00000000000000#include "ldrwidget.h" #include "ldrblockwidget.h" ///////////////////////////////////////////////////////////////////////////// LDRblockGrid::LDRblockGrid(LDRblock& block,unsigned int columns,QWidget *parent,const char* omittext) : QWidget(parent), val(block) { Log odinlog(&block,"LDRblockGrid(...)"); grid=0; STD_list subwidgets; STD_list::iterator it; unsigned int numof_pars=block.numof_pars(); LDRbase* ldrptr; // fill list with subwidgets for(unsigned int i=0;iget_jdx_props().userdef_parameter && (ldrptr->get_parmode()!=hidden)) { LDRwidget* ldrwidget=0; LDRblock* blockdummy=0; blockdummy=ldrptr->cast(blockdummy); if(blockdummy) { unsigned int cols4block=1; if(blockdummy->numof_pars()>5) cols4block=2; ldrwidget=new LDRwidget(*ldrptr,cols4block,this,false,omittext); } else ldrwidget=new LDRwidget(*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::VCenter, rowheight, colwidth ); connect((*it),SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); connect(this,SIGNAL(updateSubWidget()),(*it),SLOT(updateWidget())); connect(this,SIGNAL(deleteSubDialogs()),(*it),SLOT(deleteDialogs())); } } void LDRblockGrid::updateWidget() { for(STD_list::iterator it=subdialogs.begin(); it!=subdialogs.end(); ++it) { (*it)->updateWidget(); } emit updateSubWidget(); } void LDRblockGrid::deleteDialogs() { emit deleteSubDialogs(); } void LDRblockGrid::createDialog() { Log odinlog(&val,"createDialog"); LDRwidgetDialog* dlg=new LDRwidgetDialog(val,1,this); subdialogs.push_back(dlg); connect(dlg,SIGNAL(valueChanged()), this,SLOT(emitValueChanged())); emit valueChanged(); } ///////////////////////////////////////////////////////////////////////////// LDRblockScrollView::LDRblockScrollView(LDRblock& block,unsigned int columns,QWidget *parent,const char* omittext) { Log odinlog(&block,"LDRblockScrollView(...)"); ldrgrid=new LDRblockGrid(block,columns,parent,omittext); connect(ldrgrid,SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); scroll=new GuiScroll(ldrgrid,parent); } LDRblockScrollView::~LDRblockScrollView() { delete scroll; } ///////////////////////////////////////////////////////////////////////////// LDRblockWidget::LDRblockWidget(LDRblock& ldrblock,unsigned int columns,QWidget *parent,bool doneButton,bool is_dialog,const char* omittext, bool storeLoadButtons, bool readonly) : QGroupBox(ldrblock.get_label().c_str(), parent ), parblock(ldrblock) { Log odinlog(&ldrblock,"LDRblockWidget(...)"); pb_done=0; pb_edit=0; pb_store=0; pb_load=0; grid=0; ldrscroll=0; noeditlist=0; if(ldrblock.is_embedded() || is_dialog) { int height=1; if(doneButton || storeLoadButtons) height=2; grid=new GuiGridLayout(this, height, 3); // if(ldrblock.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=ldrblock.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()) ldrscroll=new LDRblockScrollView(ldrblock,columns,0,omittext); connect(ldrscroll,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 LDRblockWidget::createDialog() { Log odinlog("LDRblockWidget","createDialog"); ODINLOG(odinlog,normalDebug) << "ldrscroll=" << ldrscroll << STD_endl; if(ldrscroll) ldrscroll->createDialog(); } LDRblockWidget::~LDRblockWidget() { if(pb_done) delete pb_done; if(pb_store) delete pb_store; if(pb_load) delete pb_load; if(grid) delete grid; if(ldrscroll) delete ldrscroll; if(noeditlist) delete noeditlist; for(unsigned int i=0; i odinlog(&ldr,"LDRwidgetDialog(...)"); grid=new GuiGridLayout(GuiDialog::get_widget(), 2, 1); ldrwidget=new LDRblockWidget(ldr,columns,GuiDialog::get_widget(),true,true, "", false, readonly); grid->add_widget( ldrwidget, 0, 0 ); connect(ldrwidget,SIGNAL(valueChanged()),this,SLOT(emitChanged())); connect(ldrwidget,SIGNAL(doneButtonPressed()), this,SLOT(callDone()) ); GuiDialog::show(); #if QT_VERSION > 299 if(modal) GuiDialog::exec(); #endif } LDRwidgetDialog::~LDRwidgetDialog() { delete ldrwidget; delete grid; } void LDRwidgetDialog::updateWidget() { ldrwidget->updateWidget(); } void LDRwidgetDialog::callDone() { emit finished(); GuiDialog::done(); } void LDRwidgetDialog::emitChanged() { emit valueChanged(); } odin-2.0.3/odinqt/odinqt.cpp0000644000000000000000000010706312732216521012644 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_POST3 #else #define QT_VERSION_3 #endif #ifdef QT_VERSION_POST3 #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_POST3 return qs.toLocal8Bit().constData(); #else return qs; #endif } int layout_border_size() { #ifdef QT_VERSION_POST3 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_POST3 ql->setCursor(Qt::CrossCursor); #else ql->setCursor(Qt::crossCursor); #endif } bool left_button(const QMouseEvent* qme, bool return_current_state) { #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 w->setToolTip(txt); #else QToolTip::add(w,txt); #endif } void set_platform_defaults(QWidget* w, bool enable) { #ifdef Q_WS_MAC #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 return qpd->height(); #else QPaintDeviceMetrics metrics(qpd); return metrics.height(); #endif } int paintdevice_width(const QPaintDevice* qpd) { #ifdef QT_VERSION_POST3 return qpd->width(); #else QPaintDeviceMetrics metrics(qpd); return metrics.width(); #endif } /////////////////////////////////////////////////// svector get_possible_image_fileformats() { #ifdef QT_VERSION_POST3 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_POST3 Qt::Alignment align=0; #else int align=0; #endif if(alignment==VCenter) align=Qt::AlignVCenter; if(alignment==Center) align=Qt::AlignCenter; #ifdef QT_VERSION_POST3 qgl->addWidget(w, row, column, rowSpan, columnSpan, align ); #else 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_POST3 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_POST3 qgl->setColumnMinimumWidth(col, minsize); #else qgl->addColSpacing(col, minsize); #endif } void GuiGridLayout::set_row_minsize(int row, int minsize) { #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 qm=new QMenu(parent); #else qpm=new QPopupMenu(parent); #endif } GuiPopupMenu::~GuiPopupMenu() { /* // never deleted #ifdef QT_VERSION_POST3 delete qm; #else delete qpm; #endif */ } void GuiPopupMenu::insert_item(const char* text, const QObject* receiver, const char* member, int accel) { #ifdef QT_VERSION_POST3 qm->addAction(text, receiver, member, accel); #else id++; qpm->insertItem(text, receiver, member, accel, id); #endif } void GuiPopupMenu::insert_separator() { #ifdef QT_VERSION_POST3 qm->addSeparator(); #else qpm->insertSeparator(); #endif } void GuiPopupMenu::popup(const QPoint& p) { #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 parent->qtb->addWidget(qcb); #endif } void GuiComboBox::set_current_item(int index) { #ifdef QT_VERSION_POST3 qcb->setCurrentIndex(index); #else qcb->setCurrentItem(index); #endif } int GuiComboBox::get_current_item() const { #ifdef QT_VERSION_POST3 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_POST3 qp->setFont(QFont(_FONT_TYPE_,_FONT_SIZE_)); #endif } GuiPainter::~GuiPainter() { delete qp; } void GuiPainter::moveTo(int x, int y) { #ifdef QT_VERSION_POST3 x_cache=x; y_cache=y; #else qp->moveTo(x,y); #endif } void GuiPainter::lineTo(int x, int y) { #ifdef QT_VERSION_POST3 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_POST3 // 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_POST3 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_POST3 qa->setFont(QFont(_FONT_TYPE_, _FONT_SIZE_)); #endif // setting text color back to normal, even if noedit QPalette pal=qa->palette(); #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 qmw->menuBar()->addSeparator(); #else qmw->menuBar()->insertSeparator(); #endif } void GuiMainWindow::close() { qmw->close(); } /////////////////////////////////////////////////// GuiScroll::GuiScroll(QWidget* child, QWidget* parent) { #ifdef QT_VERSION_POST3 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_POST3 return qsa; #else return qsv; #endif } GuiScroll::~GuiScroll() { #ifdef QT_VERSION_POST3 delete qsa; #else delete qsv; #endif } /////////////////////////////////////////////////// class QDialogDerived : public QDialog { public: QDialogDerived(GuiDialog* user, QWidget *parent, const char* caption, bool modal) : #ifdef QT_VERSION_POST3 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_POST3 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_POST3 qpd->setValue(progr); #else qpd->setProgress(progr); #endif } int GuiProgressDialog::get_progress() const { #ifdef QT_VERSION_POST3 return qpd->value(); #else return qpd->progress(); #endif } void GuiProgressDialog::set_total_steps(int steps) { #ifdef QT_VERSION_POST3 qpd->setMaximum(steps); #else qpd->setTotalSteps(steps); #endif } bool GuiProgressDialog::was_cancelled() const { #ifdef QT_VERSION_POST3 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_POST3 qi=new QImage( data, width, height, QImage::Format_Indexed8); qi->setColorCount (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_POST3 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_POST3 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_POST3 if(qtrw) return qtrw; if(qtw) return qtw; return 0; #else return qlv; #endif } GuiListView::~GuiListView() { delete sd; #ifdef QT_VERSION_POST3 if(qtrw) delete qtrw; if(qtw) delete qtw; #else delete qlv; #endif } ///////////////////////////////////////////////// #ifndef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 if(qtwi) return c_str(qtwi[0].text()); #else if(qcli) return c_str(qcli->text()); #endif return ""; } GuiListItem::~GuiListItem() { #ifdef QT_VERSION_POST3 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_POST3 tablemap=new STD_map; #else listmap=new STD_map; #endif } void GuiListItem::destroy_static() { #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 return qtb->isChecked(); #else return qtb->isOn(); #endif } void GuiToolButton::set_on(bool flag) { #ifdef QT_VERSION_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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_POST3 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-2.0.3/odinqt/odinqt_callback.h0000644000000000000000000000554012732216521014122 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-2.0.3/odinqt/stringbox.cpp0000644000000000000000000000204512732216521013357 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-2.0.3/odinqt/ldrblockwidget.h0000644000000000000000000001024212732216521014003 00000000000000/*************************************************************************** ldrblockwidget.h - description ------------------- begin : Mon Aug 5 2005 copyright : (C) 2000-2015 by Thies H. Jochimsen email : thies@jochimsen.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 LDRBLOCKWIDGET_H #define LDRBLOCKWIDGET_H #include #include "odinqt.h" #include class LDRwidgetDialog; // forward declaration //////////////////////////////////////////////////////////// class LDRblockGrid : public QWidget { Q_OBJECT public: LDRblockGrid(LDRblock& 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 LDRblockScrollView; void createDialog(); GuiGridLayout* grid; LDRblock& val; STD_list subdialogs; }; //////////////////////////////////////////////////////////// class LDRblockScrollView : public QObject { Q_OBJECT public: LDRblockScrollView(LDRblock& block, unsigned int columns=1, QWidget *parent=0, const char* omittext=""); ~LDRblockScrollView(); // QSize gridsize() const {return ldrgrid->frameSize();} QWidget* get_widget() {return scroll->get_widget();} signals: void valueChanged(); public slots: void updateWidget() {ldrgrid->updateWidget();} void deleteDialogs() {ldrgrid->deleteDialogs();} void swapSliderTracking() {ldrgrid->swapSliderTracking();} void emitValueChanged() {emit valueChanged();} private: friend class LDRblockWidget; void createDialog() {ldrgrid->createDialog();} GuiScroll* scroll; LDRblockGrid* ldrgrid; }; //////////////////////////////////////////////////////////// class LDRblockWidget : public QGroupBox { Q_OBJECT public: LDRblockWidget(LDRblock& ldrblock,unsigned int columns=1,QWidget *parent=0,bool doneButton=false,bool is_dialog=false,const char* omittext="", bool storeLoadButtons=false, bool readonly=false); ~LDRblockWidget(); // QSize gridsize() const {if(ldrscroll) return ldrscroll->gridsize(); else return QSize();} signals: void valueChanged(); void doneButtonPressed(); public slots: void updateWidget() {if(ldrscroll) ldrscroll->updateWidget();} void deleteDialogs() {if(ldrscroll) ldrscroll->deleteDialogs();} void swapSliderTracking() {if(ldrscroll) ldrscroll->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; LDRblock& parblock; LDRblockScrollView* ldrscroll; GuiListView* noeditlist; STD_vector noedititems; }; //////////////////////////////////////////////////////////// class LDRwidgetDialog : public QObject, public GuiDialog { Q_OBJECT public: LDRwidgetDialog(LDRblock& ldr,unsigned int columns=1,QWidget *parent=0, bool modal=false, bool readonly=false); ~LDRwidgetDialog(); public slots: void updateWidget(); void emitChanged(); private: GuiGridLayout *grid; LDRblockWidget *ldrwidget; private slots: void callDone(); signals: void finished(); void valueChanged(); }; #endif odin-2.0.3/odinqt/float2d.h0000644000000000000000000000767112732216521012352 00000000000000/*************************************************************************** float2d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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, bool disable_scale, 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; void write_legend(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 xpos, 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 get_scale_size() const; // takes disable_scale into account bool disable_scale_cache; GuiPainter* roi_painter; mutable QPixmap* maplegend_pixmap; unsigned char* imagebuff; unsigned int len; const float* data_cache; unsigned int nx_cache; unsigned int ny_cache; mutable int scale_size_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-2.0.3/odinqt/floatedit.h0000644000000000000000000001121212732216521012754 00000000000000/*************************************************************************** floatedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/floatedit.cpp0000644000000000000000000001424612732216521013321 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-2.0.3/odinqt/odinqt.h0000644000000000000000000003453012732216521012307 00000000000000/*************************************************************************** odinqt.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/Makefile.am0000644000000000000000000000231312732216521012666 00000000000000 libodinqt_la_LDFLAGS = -no-undefined -release $(VERSION) $(GUILIBS) libodinqt_la_LIBADD = ../odinpara/libodinpara.la if GUI_ENABLED AM_CPPFLAGS = $(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 \ ldrwidget.h \ ldrblockwidget.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 \ ldrwidget.h ldrwidget.cpp ldrwidget_moc.cpp \ ldrblockwidget.h ldrblockwidget.cpp ldrblockwidget_moc.cpp dist-hook: -rm -rf $(distdir)/*_moc.cpp endif clean-local: -rm -f *_moc.cpp odin-2.0.3/odinqt/ldrwidget.cpp0000644000000000000000000007716312732216521013342 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 "ldrwidget.h" #include "ldrblockwidget.h" #include #include #include #include #include /** * * Helper class to analayze the value range of a (scalar) LDR parameter */ class RangeHelper { public: double minval; double maxval; RangeHelper(const LDRbase& 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; } }; ///////////////////////////////////////////////////////////////////////// LDRwidget::LDRwidget(LDRbase& ldr,unsigned int columns, QWidget *parent, bool doneButton, const char* omittext, bool storeLoadButtons ) : QWidget(parent), val(ldr) { Log odinlog(&val,"LDRwidget(...)"); 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; /*---------------- LDR types BEGIN ------------------------*/ /*---------------- LDRblock ------------------------*/ LDRblock* dumblock=0; dumblock=ldr.cast(dumblock); if(dumblock) { label_cut=false; if(dumblock->is_embedded()) cols=2; blockwidget=new LDRblockWidget(*dumblock,columns,vport,doneButton,false,omittext,storeLoadButtons); ODINLOG(odinlog,normalDebug) << "LDRblock: LDRblockWidget 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) << "LDRblock: set_widget done" << STD_endl; connect(blockwidget,SIGNAL(valueChanged()),this,SLOT(emitValueChanged())); connect(blockwidget,SIGNAL(doneButtonPressed()),this,SLOT(emitDone())); ODINLOG(odinlog,normalDebug) << "LDRblock: connect done" << STD_endl; } ODINLOG(odinlog,normalDebug) << "LDRblock done" << STD_endl; /*---------------- LDRint ------------------------*/ int* dumint=0; 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(changeLDRint( 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(changeLDRint( int ))); connect(this,SIGNAL(newintval( int )),intedit,SLOT(setintLineBoxValue( int ))); } } ODINLOG(odinlog,normalDebug) << "LDRint done" << STD_endl; /*---------------- LDRfloat & LDRdouble ------------------------*/ float* dumfloat=0; dumfloat=ldr.cast(dumfloat); double* dumdouble=0; 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(changeLDRfloat( 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(changeLDRfloat( float ))); connect(this,SIGNAL(newfloatval( float )),floatedit,SLOT(setfloatLineBoxValue( float ))); } } ODINLOG(odinlog,normalDebug) << "LDRfloat & LDRdouble done" << STD_endl; /*---------------- LDRenum ------------------------*/ LDRenum* dumenum=0; 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(changeLDRenum( int ))); connect(this,SIGNAL(newenumval( int )),enumwidget,SLOT(setValue( int ))); ODINLOG(odinlog,normalDebug) << "connect done" << STD_endl; } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRenum done" << STD_endl; /*---------------- LDRbool ------------------------*/ bool* dumbool=0; 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(changeLDRbool( bool ))); connect(this,SIGNAL(newboolval( bool )),boolwidget,SLOT(setToggleState( bool ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRbool done" << STD_endl; /*---------------- LDRaction ------------------------*/ LDRaction* dumaction=0; 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(changeLDRaction())); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRaction done" << STD_endl; /*---------------- LDRfloatArr ------------------------*/ farray* dumfarray=0; dumfarray=ldr.cast(dumfarray); if(dumfarray) { create_or_update_floatArrwidget(*dumfarray,true); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRfloatArr done" << STD_endl; /*---------------- LDRdoubleArr ------------------------*/ darray* dumdarray=0; 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) << "LDRcomplexArr done" << STD_endl; /*---------------- LDRfunction ------------------------*/ LDRfilter("dummy"); // created dummy to force initialization of registered_functions (in USING_WIN32/DLL) ODINLOG(odinlog,normalDebug) << "Testing for function" << STD_endl; LDRfunction* dumfunc=0; 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(changeLDRfunction( int ))); connect(funcwidget,SIGNAL(edit()), this,SLOT(editLDRfunction())); connect(funcwidget,SIGNAL(info()), this,SLOT(infoLDRfunction())); connect(this,SIGNAL(newfuncval( int )),funcwidget,SLOT(setValue( int ))); ODINLOG(odinlog,normalDebug) << "connect done" << STD_endl; } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRfunction done" << STD_endl; /*---------------- LDRstring ------------------------*/ STD_string* dumstring=0; 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(changeLDRstring( const char* ))); connect(this,SIGNAL(newstringval( const char* )),stringwidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRstring done" << STD_endl; /*---------------- LDRfileName ------------------------*/ LDRfileName* dumfileName=0; 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(changeLDRfileName( const char* ))); connect(filenamewidget,SIGNAL(stringBoxButtonPressed()), this,SLOT(browseLDRfileName())); connect(this,SIGNAL(newfilenameval( const char* )),filenamewidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRfileName done" << STD_endl; /*---------------- LDRformula ------------------------*/ LDRformula* dumformula=0; 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(changeLDRformula( const char* ))); connect(formulawidget,SIGNAL(stringBoxButtonPressed()), this,SLOT(infoLDRformula())); connect(this,SIGNAL(newformulaval( const char* )),formulawidget,SLOT(setstringBoxText( const char* ))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRformula done" << STD_endl; /*---------------- LDRtriple ------------------------*/ LDRtriple* dumtriple=0; 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(changeLDRtriple(float,float,float))); connect(this,SIGNAL(newtripleval(float,float,float)),triplewidget,SLOT(setfloatLineBox3DValue(float,float,float))); } else cast_success=false; ODINLOG(odinlog,normalDebug) << "LDRtriple done" << STD_endl; /*---------------- LDR types swith END ------------------------*/ if(!cast_success) { ODINLOG(odinlog,normalDebug) << "Unable to proces parameter >" << ldrlabel << "<" << STD_endl; } return; } void LDRwidget::write_pixmap(const char* fname, const char* format, bool dump_all) const { if(floatArrwidget2) floatArrwidget2->write_pixmap(fname, format, dump_all); } void LDRwidget::write_legend(const char* fname, const char* format) const { if(floatArrwidget2) floatArrwidget2->write_legend(fname, format); } void LDRwidget::write_map_legend(const char* fname, const char* format) const { if(floatArrwidget2) floatArrwidget2->write_map_legend(fname, format); } LDRwidget::~LDRwidget(){ // 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 LDRwidget::get_label() const {return val.get_label();} void LDRwidget::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 LDRwidget::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 LDRwidget::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(changeLDRfloat( 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, !dispscale.enable,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 LDRwidget::emitValueChanged() { emit valueChanged(); } void LDRwidget::emitDone() { emit doneButtonPressed(); } void LDRwidget::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=0; dumfloat=val.cast(dumfloat); double* dumdouble=0; dumdouble=val.cast(dumdouble); float floatval=0.0; if(dumfloat) floatval=(*dumfloat); if(dumdouble) floatval=(*dumdouble); emit newfloatval( floatval ); } if(enumwidget) { LDRenum* dumenum=0; dumenum=val.cast(dumenum); if(dumenum) emit newenumval( dumenum->get_item_index() ); } if(boolwidget) { bool* dumbool=0; dumbool=val.cast(dumbool); if(dumbool) emit newboolval(*dumbool); } if(complexArrwidget) { carray* dumcarray=0; 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=0; dumfarray=val.cast(dumfarray); if(dumfarray) { create_or_update_floatArrwidget(*dumfarray,false); } darray* dumdarray=0; 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=0; dumstring=val.cast(dumstring); if(dumstring) { const char* str=dumstring->c_str(); ODINLOG(odinlog,normalDebug) << "str=" << str << STD_endl; emit newstringval(str); } } if(filenamewidget) { LDRfileName* dumfileName=0; dumfileName=val.cast(dumfileName); if(dumfileName) emit newfilenameval( dumfileName->c_str() ); } if(formulawidget) { LDRformula* dumformula=0; dumformula=val.cast(dumformula); if(dumformula) emit newformulaval( dumformula->c_str() ); } if(triplewidget) { LDRtriple* dumtriple=0; dumtriple=val.cast(dumtriple); if(dumtriple) emit newtripleval( (*dumtriple)[0],(*dumtriple)[1],(*dumtriple)[2] ); } } void LDRwidget::deleteDialogs() { emit deleteSubDialogs(); for(STD_list::iterator it=subdialogs.begin(); it!=subdialogs.end(); ++it) { (*it)->hide(); // delete (*it); } subdialogs.clear(); } void LDRwidget::changeLDRint( int newval ) { int* dumint=0; dumint=val.cast(dumint); if(dumint) (*dumint)=newval; long* dumlong=0; dumlong=val.cast(dumlong); if(dumlong) (*dumlong)=newval; emit valueChanged(); } void LDRwidget::changeLDRfloat( float newval ) { Log odinlog(&val,"changeLDRfloat"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; float* dumfloat=0; dumfloat=val.cast(dumfloat); if(dumfloat) (*dumfloat)=newval; double* dumdouble=0; dumdouble=val.cast(dumdouble); if(dumdouble) (*dumdouble)=newval; farray* dumfarray=0; dumfarray=val.cast(dumfarray); if(dumfarray && dumfarray->length()) dumfarray[0]=newval; darray* dumdarray=0; dumdarray=val.cast(dumdarray); if(dumdarray && dumdarray->length()) dumdarray[0]=newval; // STD_string dummy=LDRdouble(newval).printvalstring(); // val.parsevalstring(dummy); ODINLOG(odinlog,normalDebug) << "val=" << val.printvalstring() << STD_endl; emit valueChanged(); } void LDRwidget::changeLDRenum( int newval ) { LDRenum* dumenum=0; dumenum=val.cast(dumenum); if(dumenum) dumenum->set_item_index(newval); emit valueChanged(); } void LDRwidget::changeLDRbool( bool newval ) { bool* dumbool=0; dumbool=val.cast(dumbool); if(dumbool) (*dumbool)=newval; emit valueChanged(); } void LDRwidget::changeLDRaction() { LDRaction* dumaction=0; dumaction=val.cast(dumaction); if(dumaction) dumaction->trigger_action(); emit valueChanged(); } void LDRwidget::changeLDRfunction( int newval ) { Log odinlog(&val,"changeLDRfunction"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; deleteDialogs(); LDRfunction* dumfunc=0; dumfunc=val.cast(dumfunc); if(dumfunc) dumfunc->set_function(newval); emit valueChanged(); } void LDRwidget::changeLDRstring( const char* newval ) { Log odinlog(&val,"changeLDRstring"); ODINLOG(odinlog,normalDebug) << "newval=" << newval << STD_endl; STD_string* dumstring=0; 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 LDRwidget::changeLDRfileName( const char* newval ) { LDRfileName* dumfilename=0; dumfilename=val.cast(dumfilename); if(dumfilename) { STD_string newvalstr(newval); (*dumfilename)=newvalstr; } emit valueChanged(); } void LDRwidget::changeLDRformula( const char* newval ) { LDRformula* dumformula=0; dumformula=val.cast(dumformula); if(dumformula) (*dumformula)=newval; emit valueChanged(); } void LDRwidget::changeLDRtriple( float xval,float yval,float zval ) { LDRtriple* dumtriple=0; dumtriple=val.cast(dumtriple); if(dumtriple) { (*dumtriple)[0]=xval; (*dumtriple)[1]=yval; (*dumtriple)[2]=zval; } emit valueChanged(); } void LDRwidget::browseLDRfileName() { Log odinlog(&val,"browseLDRfileName"); LDRfileName* dumfilename=0; 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 LDRwidget::infoLDRformula() { LDRformula* dumformula=0; 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 LDRwidget::editLDRfunction() { LDRfunction* dumfunc=0; dumfunc=val.cast(dumfunc); if(dumfunc) { LDRwidgetDialog* dlg=new LDRwidgetDialog(*(dumfunc->get_funcpars_block()),1,vport); subdialogs.push_back(dlg); connect(dlg,SIGNAL(valueChanged()), this,SLOT(emitValueChanged())); } emit valueChanged(); } void LDRwidget::infoLDRfunction() { LDRfunction* dumfunc=0; 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-2.0.3/odinqt/enumbox.cpp0000644000000000000000000000271112732216521013015 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-2.0.3/odinqt/plot.h0000644000000000000000000001060412732216521011763 00000000000000/*************************************************************************** plot.h - description ------------------- begin : Mon Aug 1 2005 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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); // TODO: Use ArrayScale::enable to control this setting 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-2.0.3/odinqt/float1d.h0000644000000000000000000000361212732216521012340 00000000000000/*************************************************************************** float1d.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/enumbox.h0000644000000000000000000000323512732216521012464 00000000000000/*************************************************************************** enumbox.h - description ------------------- begin : Tue May 29 2001 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/odinqt/ldrwidget.h0000644000000000000000000001502512732216521012774 00000000000000/*************************************************************************** ldrwidget.h - description ------------------- begin : Mon Apr 15 2002 copyright : (C) 2000-2015 by Thies H. Jochimsen email : thies@jochimsen.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 LDRWIDGET_H #define LDRWIDGET_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 LDRbase; class intScientSlider; class intLineBox; class floatScientSlider; class floatLineBox; class enumBox; class buttonBox; class floatBox1D; class floatBox3D; class complexfloatBox1D; class stringBox; class floatLineBox3D; class LDRwidgetDialog; class LDRblockWidget; class LDReditCaller; /////////////////////////////////////////////////////////////// /** * * This class produces a widget according to a given Labeled Data Record (LDR) or a block * of them so that the parameter(s) can be edited interactively */ class LDRwidget : 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 * */ LDRwidget(LDRbase& ldr,unsigned int columns=1, QWidget *parent=0, bool doneButton=false, const char* omittext="", bool storeLoadButtons=false); ~LDRwidget(); // members for 2D/3D plot void write_pixmap(const char* fname, const char* format, bool dump_all=false) const; void write_legend(const char* fname, const char* format) 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 changeLDRint( int ); void changeLDRfloat( float ); void changeLDRenum( int ); void changeLDRbool ( bool ); void changeLDRaction(); void changeLDRfunction( int ); void changeLDRstring(const char*); void changeLDRfileName(const char*); void browseLDRfileName(); void changeLDRformula(const char*); void changeLDRtriple(float,float,float); void infoLDRformula(); void editLDRfunction(); void infoLDRfunction(); 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; LDRblockWidget* 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; LDRbase& val; STD_string ldrlabel; STD_string ldrlabel_uncut; bool label_cut; STD_list subdialogs; unsigned int rows,cols; }; #endif odin-2.0.3/odinqt/float3d.cpp0000644000000000000000000000774512732216521012710 00000000000000#include #include // for LDRfileName #include "float3d.h" floatBox3D::floatBox3D(const float *data, float lowbound, float uppbound, long int nx, long int ny, long int nz, bool disable_scale, 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,disable_scale,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) { LDRfileName dumpfname(fname); STD_string dumpprefix=dumpfname.get_dirname()+SEPARATOR_STR+dumpfname.get_basename_nosuffix(); for(unsigned 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-2.0.3/odinqt/stringbox.h0000644000000000000000000000323112732216521013022 00000000000000/*************************************************************************** intedit.h - description ------------------- begin : Sun Aug 27 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/docs/0000755000000000000000000000000013010330627010337 500000000000000odin-2.0.3/docs/Makefile.in0000644000000000000000000004413213010312545012327 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-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 \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ distdir am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in 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@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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 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. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ 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" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 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; \ $(am__define_uniq_tagged_files); \ 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-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ 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" cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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 \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ check-am clean clean-generic clean-libtool cscopelist-am ctags \ ctags-am 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-am uninstall uninstall-am .PRECIOUS: Makefile # 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-2.0.3/docs/tutorials/0000755000000000000000000000000013010330627012365 500000000000000odin-2.0.3/docs/tutorials/Makefile.in0000644000000000000000000003263713010312545014364 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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 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: ctags CTAGS: cscope cscopelist: 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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 cscopelist-am ctags-am 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 \ tags-am uninstall uninstall-am .PRECIOUS: Makefile @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-2.0.3/docs/tutorials/main.tex0000644000000000000000000007167112732216512013775 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{LDRint} 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{}LDRfloat\normalfont~ and \tt{}LDRdouble\normalfont. Composite types are also available, such as \tt{}LDRstring\normalfont, \tt{}LDRcomplex\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-2.0.3/docs/tutorials/Makefile.am0000644000000000000000000000217612732216512014355 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-2.0.3/docs/homepage/0000755000000000000000000000000013010330627012124 500000000000000odin-2.0.3/docs/homepage/index.wml0000644000000000000000000001173112732216512013705 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-2.0.3/docs/homepage/platforms.wml0000644000000000000000000000233712732216512014607 00000000000000#include "head.wml" 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/7 (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:

  • ISMRM Raw Data Format (ISMRMRD) to be reconstructed with odinreco
  • #include "formats.wml"

    #include "tail.wml" odin-2.0.3/docs/homepage/Makefile.in0000644000000000000000000003371113010312545014115 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) am__DIST_COMMON = $(srcdir)/Makefile.in DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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 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 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: ctags CTAGS: cscope cscopelist: 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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 cscopelist-am ctags-am 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 \ tags-am uninstall uninstall-am .PRECIOUS: Makefile @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 $$(ls ../../sequences/odin*.cpp | grep -v odin2idea); 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 | grep -o \(.*\) | sed s/^\(/\/ | sed s/\)$$/\<\\/li\>/ | sort -u >> formats.wml @ONLY_LIBS_FALSE@homepage: 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 formats.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-2.0.3/docs/homepage/download.wml0000644000000000000000000000366312732216512014412 00000000000000#include "head.wml"

    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://svn.code.sf.net/p/od1n/code/trunk/odin
    
    or download a tarball with the recent code.

    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-2.0.3/docs/homepage/tail.wml0000644000000000000000000000336512732216512013533 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-2.0.3/docs/homepage/head.wml0000644000000000000000000000557212732216512013505 00000000000000 ODIN - Object Oriented Development Interface for NMR


    Navigation

    Introduction

    Platforms

    Download

    Documentation

    Sequences

    Manual

    Browse Code

    Mailing List

    Authors




    Search:



    Screenshots:






    odin-2.0.3/docs/homepage/logo.jpg0000644000000000000000000003324412732216512013522 00000000000000ÿØÿàJFIFÿÛC    $.' ",#(7),01444'9=82<.342ÿÛC  2!!22222222222222222222222222222222222222222222222222ÿÀ€"ÿÄÿÄR !1"AQaq2‘¡#±³Ñð6BRSbu37Ut‚’“²Á$&CTrƒÓáñ%4Ec”£ÂÿÄÿÄ9!1AQq"a‘Á2BR¡±Ñð#3ÂñDbr‚áÿÚ ?ä´uên˜wP3j‚Ò\Y=5䥵6•áÆ?8O~Í9ýŽ‘i›Ý‚ã¼W&1””tVÒñܤdmAVääcÏ /X½H?`L(ÊC©ye2ÙP-•y ’GIC9ω'þ­8UEÞ«,ˆoÎ`ÚåDZƒIl¡×Å B‚ÉÀSÝø ÉÀ»åË‹¶ôZgªk)ÞädÆYq ã’œdGQëCvöœÓ².aõõ˜–Üu3Óð”­ RT»¿æÔ1·Ìsé.›Ý²^‰f˜©l!¦Û*}–RéÞ‡d¨$$­<Èç §9ÈhåÎ ÖK«+vi›.{r›€è)HpxÝÜ Qê’NÞéþׄ±nœ§”ȇ º‡“H +r]9cíªÀïÁô©9zZìðã¢×fHŠd¹E_Q¡Õ[|§¾< äö‡Ö]z¦ÕÕ¹¼†¦—®’—"A)NÖC>Ú’‘ŸO_ ’øÆŒ[Ôv¸öæ­Œ¸ùa¶[ðýµ—‰R\}Xé-e ÿÚÝ‘·ÂާSõÛV†XJ·²TžŒT#rÊØœv*ÈÚœAϧrW jŸq•1eEOº·U¼‚¬¨ç’çÈ©׈æH—-™JmÆu°U6¤Èüâwgû~e'*P Qgº.s‘m˜©m§rØ (¸‘Ç%8ȼR×;;Ö÷§ ©lE˜¨Þ’€Z†îÇ”ƒ„ƒ‚sÈïɧîÝmÛQi[’Ѥ·²Ha%k)SÊÁox~|Œî?cû\'qºAšÅä¥RìÛ€”Ò IÚ:œ(îàþpöì÷ç€"×mœÒÚC¤¡O,¶ÐSJjiJxäƒÁβ›UÅr×0%*Jå²QZG”ã r>ñS/j&¤\.R\¯ùÜä¾…øT¤¶êpA8PĈ9šÂ/Ó×a%ieΚƒŠ†Ó );òÊŽÔ\'…pAÀXH¬ÛæÈŒ¹,Ãävó½Ô4¢”àdäÍlˆKr_IQ[¯†i)Ü\8ʱL£=Üv5.Íâ<Ù/9)ÄyIiå>0´º¬(m”Tá#‘Ǭzî ªAu¸­“A nKx e'Âs’TžŠ•Û4tÛg*R⦓!rš +zG‘ŒŽãï­ƒ-øëÔWÜeÞâ%)ÀÉÉì8©tÞ"§¬ÊJÒÒúj TVܧ~BZQÚ€JÉàðAÀXµuf\‡\’…‡ƒRÛ¥Ô…¥ÅaCo*%dp@äqêR¢ºÇErYy–]ÁJËgÄž9Nqž­86ô&å2žVXíPGÚ(óÏ >´æ]Æð}Õ¶ÖÒTòð²± (mÈÁY¾Ò?4ÌØŠ½K–TðeàîÜ6 X#‘»n>|ããÀtòD#b™yJCAÅ¡/δ‘Ÿ–{ã8øö¤’ˆÆŠS® !`!>žrsûýsé™”ìÅ:^)z@u=³´àrxû@yããÚ€bëkeÂÚÓ…¯×>cãZR<§” 0”§²G ýþ=é:¢Š(Š(  (¢€(¢Š¢Š(iÇâÚ”–Ó¹d'!# dú >dRujÓ'ÝØˆØÿêóLT8RذžzáX<4’AòªžôEPQ@QEQEEPQ@QEQEIXìMIrM¾Ñ r¥•ìI HîJ‰Ã$÷ w"€¥aéR¥¼û«m¶ÒT¥¨œä’|«µY?ƒò‚ÃšŠøÚrÌ’Tœpz‹=ÆÃÀïÏBϤì:*Ò¡b‚Ûr‹–³½÷2r¾àv§ Ï Ï–d¾ú· ¦ÒÊr—MÌnPÇJÏ Îvíàóž*Ïø>ÜÔóŸ•u®+ A!QR·×»#‚•`c<çÓŽr:k×¥KlåÕuLjäŒyUj~¦™ô÷‰G€æ€§ß½†Lg~]šì«¬¦|F‡Ò[ˆÁ'f­ÊöðHÎ2F WIû6Ô§Q7j÷)”%é%2¤Z$áX8ÜNHÈ<€ ÒáM¥•8¥)i’£É'ÿsSy…†Il`»öÔ;œv¸ÿÛƒq’«^¤‰%ò¼IަƒÈRJÉ=¸Ç™çŽy. Ò×Í+0E½Û_†â¾ÁXp Ú±”«†pN3ƒÍznÛ©×C’‚ˆÚ{åV_Ê‘nUk-¸ÃÉØãn$) r’cËã@x¢ŠôÆ¥ö¦/+zM­Ç­œä%œ-ÅY'¦y%IŒ©ô•çH\D;¼`Ù^â˨PSn¤nI~d ÐtQEQEEPyÓ™PŸ††òR! óE+JÂIàœ‚0yhÔQEQJÇŽì§ÒË(ܵgŒ€$’x ’O šÞTG¡ºx$'rT…¥iPõ I Œ‚8=ÁF€oEîMºTFÂÞm gj‚\JŠý€IIà𬡠QE*Ë.HYCIÜ …,Œã„¤¨Ÿ¸@%El¤- B”•$,nI#†HÈú‚>•­Q[( ,¤ì$€¬pHÆGâ>úq*ðóÖè…m)KÈRô Gj­¸ie•:* 'МãôÒ€(¢Š¢ŠÙSŠÚ‘’WÐ ŸÀPÑ[¶Ò*”¤¨äÀïZí;J°p  1EºS™ÛŒäÞh (¬RH ‚8 Ö(Š(  (¢€+"±Y &%Û}ªÌ¦—¶B_vkKJžþ{™QÇlñ¥å†¢ß.ØFÆZ’✓„…O·º±íŒ+‡†7MÎ-ÄýéZO×Ö±z9œ×ù¤oÔ"€¢Š(Š(  (¢€(¢Š¢Š(Š(  («_³ý.M¨‚%¶µ[¢ ½(¤”îÍFà8$üްr( íì©ëôCt¾®L i@qØORBHW ’v`„‘”Á\z×f´K·Ú#u–ßt ìBq’”{©X$œñɨ—fõˆÀi†Ðm¤Œ%)ä1M­w5D¸­.§’rAÅaºÝ €µ“È·ïû)â'É C„øÓ‘Çnj­©äøÚq*ð+j’G˜­\¿5Ô„)@'É4=òY‰4­*) =³Q^÷«Ão9©ç·¦+‘##ìî8øÔ•ªÉ6Jà!”Ÿrhe¸e䯂@üEL^&¥ÒƒŒ“ž~F©–ïDy(qAgx §÷øU‚\莨²êŽGž2( & Ð˜TÖB9O5-§¯òîxŠP|*P<|8õ¤5%•DSñÔ•( äv4Ë@É =#¶Gˆªh¢«Š!!–VVG8¬LrÝq€YœÃ¢¸FæŸl-'<¤ñÁ橎ÉzDÅ-D; Úd΀i’FIÏïøPý[ì† Ò4š‹/¤Ð_t”(ñÓR¹ È죃»¸<˱ßq‡Û[N¶¢…¶´”©*{kÒfaƒ%GÓ±íT¿iZi:§5š%Çc2Zà›H'xÄEVàm~0ëŽ% !· ecqÈàŠ®Ñ@]U»ò‚Wþ£±“ÕË‘ÕÓ^õ¤„²¬Œ€O*ÁRŒvø¦Í%)Eµ) p…¥@’rv¤ްò ¤”ý¡öÍW( [][SÐ[[)QJ‘ùã„()%%$ùFr1œäwÑEµ…»¶uE³yê£nÝÛ†7c\ñ/p.›ƒýnŸSyÝÓÆÜü?|úóM¨ $rÒ ³¼³…4¢QÓñ•nPv=qçå÷ªßEHq `­E¡”ð’…ã¿r8?ZŠ*$I!#'°¬PÓ´È´ÑXY JS¸…Œqا·í¦éÁs;2r7c?v¤( ÉÇ;z[7~on7møãéߟƴdªNP8;V¬}s‘ëøÒ4P < ¢Hç“çÉÇáŠNŠ(Š(  (¢€(¢¶BâÒ„$©j8JR2IôëÑÅÑÆÚa ÇQò*m A#ᔜ|+½›{ÊåÇ"ç×jÔ„ýÉBGÒ´»8—o3œB‚¹)*IÈ ¨ò+2ORÛÞÛ:Œc× ßŸÿf1ðøÐ ¨¢Š¢Š(Š(  (¢€(¢Š¢Š(»>ƒ·.Õ¡‘ ¶CÓ/,–ö¨$xP’{”ðToÔó­!`Eêæ\”œÛâáR^Ò¬çjGŸ$sÛ€yÔ$_ÜiÜ¥d~ÊO|¨ ^—qŽ¢âÎ|ª"]æQwzÚ(ZprjÀÕî$€: Ÿ2ž? fß-²7 žÝAÜ|è'µ:¦FCO6Sæ=;Ôl»‚¤¤ç9¤®±“ QKg(=©†óÿµ1ce¹WVáFUƒçŠèéî®&;$¤÷À®VÄ•Çp8ƒ…$‚1S°nŠZ÷¸¬­\s@t¸s’ðWmþd ó¨œyjXS) G˜ßšÞÝÂB” qåŸ>(~î¦_Ú²Jˆ‡á@@½}› % Þ¡€¿Ze¥ætnë %;ÆÙR:ˆG‘n‡ c±ªQ|¥ÍÉQv ó@uDIJßpàäç÷ô¨)W@íä’¬¥ºª3u’ÁVRó<ÒlÉZ¥J”¡»šÞì—¦É*)Ï „ ¦Ÿm.4´”­ HRT’0A¸¨ög1 sÑÙ4"ñ*kÉZBÂAàç@(M©íéµêYñTP‡w$©IÚ 8G„ 1Ž<“ØDÕÿÚt7Ì›uÁm«j™,)yÈ(|ùÁàcšQEE;&ѧŸGNK²àGY@õ‚Pµ'Â8#=þÐäyEL¥–"Ùs!§ÕÖ-8R•„rðe'Œ÷Ò/¡Qíó¢u ÐÔÄä2€œygî #(©ve e¸±ÆIIY yíóÎ3çŠM´Ä—JÙSJRQ¸d;±ÈÎp1Ï|r*(¢€(¢Š¢Š(Š(  (¢€(¢Š¢Š(Š(  (¢€(¥}ØÏ%Ö[N'²Ð¢’<»Švowoò¤ßÿ!¶€aE>üµuÿ)Íÿn¯Û[7|º!a_”$/N,­?P¬ƒ@7bÉM•LjûÈiSm•}8*EhSkR’•¤¤¨`‚;‚)Û×kŒ…•»:B‰$ã¨@ô‡Ò•EòbP7«ªâ~ËŽ-eCçâ¿ÒÓ·Yµ!Öú~óÿ=SeÔF “”í pó)$€3Û‚i QÛtŽï“*ë+ââ8øàÓò„ÝÛ½òFìç=UgôÔ‹’ß%ÈCîìSVÒvä$ÿwr‡Í?J¤î´8ÏMôìønJ·}û÷R~û+þÒ÷ûCN#K’ão²d:JV’Vx)ç¿ýÝÃê>€6e”­ uÕ”4‚””î99À#Ðùù|²J`0ñJ\6Fä8Cן¸úE9‘.Cm2Ï]ÝÁ=E+yä¨Ëúæµjé% ––®ªs¸oR²“ð ƒô µCÉ*i‡\H8ÊHÍ%N_¸J}Õ8§–œöJI@+"ã0 £Þ\çÌœ«ïï@5¢—÷Ùö§¿Ú=òWý¥ïõÍ…©•!C÷OÍf±×wúÕÿ¬hè­úÎÿX¿õ`¸µ ¨Bh h¢Š è¤¥:bJÒ”‡,…+1“è2~óëN¤Æ“¹E£‘ߚƕ†¨Úe´«!o¬½‚{g~­9uÇ‘”Ž>b€„Zd¥\îÈô5²dMla p™§‹CÊQW¼Ù½àà  )ÇqYuJ'>tžþjfkH÷u+níPL/?RºÙ¡•§ᙡaµ ã¦/´äw n ¥CÈЛeò)JU+ Æ2ªa|º5%¢¦_J°¾ÃΪ!Uô‹·Þ@BœQHøÓp¿jË.<| 8Í’¡éÚ€Ü/Ê”k{Š!cΚóKG’XVá÷ÐM±0¨(å`ySl^dÇl%0ÊT7 T+:h8Rr>B¤cߢ¸p´#?Šû‰]òÝ"¢ ‡ÐA$•l#”«Ë±:ä6¶œSn!HZIJ’¡‚íí´¨!‚“Ù sT_ \šÞÐ%V‘Æœn8ÇžAù“@Wh¢Š¥’ã²×+;]S…̧ŒsÅ#Eá3æ!JR%¾•+¹O$þ’OÔÒa÷’™¬4£• (í'×¼…'E©’úº{Ÿpô¿ÁågÁòôì+dM’Ûê}2¨©{‰$cÿ~Ô…EPQ@QEQEY´•V°Õ±mŠ*La—¤­=ÒÚ{ãâIëUgÍ å—#¤•³)[¤/£ý_ušºšKR¬.[ùϘOšËêEuX?Áö̆€Ÿyžóže„¡¡÷ª½jMEgö{¥ò™JhbÄg‚µc„AæOé=ø%ÛÛ6±¸ÉRãMnÞÎ|,Çi'â¥OïÅxìz¿ñfç¥k5ÇüÓM‡xö–ì»Ý¿ƒìRÊ•f½<‡@ð¢b‚¾jHûqíC¦nÚZâ`Ý¢)‡{¡]ÐàõJ»ûš¿in7Û|ÆÛ¿m¸ÂQÂÖJ@õ`‘úŠìÚŽÃjö…¤:Am¸Ü†ÃÐåþ DxT>DzdT—‰x…fŒÒ,±$ ¡ö.ì4âóT—’ûÅzOÚuÎm›ÙåÒ}ºBãËk¥±ÔwN]@?"­ñý^ª:¼tÙ:zöøné3£–ä¸*?ƒõH"-ÞäÚ¼‹½5¸%5AվƯÚr+“a¸‹¤&Æå©”¸êQÏ"j:µÍm Ô¯òÁymöP ¯Ã?qÝ}{B®mî…´˜×(ÀuØIÊH=–œó‡—ÜjF_ðµí²Íd‚çû¤Ñ”±Ïe³<§]«Aû Óú£EÛï3¦\Û“'©½,:Ø@Úâ’0 ì‘çUßlºE7ª› Ü+’TàBFoÐrÔúWbö=þ*ìßøÿ¯r¶¼oÅfü7«K'©/å+_TG[Œ3ê{VKu¶°¥©˜“aµ8AQJR À8•ÞÿäJÿ”/?íšÿË®­?—z‡ûÎOëU^¿›1‹t d¯cÚS®+ÂR 'îGâ~«-?°›NIÝwü¿ÔÎ(Å·gµfœ“¥5$»Dœž’²Ó˜ÿÙû*úÇ#Ê¡kÒÞØtzu.˜Mâ“­è.$£ž«=Ô®>Ðúúךk»à¾"µúU7ù–Òõÿé^HtÊŽù¨}ˆé«NšºÜ˜vSÑ!¼ûiqÖÊJ‚ µÀëØÚÓù ¨»$þ©UãšæþÖgÕaÉ,òri®} 犋T¡}Õ2–K«-$ä ¨íåõ¤è¯PP³n-¥…¶µ!C²’pEkE•(©EJ$¨œ’O&±EEPQ@QEQEKDŽeÌf8$u3€O' F¦ôÛ8–¹*KiÚ’¤ôý4®L…´ –PR”ðlR"ôãck¡iø¨f“vz¾R“ñ4ÒTÆVÙNÑÛç@J"ì\8J‡ú¢ Á(å±ÈôÅUqhP85*Ü’¤ágŒqš7 ‰ZƒÜú † ñŒÒ²Ü |$IÑ„ñÜP ,4¤©yÔ’‹7 ^HÞ<Çz®1#r<ùÓØòJNsŠv׵„«'‚)Ì{CMøß_ÈVýÏîÏóqøÒå’­€ð;Ð -ô%¶¼-Ÿ¾¡å®<éU¾<Í2qÞ¡õ 2•gŠ” 5ÑX R° ;.-iÀ p7ä@¤Ò”ž ¦‹* 9Í9f3Š$Œù ë(BHPWn{Ó RæöaBçèE?D`”òqó5¨Ïæâ ƒöû£@@ÑE[´\xÇ=ûŽ?Ò²pÀÐ ôêÎÔpJ‡Ó­:  RR  Ús“ŒçôÇTã))òO8ÿi¡/pAvgôP - §Ûm„„¨€²N3ß´¨gõjˆO98þ"´éÒžJ“ŸÓû(/(’HœóÏÿÞ±Ô>„cæ( ”“ÊHœùçË¿•aMµ’ ¸‚Ÿ–+R¼¤¤¿d¸UœÉ'åšGP:… B2pB‰àzóZ†Ó±Grx# Ï—5©s*ݵ žýù¬ä€Ã÷øÐ-(’çÃçÅv¿àøÃFeõì£m0|ð¢²ÝOÝ\P¸I$“ž}3]#ئ£jÏ­=ÊJ¹5Ð 'Ž 9F~|§ê+‘ãØ§—òÆÕýoø"ÌN¦¬•þ^sSÚá©xŽÔ>ªsÛrÖ  äE¢$gž3é^”öÁ¡äê‹C c][„rÈîóg¸Ú<ò|ñ^lt:ÓªC¨RA)RT0Aç Z×ü7©Å—AAïšùýÌæMNØüi PÁ5é?a’Þ“ìô´êŠ‘c4³„¯ô¬×­vÉ÷«ƒ0-±W"SŠð¡±Ÿ©òÔö¯Wé }¢Ø„ûͧÝÛSҞθø”sè;|…i~-Ïicƒ™¶š]ûïö%>«8ž¢ŽÔá ÊHÁ»Cpàó¹EµÄ×Zö½ƒì¾ðÈ%×·\"èßý±Àº„á2oL-÷ê¤$ô@®íí|ãÙmäút?^ÝhxŽ9cÖh!>WB~©¢pw3ÊêÇ dv®ìZCÑý¥ÁCj!y§óHAWéH®}{–+¹{Ñ3#IsS\XS(SE¨hX”ö—Lp=r~é<: ¾Ñòš^¯êS‰7%D··ö½mx㨉á)?ÚÉÿtU‡Øÿø¬³sŸðÿ¯r¨ŸÂøÚœµXÚX+FéOèämGÿßáW¿cßâ®Íÿú÷+Æj±Ê‡ðõwüªFÄ_ù¬ó–µôïPÿyÉýj«Õ:Óù ¨»$þ©Uåmkü»Ô?ÞrZªõN´þBjîÉ?ªUtѸCê(žÄõ‰»XÍ‚s™•?ór£ËŒñÇú9äG¡®gíOD+ªìr†í³‰v8ÁÂó‘Àò'U±ß%éËÜ+œaè«c<,´“ð#ŠôÅþÛoö¡ìí+ˆ¤“!°üGݧF|'딟­lj“ðZ˜ÿ¥—i|÷¿Õù®è™Öc:P‚@ÿá²y>_šUxû¤ëÛû•û+Ø:Óù ¨»$þ©UãšÇàßô2ú¯ä5¡Nš?¯oîW죦ëÛû•û):+Ùâ4ÿ\¹_²Žš®GܯÙIÑ@oÓOõ¨ûì£b­GÜeiE¾ÄÿZ¸þÊ6'úÄýÇöV”P†Á “óý•¥²ùQ>¼ÐÑEEPNEqLÛÙIô'3Pu$]ÃiH9(NI+ëFï'µ6ưÚ¼Šp©G8øÒO?†øPÏ­02 “Þ[ªóߺK-Œ­¨Î•-?BOÀT%§NL¼[n“£¸Â¶¶y.(…(£áÀ<øO|UÖiç8Í4¾üKXË¥Çr"Š*Nådz×ß-ÉQ]LæËˆC.)°N00|_Ư”ã¢ÞÓk±ETŒT¾¢Ó²ôÌæ¢Mq‡uòK*$m$Žr>Py"¤ Þï‘%Ó’áP$2O`*çÙŽ •·œ÷HŠpe It¥júp~¡›S‹O,’²XñO'äVS+)R ¤’•AÁžÝ¬óìsÕ áL¼‘œB‡¨=ˆ¥lvG¯ÓŒÌ¨±ÔÛEÒ©.$€@À yý5'—³ö—îù˜P—WMnv}í®+±Z¶ê§ 2Q<$”¸?¶ ü{;…T•툺».›m˜êJU%QôF?Qº_Z»¦Ñu*†™®Ï ÊÝs€Fì• ÙÝÏ"¹š½6£R§‘C¥ÒIZ·RNíl«±·‡6,N1êµmÝ|,VuØõÜ{…´X"[%1OÇ~0Æ0@°y#¿~{S‡4­¾î1ÙŽ™1\vSŒ %n„¡³É’yäúš®/[Æ‹m—ÇabÖô´ì}ô¼§R{„äxj_VÞ•a:V=¾k.Ü-1ÈuMÈ¥ Ú~{Oð|ª©aÔG*Ž;ŠwI»¯u«{½­®äÖLN ÊUº«ÝmÛµ–dédN–å¶N‡ÖBÔÆ^G]û*899ôç¿9ª†Ãn³Yï·Ë¬DÜUl’b7G+ Çá•ÿjþ»·,:û:JÚÝÅÐwH_9=ÈAN3õ¨½;«$Ø ¦•™°eÿó^üG¡ú§‹I¬X¤žÜm|Óß~©U­¹_"3ÏÍ5ñÞ¸òÚ—ùš—ONŽÌ“§‹rŽòV„°”û»É•§ŽÏ‘ÿ…X½¦”ܵªÐ”BŒãŒ%Ï|xìÚ XÚ¥c„Œgæj­yÖ Î´›U®Ï× jÞê[;Öáø«ŽÝMun¥þ4ÜØ™îžëÒŽ–6u7ç QÎp?¥ÛáWãÑÍæÇ‘EÅ.®]ÕÕwõÛr¹gD£wuÚ¯›&ôöœjÑ®¬m˸Û&¶ë‹P÷7ú*JrÜ eXÇÊ¡u¬™Ï뙚¥õ¤6~Êðãጮj §\aä<ÒÔ‡ ¤)'$r«ÀöŠÄ¶Ú]ëM@¸Ím &J°’qê6œþŠºx³â̳%×µvO›½öø?B¸Ïñ¼môï~}‰©‰ü¥`Ðo]˜ìæÛPtd¸É^è»Æ…†­icŒ† (÷4©oF é)rÒ•zÀýÅAÁÖìþL÷cvDTìŽã‹Ø´'МŽßuFÍտǺË£Ðj;a)H¸ûYó©âÒë–Y6ëóoç|~§Æß¥QæÓ¸$—–Þ^}¾ìèV;ÅŒûAM’.œÅuÖ˜”ØÃ›•UæA]Éò®mª?•·ŸóçÿXª¶5í6;74\›Ó0Ñ5\H}.áN yx|<ãž}*‘t›ùJï6O§ï/­í›³·r‰Æ|ûÕú 6\yœçÒ–î÷½û²½NXKŠw»|VÅÏ]ñ£ô_ùš¿Ýj¤çB{Pè] Ì÷›"gE.¯•tŽáŸ>*)hVÿÉè3´¼yÊ€Èi·xÀ¥Àâ ïšÆé|ºÆœ¥&?ºb´ÈÂZÁ#Ôð>ê§—RÔ1ôôô¹>«]úª«×{,žlIÊWv’¯Jþ‡NV—m‰È¶3¢á½hÈBæ-ôuÈ=Öw—èªÕ»OAMÏSé°Ë²ƒeèÚK€€»ìSÛÑ^µ½Býòf”·H¹ã™*>c%çïªåºý"ß©½!ê¡î¡m°’t€;  >‹YÑ%7N¶ß™'iþgóâï‚Y5:—Nêÿ‡— î[^±DgOé« ŽÂ.—gƒÏÈS@¸ÛDð2FGqý“ëVÅivØœ‹c:.ÖŒ„.bßG\ƒÝ`çpù~Šå×íS.õ©EéÆu²Ž‚½Ý-½°p3ÎOo:›^¿ƒ!~ù3J[¤\ñÌ• Ž1’Œs÷Ó6Xã·nÛWÄ›ÿʗӅ騷A¹ld¾€UµIh¥%XÎîGŸ>´ŒÙš~’ƒªÑ¦ ªLÕô=ÝCó( ¯*ÛŒ7ÓÌUEzÅù^çi•¼üù~ô¹EÌ`ø8Ûìzùü) š—Þôe¿O{¦ÏsyNõú™ß’³¸ãíúùUðÐgm<–ßVûóŸ_?™Tµ8Õ¨UVÛw¿è\îBÕyÔšmØ‘Ä(·X¦Kì4p¬LîM§K"t·-²tl8v²†¦2ò:èÇÙQÁÉϧ=ùÍsÙzæRÿ‹îBŽ#?gc¢•—7‡|)IÈÀÀ!'Ž{Ó§õݹa×ÙÒVÖî.ƒºBüiÉîB qŸ­U=¹Æ)vMs÷Oó.ÕçèN9ôÉ·öçe·½ùöh6».„¾K¸Ú¢Ü$@¹©„—2Hé¤ Ýöä“>}iâ$»Kj˜¶Xqž~xˆìt tù*HV1Œ‚ÀþÊ£±©Ë:2vŸ17RDƒ#©¿c¸þǯ8cXt4í¢Óî¿'NLί[L)Gn6ñö»äöíWdÐç“”·mÉ÷ۥƸºçæB:Œj—d¼»ß§÷Ú”Ä?¬äGLV[Tt )Ô' w(IÊž3ðâÏþ&uùãï5UKzþ1j W_w÷~¾ÏÍoß·j{àg¶{S˜z—Ý4eÃO{¦ÿ|y.õú˜Ù‚ƒ¸çìzùÖÊÒäZ\8’Þ. üšoûú{h¼Ù&ÞÍJ¾|K´ËšÓÚbBôݾd‰PЧãiTO%{žÜúÕŠÍÚ<˜0!2ÛS-é–ŽZÂÊJSè“Á#à+”ê KùvÙf‡îɱÃú›ºžŒãg·=êx{JÆ«nùù'ìA÷>¼÷ñîÝ»oÓú×?/‡j%†’mµ+ßãqï_ÞæÌ5X”í½•Vß ûzZÆÅâßpÔ¨°Å—)ÇúqmÁIm†À$ƒÇŸo‡Ç„õŽ—ÅE^ž²±gŸÔ¡Öc­*mÔ(€ à‘øü*«§õc–XoÛ¤Ábãl}[×î0¯Tžpx^U‹ö¤tˆÜ;}’²2¸ôÀ[Š?à|+ei5KUÔŸºŸ?öù~oö¿;*öØ^|×ñóãïò:“ïÚíÑ­vx6sK}¢â䥕#…à'³ÉóÍW#A¶Þ5~ª»ÜನÖrá1™NÐò’WâW©; >¤ÔÍ{ïzÞ£ü›³ÝZéû¿_;¸PÎí¼}¯O*cnÖRízšávµ5=ÇôWä©*QVÜúŒ÷ÇÒ¨ÅáÚˆBÒ©8%wÞí«¿.üOUŠR§ÇSíÚ¶þ%ÓG\,ªå-§tµº3ÌÆRÐ[i*AN@9IÜ0~u¦í3JÙæ=ftŸto¬W(nCiÀ8ƒÎ?€¤à{H…j}Õ[´¼X­<ÙK‰mì)Jò;¶öøqçQ–­l#Y›´ÝíîÐÙ9`:­ŠoàƒÅIi5r’ƒPµîõnö}ïÎ^æ|])u.­÷¯O‡—Ày ŸÖZ²Úž Ö丕.k žŸÎF{vµtN–Dén[dèØpíd) LeäuѲ£ƒ“ŸN{óšç3µÅÁûÌð˜b pF#Ge>‚0AõÈãËŠ|þ»·,:û:JÚÝÅÐwH_9=ÈAN3õ¬ê4šÉtôZUçn.ù¾¨ÞÕûÞ^¸Å›¾®oÊ­}Ø©Oˆ¨PÖ ¥Gum<ÊIð®›«ž]=£m鉓rio ôÆè<\€®V¥¨¨÷''а^µJîÖ»Fã˵4P—C»ŠÎƒŒ ¿cãÞº<òdÅ%únßþ¯­ØrÆš}ëùÿBç)í5iÕLi/âÔwØ*m‡%9ËÅk Æœ;çŠÚÍ`µXåëF¥Àbà͹¶Ýd>€¥”-x #ƒŒG¥B£ÚRT¶¦ÊÓðd^FÔN*ÇÈ”ã¿Ô|1QP5œˆÑu %0e?yFÕ½ÔÛÓ8PÎ0sö»qÚ¹«GªxÜi­¢Ÿ½vú“mo¶×åèm<øT“µÞ¶áS¥ñܯ͒™“Ÿ’†a.¸VhaöÐWhÔî³w»ÿå))mÈ~ÕüÉ Rñ÷¦<ëˆURêÇo÷ÈwF#˜NÅe £ï9JŠ‚³ëÛá[úͳdÇѲŠ{ù=«ùø3¬q—Wzù­ì¸j\ŒgL<‚‡[RP´žé ²§Úå•ê&/PIrm¦S²‘ܶãhô²~‚ª:ƒ_.ÿ>É-Ëpev×zªì‡NP£áûõ˜þÐ]­æj$@ðJh6¸½o ”âÛêœöóÅs¡¢Õ% >ôTŸ+—;®{«6e¨ÂÜ£{6¾5&^\q¸ºsRXP-Zm-´¢<ÜRRÏ׊o#J·©ô¶•ßr÷CP¥-ïZÓµ¼”óåëÜU ²v3/Dë»zI _WoHþX9ûÔàëé-ÿU/EvvËJ%ÝÂBHH Œ d'ãßáXÿÕÂW‹gw{sÑOë+\|LþÕ†J§ÅUoûßd7××øº‹R™0·ì²–µ 0IÝš¿ «Ô•úãíwztH䇎å2Þ¼È8Ï¥F×{KbÃ%T¸g74Üò97vQE^VQEÿÙodin-2.0.3/docs/homepage/documentation.wml0000644000000000000000000000076612732216512015455 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-2.0.3/docs/homepage/Makefile.am0000644000000000000000000000342212732216512014107 00000000000000EXTRA_DIST = logo.jpg 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 $$(ls ../../sequences/odin*.cpp | grep -v odin2idea); 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 | grep -o \(.*\) | sed s/^\(/\/ | sed s/\)$$/\<\\/li\>/ | sort -u >> formats.wml homepage: 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 formats.wml wml $(LAYOUTDEFINES) -DVERSION="$(VERSION)" -DDATE="`date +'%b %d %Y'`" $< > $@ odin-2.0.3/docs/Makefile.am0000644000000000000000000000003512732216512012317 00000000000000SUBDIRS = homepage tutorials odin-2.0.3/Makefile.in0000644000000000000000000012217413010312545011402 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) 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 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = SOURCES = DIST_SOURCES = RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ ctags-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 \ tags-recursive uninstall-recursive am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ $(RECURSIVE_TARGETS) \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ cscope check recheck distdir dist dist-all distcheck am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags CSCOPE = cscope am__tty_colors_dummy = \ mgn= red= grn= lgn= blu= brg= std=; \ am__color_tests=no am__tty_colors = { \ $(am__tty_colors_dummy); \ if test "X$(AM_COLOR_TESTS)" = Xno; then \ am__color_tests=no; \ elif test "X$(AM_COLOR_TESTS)" = Xalways; then \ am__color_tests=yes; \ elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \ am__color_tests=yes; \ fi; \ if test $$am__color_tests = yes; then \ red=''; \ grn=''; \ lgn=''; \ blu=''; \ mgn=''; \ brg=''; \ std=''; \ fi; \ } 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__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } am__recheck_rx = ^[ ]*:recheck:[ ]* am__global_test_result_rx = ^[ ]*:global-test-result:[ ]* am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]* # A command that, given a newline-separated list of test names on the # standard input, print the name of the tests that are to be re-run # upon "make recheck". am__list_recheck_tests = $(AWK) '{ \ recheck = 1; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ { \ if ((getline line2 < ($$0 ".log")) < 0) \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \ { \ recheck = 0; \ break; \ } \ else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \ { \ break; \ } \ }; \ if (recheck) \ print $$0; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # A command that, given a newline-separated list of test names on the # standard input, create the global log from their .trs and .log files. am__create_global_log = $(AWK) ' \ function fatal(msg) \ { \ print "fatal: making $@: " msg | "cat >&2"; \ exit 1; \ } \ function rst_section(header) \ { \ print header; \ len = length(header); \ for (i = 1; i <= len; i = i + 1) \ printf "="; \ printf "\n\n"; \ } \ { \ copy_in_global_log = 1; \ global_test_result = "RUN"; \ while ((rc = (getline line < ($$0 ".trs"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".trs"); \ if (line ~ /$(am__global_test_result_rx)/) \ { \ sub("$(am__global_test_result_rx)", "", line); \ sub("[ ]*$$", "", line); \ global_test_result = line; \ } \ else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \ copy_in_global_log = 0; \ }; \ if (copy_in_global_log) \ { \ rst_section(global_test_result ": " $$0); \ while ((rc = (getline line < ($$0 ".log"))) != 0) \ { \ if (rc < 0) \ fatal("failed to read from " $$0 ".log"); \ print line; \ }; \ printf "\n"; \ }; \ close ($$0 ".trs"); \ close ($$0 ".log"); \ }' # Restructured Text title. am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; } # Solaris 10 'make', and several other traditional 'make' implementations, # pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it # by disabling -e (using the XSI extension "set +e") if it's set. am__sh_e_setup = case $$- in *e*) set +e;; esac # Default flags passed to test drivers. am__common_driver_flags = \ --color-tests "$$am__color_tests" \ --enable-hard-errors "$$am__enable_hard_errors" \ --expect-failure "$$am__expect_failure" # To be inserted before the command running the test. Creates the # directory for the log if needed. Stores in $dir the directory # containing $f, in $tst the test, in $log the log. Executes the # developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and # passes TESTS_ENVIRONMENT. Set up options for the wrapper that # will run the test scripts (or their associated LOG_COMPILER, if # thy have one). am__check_pre = \ $(am__sh_e_setup); \ $(am__vpath_adj_setup) $(am__vpath_adj) \ $(am__tty_colors); \ srcdir=$(srcdir); export srcdir; \ case "$@" in \ */*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \ *) am__odir=.;; \ esac; \ test "x$$am__odir" = x"." || test -d "$$am__odir" \ || $(MKDIR_P) "$$am__odir" || exit $$?; \ if test -f "./$$f"; then dir=./; \ elif test -f "$$f"; then dir=; \ else dir="$(srcdir)/"; fi; \ tst=$$dir$$f; log='$@'; \ if test -n '$(DISABLE_HARD_ERRORS)'; then \ am__enable_hard_errors=no; \ else \ am__enable_hard_errors=yes; \ fi; \ case " $(XFAIL_TESTS) " in \ *[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \ am__expect_failure=yes;; \ *) \ am__expect_failure=no;; \ esac; \ $(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT) # A shell command to get the names of the tests scripts with any registered # extension removed (i.e., equivalently, the names of the test logs, with # the '.log' extension removed). The result is saved in the shell variable # '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly, # we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)", # since that might cause problem with VPATH rewrites for suffix-less tests. # See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'. am__set_TESTS_bases = \ bases='$(TEST_LOGS)'; \ bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \ bases=`echo $$bases` RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ */*) \ case '$*' in \ */*) b='$*';; \ *) b=`echo '$@' | sed 's/\.log$$//'`; \ esac;; \ *) \ b='$*';; \ esac am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in AUTHORS COPYING ChangeLog \ INSTALL NEWS README TODO compile config.guess config.sub \ install-sh ltmain.sh missing test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) am__remove_distdir = \ if test -d "$(distdir)"; then \ find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \ && rm -rf "$(distdir)" \ || { sleep 5 && rm -rf "$(distdir)"; }; \ else :; fi am__post_remove_distdir = $(am__remove_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 DIST_TARGETS = dist-gzip distuninstallcheck_listfiles = find . -type f -print am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \ | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$' distcleancheck_listfiles = find . -type f -print ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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 icons replacements EXTRA_DIST = 00odin.h odin.doxygen odin.nsi install.win install.macos TESTS = cmdline-utils/odintestsuite all: all-recursive .SUFFIXES: .SUFFIXES: .log .test .test$(EXEEXT) .trs am--refresh: Makefile @: $(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 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. $(am__recursive_targets): @fail=; \ if $(am__make_keepgoing); then \ failcom='fail=yes'; \ else \ failcom='exit 1'; \ fi; \ dot_seen=no; \ target=`echo $@ | sed s/-recursive//`; \ case "$@" in \ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ *) list='$(SUBDIRS)' ;; \ esac; \ 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" ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-recursive TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 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; \ $(am__define_uniq_tagged_files); \ 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-recursive CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ 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" cscope: cscope.files test ! -s cscope.files \ || $(CSCOPE) -b -q $(AM_CSCOPEFLAGS) $(CSCOPEFLAGS) -i cscope.files $(CSCOPE_ARGS) clean-cscope: -rm -f cscope.files cscope.files: clean-cscope cscopelist cscopelist: cscopelist-recursive cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files # Recover from deleted '.trs' file; this should ensure that # "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create # both 'foo.log' and 'foo.trs'. Break the recipe in two subshells # to avoid problems with "make -n". .log.trs: rm -f $< $@ $(MAKE) $(AM_MAKEFLAGS) $< # Leading 'am--fnord' is there to ensure the list of targets does not # expand to empty, as could happen e.g. with make check TESTS=''. am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck) am--force-recheck: @: $(TEST_SUITE_LOG): $(TEST_LOGS) @$(am__set_TESTS_bases); \ am__f_ok () { test -f "$$1" && test -r "$$1"; }; \ redo_bases=`for i in $$bases; do \ am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \ done`; \ if test -n "$$redo_bases"; then \ redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \ redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \ if $(am__make_dryrun); then :; else \ rm -f $$redo_logs && rm -f $$redo_results || exit 1; \ fi; \ fi; \ if test -n "$$am__remaking_logs"; then \ echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \ "recursion detected" >&2; \ elif test -n "$$redo_logs"; then \ am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \ fi; \ if $(am__make_dryrun); then :; else \ st=0; \ errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \ for i in $$redo_bases; do \ test -f $$i.trs && test -r $$i.trs \ || { echo "$$errmsg $$i.trs" >&2; st=1; }; \ test -f $$i.log && test -r $$i.log \ || { echo "$$errmsg $$i.log" >&2; st=1; }; \ done; \ test $$st -eq 0 || exit 1; \ fi @$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \ ws='[ ]'; \ results=`for b in $$bases; do echo $$b.trs; done`; \ test -n "$$results" || results=/dev/null; \ all=` grep "^$$ws*:test-result:" $$results | wc -l`; \ pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \ fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \ skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \ xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \ xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \ error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \ if test `expr $$fail + $$xpass + $$error` -eq 0; then \ success=true; \ else \ success=false; \ fi; \ br='==================='; br=$$br$$br$$br$$br; \ result_count () \ { \ if test x"$$1" = x"--maybe-color"; then \ maybe_colorize=yes; \ elif test x"$$1" = x"--no-color"; then \ maybe_colorize=no; \ else \ echo "$@: invalid 'result_count' usage" >&2; exit 4; \ fi; \ shift; \ desc=$$1 count=$$2; \ if test $$maybe_colorize = yes && test $$count -gt 0; then \ color_start=$$3 color_end=$$std; \ else \ color_start= color_end=; \ fi; \ echo "$${color_start}# $$desc $$count$${color_end}"; \ }; \ create_testsuite_report () \ { \ result_count $$1 "TOTAL:" $$all "$$brg"; \ result_count $$1 "PASS: " $$pass "$$grn"; \ result_count $$1 "SKIP: " $$skip "$$blu"; \ result_count $$1 "XFAIL:" $$xfail "$$lgn"; \ result_count $$1 "FAIL: " $$fail "$$red"; \ result_count $$1 "XPASS:" $$xpass "$$red"; \ result_count $$1 "ERROR:" $$error "$$mgn"; \ }; \ { \ echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \ $(am__rst_title); \ create_testsuite_report --no-color; \ echo; \ echo ".. contents:: :depth: 2"; \ echo; \ for b in $$bases; do echo $$b; done \ | $(am__create_global_log); \ } >$(TEST_SUITE_LOG).tmp || exit 1; \ mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \ if $$success; then \ col="$$grn"; \ else \ col="$$red"; \ test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \ fi; \ echo "$${col}$$br$${std}"; \ echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \ echo "$${col}$$br$${std}"; \ create_testsuite_report --maybe-color; \ echo "$$col$$br$$std"; \ if $$success; then :; else \ echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \ if test -n "$(PACKAGE_BUGREPORT)"; then \ echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \ fi; \ echo "$$col$$br$$std"; \ fi; \ $$success || exit 1 check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ log_list=`for i in $$bases; do echo $$i.log; done`; \ trs_list=`for i in $$bases; do echo $$i.trs; done`; \ log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \ exit $$?; recheck: all @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @set +e; $(am__set_TESTS_bases); \ bases=`for i in $$bases; do echo $$i; done \ | $(am__list_recheck_tests)` || exit 1; \ log_list=`for i in $$bases; do echo $$i.log; done`; \ log_list=`echo $$log_list`; \ $(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \ am__force_recheck=am--force-recheck \ TEST_LOGS="$$log_list"; \ exit $$? cmdline-utils/odintestsuite.log: cmdline-utils/odintestsuite @p='cmdline-utils/odintestsuite'; \ b='cmdline-utils/odintestsuite'; \ $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) .test.log: @p='$<'; \ $(am__set_b); \ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) @am__EXEEXT_TRUE@.test$(EXEEXT).log: @am__EXEEXT_TRUE@ @p='$<'; \ @am__EXEEXT_TRUE@ $(am__set_b); \ @am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \ @am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \ @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) 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 \ $(am__make_dryrun) \ || test -d "$(distdir)/$$subdir" \ || $(MKDIR_P) "$(distdir)/$$subdir" \ || exit 1; \ 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__post_remove_distdir) dist-bzip2: distdir tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2 $(am__post_remove_distdir) dist-lzip: distdir tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz $(am__post_remove_distdir) dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z $(am__post_remove_distdir) dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir -rm -f $(distdir).zip zip -rq $(distdir).zip $(distdir) $(am__post_remove_distdir) dist dist-all: $(MAKE) $(AM_MAKEFLAGS) $(DIST_TARGETS) am__post_remove_distdir='@:' $(am__post_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.lz*) \ lzip -dc $(distdir).tar.lz | $(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 u+w $(distdir) mkdir $(distdir)/_build $(distdir)/_build/sub $(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/sub \ && ../../configure \ $(AM_DISTCHECK_CONFIGURE_FLAGS) \ $(DISTCHECK_CONFIGURE_FLAGS) \ --srcdir=../.. --prefix="$$dc_install_base" \ && $(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__post_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: @test -n '$(distuninstallcheck_dir)' || { \ echo 'ERROR: trying to run $@ with an empty' \ '$$(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ $(am__cd) '$(distuninstallcheck_dir)' || { \ echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \ exit 1; \ }; \ test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \ || { 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi mostlyclean-generic: -test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS) -test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs) -test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) 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: $(am__recursive_targets) check-am install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-TESTS check-am clean clean-cscope \ clean-generic clean-libtool cscope cscopelist-am ctags \ ctags-am dist dist-all dist-bzip2 dist-gzip dist-hook \ dist-lzip 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 recheck tags tags-am uninstall uninstall-am \ uninstall-local .PRECIOUS: Makefile 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 rm -rf platforms.doxygen for platform in $(PLATFORMS) ; do \ echo "ENABLED_SECTIONS += $$platform" >> platforms.doxygen ; \ done doxygen $(PACKAGE).doxygen release: test ! # Please make sure that you have done the following before continuing test ! # - updated versions in configure.ac test ! # - updated ChangeLog test ! # - executed svn copy https://svn.code.sf.net/p/od1n/code/trunk/odin https://svn.code.sf.net/p/od1n/code/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 ChangeLog $(PACKAGE)-homepage convert -resize 16x16 icons/odin.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 platforms.doxygen $(PACKAGE)-$(VERSION).tar.gz svnclean: distclean for entry in $$(svn status | grep ^? | grep -v platforms/ | grep -v platforms.tgz | 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-2.0.3/miview/0000755000000000000000000000000013010330626010706 500000000000000odin-2.0.3/miview/Makefile.in0000644000000000000000000006413513010312545012704 00000000000000# Makefile.in generated by automake 1.15 from Makefile.am. # @configure_input@ # Copyright (C) 1994-2014 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@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ false; \ elif test -n '$(MAKE_HOST)'; then \ true; \ elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ true; \ else \ false; \ fi; \ } am__make_running_with_option = \ case $${target_option-} in \ ?) ;; \ *) echo "am__make_running_with_option: internal error: invalid" \ "target option '$${target_option-}' specified" >&2; \ exit 1;; \ esac; \ has_opt=no; \ sane_makeflags=$$MAKEFLAGS; \ if $(am__is_gnu_make); then \ sane_makeflags=$$MFLAGS; \ else \ case $$MAKEFLAGS in \ *\\[\ \ ]*) \ bs=\\; \ sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ esac; \ fi; \ skip_next=no; \ strip_trailopt () \ { \ flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ }; \ for flg in $$sane_makeflags; do \ test $$skip_next = yes && { skip_next=no; continue; }; \ case $$flg in \ *=*|--*) continue;; \ -*I) strip_trailopt 'I'; skip_next=yes;; \ -*I?*) strip_trailopt 'I';; \ -*O) strip_trailopt 'O'; skip_next=yes;; \ -*O?*) strip_trailopt 'O';; \ -*l) strip_trailopt 'l'; skip_next=yes;; \ -*l?*) strip_trailopt 'l';; \ -[dEDm]) skip_next=yes;; \ -[JT]) skip_next=yes;; \ esac; \ case $$flg in \ *$$target_option*) has_opt=yes; break;; \ esac; \ done; \ test $$has_opt = yes am__make_dryrun = (target_option=n; $(am__make_running_with_option)) am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 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 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(am__dist_desktop_DATA_DIST) \ $(am__DIST_COMMON) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/tjutils/config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" \ "$(DESTDIR)$(desktopdir)" 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) am__DEPENDENCIES_1 = @GUI_ENABLED_TRUE@miview_DEPENDENCIES = ../odindata/libodindata.la \ @GUI_ENABLED_TRUE@ $(am__DEPENDENCIES_1) ../odinqt/libodinqt.la \ @GUI_ENABLED_TRUE@ ../odinpara/libodinpara.la \ @GUI_ENABLED_TRUE@ ../tjutils/libtjutils.la \ @GUI_ENABLED_TRUE@ $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false am__v_P_1 = : AM_V_GEN = $(am__v_GEN_@AM_V@) am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) am__v_GEN_0 = @echo " GEN " $@; am__v_GEN_1 = AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = 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) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CXXFLAGS) $(CXXFLAGS) AM_V_CXX = $(am__v_CXX_@AM_V@) am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) am__v_CXX_0 = @echo " CXX " $@; am__v_CXX_1 = CXXLD = $(CXX) CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CFLAGS) $(CFLAGS) AM_V_CC = $(am__v_CC_@AM_V@) am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) am__v_CC_0 = @echo " CC " $@; am__v_CC_1 = CCLD = $(CC) LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(AM_LDFLAGS) $(LDFLAGS) -o $@ AM_V_CCLD = $(am__v_CCLD_@AM_V@) am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) am__v_CCLD_0 = @echo " CCLD " $@; am__v_CCLD_1 = SOURCES = $(miview_SOURCES) DIST_SOURCES = $(am__miview_SOURCES_DIST) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac 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__uninstall_files_from_dir = { \ test -z "$$files" \ || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } man1dir = $(mandir)/man1 NROFF = nroff MANS = $(dist_man_MANS) am__dist_desktop_DATA_DIST = miview.desktop DATA = $(dist_desktop_DATA) am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. am__uniquify_input = $(AWK) '\ BEGIN { nonempty = 0; } \ { items[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in items) print i; }; } \ ' # Make sure the list of sources is unique. This is necessary because, # e.g., the same source file might be shared among _SOURCES variables # for different programs/libraries. am__define_uniq_tagged_files = \ list='$(am__tagged_files)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | $(am__uniquify_input)` ETAGS = etags CTAGS = ctags am__DIST_COMMON = $(dist_man_MANS) $(srcdir)/Makefile.in \ $(top_srcdir)/depcomp DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 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@ DLLTOOL = @DLLTOOL@ 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@ LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ MAKEINFO = @MAKEINFO@ MANIFEST_TOOL = @MANIFEST_TOOL@ 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_AR = @ac_ct_AR@ 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@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ psdir = @psdir@ runstatedir = @runstatedir@ 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@AM_CPPFLAGS = $(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 $(DATALIBS) ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la $(GUILIBS) $(BASELIBS) # Manual pages for distribution @GUI_ENABLED_TRUE@dist_man_MANS = miview.1 #desktop entry @GUI_ENABLED_TRUE@desktopdir = $(datadir)/applications @GUI_ENABLED_TRUE@dist_desktop_DATA = miview.desktop 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 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) @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ fi; \ 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) $(EXTRA_miview_DEPENDENCIES) @rm -f miview$(EXEEXT) $(AM_V_CXXLD)$(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@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs install-man1: $(dist_man_MANS) @$(NORMAL_INSTALL) @list1=''; \ list2='$(dist_man_MANS)'; \ test -n "$(man1dir)" \ && test -n "`echo $$list1$$list2`" \ || exit 0; \ echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \ $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \ { for i in $$list1; do echo "$$i"; done; \ if test -n "$$list2"; then \ for i in $$list2; do echo "$$i"; done \ | sed -n '/\.1[a-z]*$$/p'; \ fi; \ } | 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,.,'`; \ dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir) install-dist_desktopDATA: $(dist_desktop_DATA) @$(NORMAL_INSTALL) @list='$(dist_desktop_DATA)'; test -n "$(desktopdir)" || list=; \ if test -n "$$list"; then \ echo " $(MKDIR_P) '$(DESTDIR)$(desktopdir)'"; \ $(MKDIR_P) "$(DESTDIR)$(desktopdir)" || exit 1; \ fi; \ 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)$(desktopdir)'"; \ $(INSTALL_DATA) $$files "$(DESTDIR)$(desktopdir)" || exit $$?; \ done uninstall-dist_desktopDATA: @$(NORMAL_UNINSTALL) @list='$(dist_desktop_DATA)'; test -n "$(desktopdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(desktopdir)'; $(am__uninstall_files_from_dir) ID: $(am__tagged_files) $(am__define_uniq_tagged_files); mkid -fID $$unique tags: tags-am TAGS: tags tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) set x; \ here=`pwd`; \ $(am__define_uniq_tagged_files); \ 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-am CTAGS: ctags ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) $(am__define_uniq_tagged_files); \ 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" cscopelist: cscopelist-am cscopelist-am: $(am__tagged_files) list='$(am__tagged_files)'; \ case "$(srcdir)" in \ [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ *) sdir=$(subdir)/$(srcdir) ;; \ esac; \ for i in $$list; do \ if test -f "$$i"; then \ echo "$(subdir)/$$i"; \ else \ echo "$$sdir/$$i"; \ fi; \ done >> $(top_builddir)/cscope.files 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 $(MAKE) $(AM_MAKEFLAGS) \ top_distdir="$(top_distdir)" distdir="$(distdir)" \ dist-hook check-am: all-am check: check-am all-am: Makefile $(PROGRAMS) $(MANS) $(DATA) installdirs: for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(desktopdir)"; 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: if test -z '$(STRIP)'; then \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ install; \ else \ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ fi 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-dist_desktopDATA 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-dist_desktopDATA \ uninstall-man uninstall-man: uninstall-man1 .MAKE: install-am install-strip .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ clean-binPROGRAMS clean-generic clean-libtool clean-local \ cscopelist-am ctags ctags-am 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-dist_desktopDATA 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 tags-am uninstall \ uninstall-am uninstall-binPROGRAMS uninstall-dist_desktopDATA \ uninstall-man uninstall-man1 .PRECIOUS: Makefile # 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-2.0.3/miview/miviewview.h0000644000000000000000000001011512732216514013201 00000000000000/*************************************************************************** miviewview.h - description ------------------- begin : Thu Jun 20 19:02:26 CEST 2002 copyright : (C) 2000-2015 by Thies H. Jochimsen email : thies@jochimsen.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 : LDRblock { LDRbool color; LDRfloat contrast; LDRfloat brightness; LDRstring valfile; LDRstring recfile; LDRint blowup; LDRstring low; LDRstring upp; LDRstring dump; LDRstring mapfile; LDRfloat maplow; LDRfloat mapupp; LDRfloat maprect; LDRstring legendexport; LDRstring maplegendexport; LDRbool 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 writeData(); void writeImage(); void writeROIs(); void writeFmriClusters(); void writeProfile(); void writeTimecourse(); void writeLegend(); void writeMapLegend(); 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, bool show_error_msg=true); void export_legend(const STD_string& filename); void export_map_legend(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 LDRfloatArr displaydata; GuiProps guiprops_cache; LDRblock settings; LDRint repetition; LDRfloatArr timecourse; bool has_olm; SelectionData* selection; // holding data of user selections GuiGridLayout* grid; LDRwidget* displaywidget; LDRwidget* settingswidget; LDRwidget* tcoursewidget; LDRwidget* fmriwidget; STD_string data_fname_cache; 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; LDRint pos_cache[n_directions]; // miview modules MiViewFmri fmri; }; #endif odin-2.0.3/miview/miview.h0000644000000000000000000000422212732216514012310 00000000000000/*************************************************************************** miview.h - description ------------------- begin : Thu Aug 31 16:27:06 CEST 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2015 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-2.0.3/miview/miview.cpp0000644000000000000000000000415312732216514012646 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("Save Data as ...", view, SLOT(writeData())); 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())); } exportMenu->insert_item("Export legend", view, SLOT(writeLegend())); if(view->has_overlay()) { exportMenu->insert_item("Export overlay legend", view, SLOT(writeMapLegend())); } 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-2.0.3/miview/main.cpp0000644000000000000000000000340712732216514012273 00000000000000/*************************************************************************** main.cpp - description ------------------- begin : Thu Aug 31 16:27:06 CEST 2000 copyright : (C) 2000-2015 by Thies Jochimsen email : thies@jochimsen.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-2.0.3/miview/miviewview.cpp0000644000000000000000000004773412732216514013555 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=0; blowup.set_cmdline_option("blowup").set_description("Enlarge display size by this factor (0=automatic)"); 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 graphic files and exit, use the given filename postfix to specify the format"); 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"); legendexport.set_cmdline_option("legend").set_description("Export legend as bitmap to this file"); append_member(legendexport,"legendexport"); 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; FilterChain 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()); LDRfileName 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; if(mopts.blowup>0) guiprops_cache.pixmap.minsize=mopts.blowup*STD_min(get_nx(), get_ny()); else guiprops_cache.pixmap.minsize=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; ODINLOG(odinlog,normalDebug) << "guiprops.pixmap.minsize=" << guiprops_cache.pixmap.minsize << STD_endl; 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 LDRwidget(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 LDRwidget(displaydata, 1, this); export_legend(mopts.legendexport); // Do this after displaywidget is initialized, bur before dump. String will be checked in export_map_legend() export_map_legend(mopts.maplegendexport); // Do this after displaywidget is initialized, bur before dump. String will be checked in export_map_legend() if(mopts.dump!="") { STD_string dumpfname(mopts.dump); STD_string format=check_and_get_format(mopts.dump, get_possible_image_fileformats(), false); if(format=="") { format="bmp"; // default dumpfname+="."+format; ODINLOG(odinlog,warningLog) << "Unknown file format, using format" << format << STD_endl; } ODINLOG(odinlog,infoLog) << "Dumping images with filename " << dumpfname << " and format " << format << STD_endl; displaywidget->write_pixmap(dumpfname.c_str(), format.c_str(), 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 LDRwidget(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 LDRwidget(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::writeData() { data_fname_cache=get_save_filename("Data File", data_fname_cache.c_str(), "", this); if(data_fname_cache=="") return; STD_string format=check_and_get_format(data_fname_cache,FileIO::autoformats()); if(format!="") { file->data.autowrite(data_fname_cache, FileWriteOpts(), &(file->prot)); } } 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::export_legend(const STD_string& filename) { Log odinlog("MiViewView","export_legend"); 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_legend(filename.c_str(), format.c_str()); } } void MiViewView::export_map_legend(const STD_string& filename) { Log odinlog("MiViewView","export_map_legend"); if(filename=="") return; STD_string format=check_and_get_format(filename,get_possible_image_fileformats()); if(format!="") { ODINLOG(odinlog,infoLog) << "Writing map legend of format " << format << " to file " << filename << STD_endl; displaywidget->write_map_legend(filename.c_str(), format.c_str()); } } void MiViewView::writeLegend() { export_legend(get_save_filename("File for Legend", "", "", this)); } void MiViewView::writeMapLegend() { export_map_legend(get_save_filename("File for Map Legend", "", "", this)); } void MiViewView::selectVoxel() { LDRblock 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 LDRwidgetDialog(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 LDRwidgetDialog(file->prot,2,this,false,true); } STD_string MiViewView::check_and_get_format(const STD_string& fname, const svector& possible_formats, bool show_error_msg) { Log odinlog("MiViewView","check_and_get_format"); STD_string result; STD_string format=LDRfileName(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=LDRfloat(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; guiprops_cache.scale[displayScale].minval=lowbound; guiprops_cache.scale[displayScale].maxval=uppbound; guiprops_cache.scale[displayScale].enable=!mopts.noscale; 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-2.0.3/miview/Makefile.am0000644000000000000000000000172412732216514012677 00000000000000 if GUI_ENABLED AM_CPPFLAGS = $(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 $(DATALIBS) ../odinqt/libodinqt.la ../odinpara/libodinpara.la ../tjutils/libtjutils.la $(GUILIBS) $(BASELIBS) # 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 #desktop entry desktopdir = $(datadir)/applications dist_desktop_DATA = miview.desktop 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-2.0.3/miview/miview.desktop0000644000000000000000000000035012732216514013530 00000000000000[Desktop Entry] Encoding=UTF-8 GenericName=Medical Image Viewer Name=MiView Exec=miview %f TryExec=miview Type=Application Terminal=false Categories=Education;Graphics;Science;DataVisualization;MedicalSoftware;Viewer; Icon=odin.png odin-2.0.3/miview/miview.10000644000000000000000000002536713010313674012231 00000000000000.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.4. .TH MIVIEW "1" "November 2016" "miview 2.0.3" "User Commands" .SH NAME miview \- Viewer for medical image files .SH SYNOPSIS .B miview [ \fI\,options \/\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 (0=automatic) (default=0) .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 graphic files and exit, use the given filename postfix to specify the format .HP \fB\-legend\fR: Export legend as bitmap to this file .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\-aa\fR: azimuthal rotation angle (default=0.0) .HP \fB\-ah\fR: height rotation angle (default=0.0) .HP \fB\-ai\fR: inplane rotation angle (default=0.0) .HP \fB\-date\fR: Date of scan [yyyymmdd] (default=20161108yyyymmdd) .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\-psize\fR: Patients size/height [mm] (default=2000.0mm) .HP \fB\-pweight\fR: Patients weight [kg] (default=50.0kg) .HP \fB\-rcname\fR: Name of receive coil (default=Unknown) .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=101540hhmmss) .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\-ldr\fR: If multiple LDR (labeled data record) 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 analyze asc coi dat dcm double float gz hdr idx ima interfile jdx mag mhd nii ph png pos pro reg s16bit s32bit s8bit smp u16bit u32bit u8bit vtk xml xpro , 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\-cluster\fR : Create clusters of non\-zero adjacent/next\-neighbours voxels, sorted by size .HP \fB\-convolve\fR : Convolution in spatial dimensions .HP \fB\-detrend\fR : Remove slow drift over time .HP \fB\-edit\fR : Edit single voxel values .HP \fB\-genmask\fR : Create mask including all voxels with value in given range .HP \fB\-inv\fR : Invert image values, i.e. lowest to highest and vice versa .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 mean 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\-slicetime\fR : Correct for different acquisition time points of slices .HP \fB\-spheremask\fR : Create spherical mask .HP \fB\-splice\fR : splices the image in the given direction .HP \fB\-srange\fR : Select range in slice direction .HP \fB\-sum\fR : Perform sum projection over given 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\-tshift\fR