Tomato
OxStartPointCalculatorShmolli.h
Go to the documentation of this file.
1 
7 #ifndef Tomato_OXSTARTPOINTCALCULATORShmolli_H
8 #define Tomato_OXSTARTPOINTCALCULATORShmolli_H
9 
10 #include "OxStartPointCalculator.h"
11 
12 namespace Ox {
13 
20  template< typename MeasureType >
22 
23  public:
24 
29  virtual int calculateStartPoint(){
30  return calculateStartPointSKP(
31  this->_nSamples,
32  this->_InvTimes,
33  this->_SigMag,
34  this->_Signs,
35  this->_CalculatedStartPoint);
36  };
37 
38  int setStartPointToDefault(){
39  this->_CalculatedStartPoint[0] = this->_DefaultStartPoint[0];
40  this->_CalculatedStartPoint[1] = this->_DefaultStartPoint[1];
41  this->_CalculatedStartPoint[2] = this->_DefaultStartPoint[2];
42 
43  return 0; // EXIT_SUCCESS
44  }
45 
46  int calculateStartPointSKP(int nSamples, const MeasureType *invTimes, const MeasureType *ysignalInput, const double *signs, MeasureType *initPoint){
47 
48  const int MAX_MOLLI_TI_SAMPLES = 128;
49  int i; // gen index
50  int lSigns[MAX_MOLLI_TI_SAMPLES] ; // signs local. Always will have first sample inverted and patches the unknown signs from magnitude info
51  MeasureType lSignal[MAX_MOLLI_TI_SAMPLES] ; // signed local copy of signal
52 
53  // KW: !!!!!
54  MeasureType lSignalAbs[MAX_MOLLI_TI_SAMPLES];
55  for ( i = 0; i < nSamples; i++) lSignalAbs[i] = fabs(ysignalInput[i]);
56 
57  // thse acalcs are absed on ansolute sample valeus
58  //a[0]=1.+ 0.5*(y[0]+y[n-1]); //average shortest and longest TI -- poor performance use max
59  initPoint[0] = 1.+ KWUtil::max(lSignalAbs[0],lSignalAbs[nSamples-1]); //average shortest and longest TI -- poor performance use max
60  initPoint[1] = 1+initPoint[0]+lSignalAbs[0]; //B param, span is a plus absolute of sample with earliest TI
61  // patch signs, converts signal to signed values and selsct samples that are over 10% of signal range from A[0]
62  int indmin = 0;
63  MeasureType signalMin = lSignalAbs[0], singalMax = lSignalAbs[0]; //for signed samples
64  KWUtil::MOLLI_min(lSignalAbs, nSamples, &indmin);// find smallest sample index
65  initPoint[2]=invTimes[indmin]; // T1* estimate in case all else breaks
66 
67  for ( i = 0; i < nSamples; i++) {
68  lSigns[i]=(int)signs[i];
69  if(lSigns[i] == 0) lSigns[i] = ( i <= indmin ) ? (-1) : (1); // assume negative sign if before lowest(i.e. possible zero corss) signal
70  lSignal[i] = lSignalAbs[i] * lSigns[i];
71  if(lSignal[i] < signalMin) signalMin = lSignal[i];
72  if(lSignal[i] > singalMax) singalMax = lSignal[i];
73  }
74 
75  MeasureType zereproxrange=0.1; // how far samples must be for log T1* approximation // this works best with ShMLLI 3+3 sample perIR tests
76  MeasureType y4log[MAX_MOLLI_TI_SAMPLES] ; // mag sample distance from A for log estiamte
77  MeasureType x4log[MAX_MOLLI_TI_SAMPLES] ; // corresponding TIs
78  int n4log=0; // number of indexes within range suitable to get logs
79  //MeasureType sdMolliBestCost= 1e32; // large enough... to prevent overshadow any better solution
80  for (i=0;i<nSamples;i++)
81  {
82  y4log[n4log]=initPoint[0]-lSignal[i];
83  if((y4log[n4log]) > ((singalMax-signalMin)*zereproxrange) )
84  {
85  y4log[n4log]=log(y4log[n4log]);
86  x4log[n4log]=invTimes[i];
87  n4log++;
88  }
89  }
90  if(n4log > 1){ // perform log slope calculation
91  MeasureType rslope, roffset;
92  MeasureType r = KWUtil::SKPLinReg(x4log,y4log, n4log, rslope, roffset); // Linear regression , returns correlation coeff
93  if( ( r < 0 ) && ( rslope < 0 ))
94  {
95  initPoint[2]=-1./rslope;
96  if ((initPoint[2] < (invTimes[0]/3.)) || (initPoint[2]) > (2*invTimes[nSamples-1])) return (1) ; // EXIT_FAILURE something gone wrong.
97  initPoint[2] = KWUtil::min(initPoint[2], invTimes[nSamples-1]); // trim extremes
98  roffset=exp(roffset);
99  initPoint[0] = KWUtil::min(2*initPoint[0],roffset/2);// trim extremes
100  initPoint[1] = KWUtil::min(2*initPoint[1],roffset);// trim extremes
101  return(n4log);
102  }
103  }
104  return(0);
105  }
106 
111  this->setNDims(3);
112  _DefaultStartPoint[0] = 100;
113  _DefaultStartPoint[1] = 200;
114  _DefaultStartPoint[2] = 1000;
115  }
116 
121  this->setAllPointersToNull();
122 
123  _DefaultStartPoint[0] = old._DefaultStartPoint[0];
124  _DefaultStartPoint[1] = old._DefaultStartPoint[1];
125  _DefaultStartPoint[2] = old._DefaultStartPoint[2];
126  this->_nSamples = old._nSamples;
127  this->setNDims(old._nDims);
128  };
129 
135 
141 
142  protected:
143  MeasureType _DefaultStartPoint[3];
144 
145  };
146 } //namespace Ox
147 
148 #endif //Tomato_OXStartPointCalculatorShmolli_H
StartPointCalculatorShmolli()
constructor
Definition: OxStartPointCalculatorShmolli.h:110
virtual StartPointCalculator< MeasureType > * newByCloning()
Definition: OxStartPointCalculatorShmolli.h:134
void setAllPointersToNull()
set all the pointers to zero
Definition: OxStartPointCalculator.h:91
Definition: OxStartPointCalculatorShmolli.h:21
virtual int calculateStartPoint()
Definition: OxStartPointCalculatorShmolli.h:29
Definition: OxStartPointCalculator.h:21
Definition: OxCalculator.h:19
virtual ~StartPointCalculatorShmolli()
do not forget about the virtual destructor, see https://stackoverflow.com/questions/461203/when-to-us...
Definition: OxStartPointCalculatorShmolli.h:140
StartPointCalculatorShmolli(const StartPointCalculatorShmolli &old)
copy constructor
Definition: OxStartPointCalculatorShmolli.h:120