nmrrelax.h
1 /***************************************************************************
2  Copyright (C) 2002-2015 Kentaro Kitagawa
3  kitagawa@phys.s.u-tokyo.ac.jp
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  You should have received a copy of the GNU Library General
11  Public License and a list of authors along with this program;
12  see the files COPYING and AUTHORS.
13 ***************************************************************************/
14 #ifndef nmrrelaxH
15 #define nmrrelaxH
16 
17 #include "secondarydriver.h"
18 #include "xnodeconnector.h"
19 //#include "pulserdriver.h"
20 //#include "nmrpulse.h"
21 //#include "nmrrelaxfit.h"
22 #include <complex>
23 
24 #include "nmrspectrumsolver.h"
25 
26 class XNMRPulseAnalyzer;
27 class XPulser;
28 class XRelaxFunc;
29 class XRelaxFuncList;
30 class XRelaxFuncPlot;
31 class XScalarEntry;
32 
33 #include "xwavengraph.h"
34 
35 class Ui_FrmNMRT1;
37 
38 //! Measure Relaxation Curve
39 class XNMRT1 : public XSecondaryDriver {
40 public:
41  XNMRT1(const char *name, bool runtime,
42  Transaction &tr_meas, const shared_ptr<XMeasure> &meas);
43  ~XNMRT1 () {}
44 
45  //! Shows all forms belonging to driver
46  virtual void showForms();
47 protected:
48  //! This function is called when a connected driver emit a signal
49  virtual void analyze(Transaction &tr, const Snapshot &shot_emitter, const Snapshot &shot_others,
50  XDriver *emitter) throw (XRecordError&);
51  //! This function is called after committing XPrimaryDriver::analyzeRaw() or XSecondaryDriver::analyze().
52  //! This might be called even if the record is invalid (time() == false).
53  virtual void visualize(const Snapshot &shot);
54  //! Checks if the connected drivers have valid time stamps.
55  //! \return true if dependency is resolved.
56  //! This function must be reentrant unlike analyze().
57  virtual bool checkDependency(const Snapshot &shot_this,
58  const Snapshot &shot_emitter, const Snapshot &shot_others,
59  XDriver *emitter) const;
60 public:
62  private:
63  friend class XNMRT1;
64  friend class XRelaxFunc;
65  friend class XRelaxFuncPlot;
66  //! For fitting and display
67  struct Pt {
68  double var; /// auto-phase- or absolute value
69  std::complex<double> c;
70  double p1;
71  int isigma; /// weight
72  std::deque<std::complex<double> > value_by_cond;
73  };
75  std::vector<std::complex<double> > wave;
76  double windowwidth;
77  FFT::twindowfunc windowfunc;
78  int origin;
79  double cfreq;
80  double power;
81  };
82  //! Raw measured points
83  struct RawPt {
84  std::deque<std::complex<double> > value_by_cond;
85  double p1;
86  };
87  std::deque<shared_ptr<ConvolutionCache> > m_convolutionCache;
88  //! Stores all measured points.
89  std::deque<RawPt> m_pts;
90  //! Stores reduced points to manage fitting and display.
91  std::vector<Pt> m_sumpts;
92  double m_params[3]; //!< fitting parameters; 1/T1, c, a; ex. f(t) = c*exp(-t/T1) + a
93  double m_errors[3]; //!< std. deviations
94 
95  XTime m_timeClearRequested;
96  };
97 
98  //! Holds 1/T1 or 1/T2 and its std. deviation
99  const shared_ptr<XScalarEntry> &t1inv() const {return m_t1inv;}
100  const shared_ptr<XScalarEntry> &t1invErr() const {return m_t1invErr;}
101 
102  const shared_ptr<XItemNode < XDriverList, XPulser > > &pulser() const {return m_pulser;}
103  const shared_ptr<XItemNode < XDriverList, XNMRPulseAnalyzer > > &pulse1() const {return m_pulse1;}
104  const shared_ptr<XItemNode < XDriverList, XNMRPulseAnalyzer > > &pulse2() const {return m_pulse2;}
105 
106  //! If active, a control to Pulser is allowed
107  const shared_ptr<XBoolNode> &active() const {return m_active;}
108  //! Deduce phase from data
109  const shared_ptr<XBoolNode> &autoPhase() const {return m_autoPhase;}
110  //! Fit 3 parameters.
111  const shared_ptr<XBoolNode> &mInftyFit() const {return m_mInftyFit;}
112  //! Use absolute value, ignoring phase
113  const shared_ptr<XBoolNode> &absFit() const {return m_absFit;}
114  //! Tracks peak freq. to accomodate a field decay.
115  const shared_ptr<XBoolNode> &trackPeak() const {return m_trackPeak;}
116  //! Region of P1 or 2tau for fitting, display, control of pulser [ms]
117  const shared_ptr<XDoubleNode> &p1Min() const {return m_p1Min;}
118  const shared_ptr<XDoubleNode> &p1Max() const {return m_p1Max;}
119  //! Candidate for the next P1/2tau.
120  const shared_ptr<XDoubleNode> &p1Next() const {return m_p1Next;}
121  const shared_ptr<XDoubleNode> &p1AltNext() const {return m_p1AltNext;}
122  //! (Deduced) phase of echoes [deg.]
123  const shared_ptr<XDoubleNode> &phase() const {return m_phase;}
124  //! Center freq of echoes [kHz].
125  const shared_ptr<XDoubleNode> &freq() const {return m_freq;}
126  /// FFT Window Function
127  const shared_ptr<XComboNode> &windowFunc() const {return m_windowFunc;}
128  /// FFT Window Length
129  const shared_ptr<XComboNode> &windowWidth() const {return m_windowWidth;}
130  //! Auto-select window.
131  const shared_ptr<XBoolNode> &autoWindow() const {return m_autoWindow;}
132  enum MEASMODE {MEAS_T1 = 0, MEAS_T2 = 1, MEAS_ST_E = 2};
133  //! T1/T2/StE measurement
134  const shared_ptr<XComboNode> &mode() const {return m_mode;}
135  //! # of Samples for fitting and display
136  const shared_ptr<XUIntNode> &smoothSamples() const {return m_smoothSamples;}
137  //! Strategy for distributing P1 or 2tau
138  const shared_ptr<XComboNode> &p1Strategy() const {return m_p1Strategy;}
139  //! Distribution of P1 or 2tau
140  const shared_ptr<XComboNode> &p1Dist() const {return m_p1Dist;}
141  //! Relaxation Function
142  const shared_ptr<XItemNode < XRelaxFuncList, XRelaxFunc > > &relaxFunc() const {return m_relaxFunc;}
143 
144 private:
145  //! List of relaxation functions
146  shared_ptr<XRelaxFuncList> m_relaxFuncs;
147 
148  friend class XRelaxFunc;
149  friend class XRelaxFuncPlot;
150 
151  //! Holds 1/T1 or 1/T2 and its std. deviation
152  const shared_ptr<XScalarEntry> m_t1inv;
153  const shared_ptr<XScalarEntry> m_t1invErr;
154 
155  const shared_ptr<XItemNode < XDriverList, XPulser > > m_pulser;
156  const shared_ptr<XItemNode < XDriverList, XNMRPulseAnalyzer > > m_pulse1;
157  const shared_ptr<XItemNode < XDriverList, XNMRPulseAnalyzer > > m_pulse2;
158 
159  const shared_ptr<XBoolNode> m_active;
160  const shared_ptr<XBoolNode> m_autoPhase;
161  const shared_ptr<XBoolNode> m_mInftyFit;
162  const shared_ptr<XBoolNode> m_absFit;
163  const shared_ptr<XBoolNode> m_trackPeak;
164  const shared_ptr<XDoubleNode> m_p1Min;
165  const shared_ptr<XDoubleNode> m_p1Max;
166  const shared_ptr<XDoubleNode> m_p1Next;
167  const shared_ptr<XDoubleNode> m_p1AltNext;
168  const shared_ptr<XDoubleNode> m_phase;
169  const shared_ptr<XDoubleNode> m_freq;
170  const shared_ptr<XDoubleNode> m_bandWidth;
171  const shared_ptr<XComboNode> m_windowFunc;
172  const shared_ptr<XComboNode> m_windowWidth;
173  const shared_ptr<XBoolNode> m_autoWindow;
174  const shared_ptr<XComboNode> m_mode;
175  const shared_ptr<XUIntNode> m_smoothSamples;
176  const shared_ptr<XComboNode> m_p1Strategy;
177  const shared_ptr<XComboNode> m_p1Dist;
178  shared_ptr<XItemNode < XRelaxFuncList, XRelaxFunc > > m_relaxFunc;
179  const shared_ptr<XTouchableNode> m_resetFit, m_clearAll;
180  const shared_ptr<XStringNode> m_fitStatus;
181 
182  //! for Non-Lenear-Least-Square fitting
183  struct NLLS {
184  std::vector<Payload::Pt> *pts; //pointer to data
185  shared_ptr<XRelaxFunc> func; //pointer to the current relaxation function
186  bool is_minftyfit; //3param fit or not.
187  double fixed_minfty;
188  };
189 
190  shared_ptr<XListener> m_lsnOnClearAll, m_lsnOnResetFit;
191  shared_ptr<XListener> m_lsnOnActiveChanged;
192  shared_ptr<XListener> m_lsnOnCondChanged, m_lsnOnP1CondChanged;
193  void onClearAll (const Snapshot &shot, XTouchableNode *);
194  void onResetFit (const Snapshot &shot, XTouchableNode *);
195  void onActiveChanged (const Snapshot &shot, XValueNodeBase *);
196  void onCondChanged (const Snapshot &shot, XValueNodeBase *);
197  void onP1CondChanged (const Snapshot &shot, XValueNodeBase *);
198  std::deque<xqcon_ptr> m_conUIs;
199 
200  void analyzeSpectrum(Transaction &tr,
201  const std::vector< std::complex<double> >&wave, int origin, double cf,
202  std::deque<std::complex<double> > &value_by_cond);
203 
204  shared_ptr<SpectrumSolverWrapper> m_solver;
205 
206  const qshared_ptr<FrmNMRT1> m_form;
207  const shared_ptr<XStatusPrinter> m_statusPrinter;
208 
209  //! Does fitting iterations \a itercnt times
210  //! \param relax a pointer to a realaxation function
211  //! \param itercnt counts
212  //! \param buf a message will be passed
213  XString iterate(Transaction &tr, shared_ptr<XRelaxFunc> &relax, int itercnt);
214 
215  //! Store reduced points
216  //! \sa m_pt, m_sumpts
217  const shared_ptr<XWaveNGraph> m_wave;
218 
219  std::deque<double> m_windowWidthList;
220 
221  atomic<int> m_isPulserControlRequested;
222 
223  const static int CONVOLUTION_CACHE_SIZE = (3 * 10);
224 
225  const static char P1DIST_LINEAR[];
226  const static char P1DIST_LOG[];
227  const static char P1DIST_RECIPROCAL[];
228 
229  const static char P1STRATEGY_RANDOM[];
230  const static char P1STRATEGY_FLATTEN[];
231 
232  double distributeP1(const Snapshot &shot, double uniform_x_0_to_1);
233  void obtainNextP1(Transaction &tr);
234  void setNextP1(const Snapshot &shot);
235 };
236 
237 //---------------------------------------------------------------------------
238 #endif

Generated for KAME4 by  doxygen 1.8.3