Tomato
OxImageCalculator.hxx
Go to the documentation of this file.
1 
7 #ifndef Tomato_OxImageCalculator_HXX
8 #define Tomato_OxImageCalculator_HXX
9 
10 namespace Ox {
11 
12  template<typename MeasureType>
13  ImageCalculator<MeasureType>
14  ::ImageCalculator(){
15  _useThreads = true;
16  _nThreads = 0;
17  _nCols = 0;
18  _nRows = 0;
19  _nSamples = 0;
20  _invTimes = 0; // nSamples
21  _echoTimes = 0; // nSamples
22  _imageMag = 0; // nCols * nRows * nSamples, address [iCol][iRow][iSam] iSample * (nCols*nRows) + iRow * nCols + iCol
23  _imagePha = 0; // nCols * nRows * nSamples, address [iCol][iRow][iSam] iSample * (nCols*nRows) + iRow * nCols + iCol
24  _imageResultsArray = 0; // nCols * nRows * nDims, address [iCol][iRow][iDim] iDim * (nCols*nRows) + iRow * nCols + iCol
25  _imageResultsMap = 0; // map of arrays, each size nCols * nRows
26 
27  _calculator = 0;
28  }
29 
30  template<typename MeasureType>
31  void
32  ImageCalculator<MeasureType>
33  ::setUseThreads(bool useThreads) {
34  ImageCalculator::_useThreads = useThreads;
35  }
36 
37  template<typename MeasureType>
38  void
39  ImageCalculator<MeasureType>
40  ::setNCols(int nCols) {
41  ImageCalculator::_nCols = nCols;
42  }
43 
44  template<typename MeasureType>
45  void
46  ImageCalculator<MeasureType>
47  ::setNRows(int nRows) {
48  ImageCalculator::_nRows = nRows;
49  }
50 
51  template<typename MeasureType>
52  void
53  ImageCalculator<MeasureType>
54  ::setNSamples(int nSamples) {
55  ImageCalculator::_nSamples = nSamples;
56  }
57 
58  template<typename MeasureType>
59  void
60  ImageCalculator<MeasureType>
61  ::setInvTimes(const MeasureType *invTimes) {
62  ImageCalculator::_invTimes = invTimes;
63  }
64 
65  template<typename MeasureType>
66  void
67  ImageCalculator<MeasureType>
68  ::setEchoTimes(const MeasureType *echoTimes) {
69  ImageCalculator::_echoTimes = echoTimes;
70  }
71 
72  template<typename MeasureType>
73  void
74  ImageCalculator<MeasureType>
75  ::setImageMag(const MeasureType *imageMag) {
76  ImageCalculator::_imageMag = imageMag;
77  }
78 
79  template<typename MeasureType>
80  void
81  ImageCalculator<MeasureType>
82  ::setImagePha(const MeasureType *imagePha) {
83  ImageCalculator::_imagePha = imagePha;
84  }
85 
86  template<typename MeasureType>
87  void
88  ImageCalculator<MeasureType>
89  ::setImageResultsArray(MeasureType *imageResultsArray) {
90  ImageCalculator::_imageResultsArray = imageResultsArray;
91  }
92 
93  template<typename MeasureType>
94  void
95  ImageCalculator<MeasureType>
96  ::setCalculator(Calculator <MeasureType> *calculator) {
97  ImageCalculator::_calculator = calculator;
98  }
99 
100  template<typename MeasureType>
101  MeasureType *
102  ImageCalculator<MeasureType>
103  ::getImageResultsArray() const {
104  return _imageResultsArray;
105  };
106 
107  template<typename MeasureType>
108  int
109  ImageCalculator<MeasureType>
110  ::calculate(){
111 
112  if (!_useThreads) {
113  int posStart = 0;
114  int posStop = _nCols * _nRows;
115  calculateOneThread(posStart, posStop);
116  }
117  else {
118 #ifndef TOMATO_USES_CXX_STANDARD_98
119 
120  // get the threads ready
121  std::vector<std::thread> threads;
122  unsigned concurentThreadsSupported = std::thread::hardware_concurrency();
123 
124  if (_nThreads == 0){
125  _nThreads = concurentThreadsSupported;
126  }
127 
128  // calc the range of pixels for each thread
129  std::vector<int> limits = KWUtil::bounds<MeasureType>(concurentThreadsSupported, _nCols * _nRows);
130 
131  // threaded loop
132  for (unsigned i = 0; i < concurentThreadsSupported; ++i){
133  threads.push_back(std::thread(&ImageCalculator<MeasureType>::calculateOneThread, this, limits[i], limits[i+1]));
134  }
135 
136  // finish threads
137  for(auto &t : threads){
138  t.join();
139  }
140 #else
141  throw std::runtime_error("Threads not supported in Tomato with C++98");
142 #endif
143  }
144  return 0; // EXIT_SUCCESS
145  }
146 
147  template<typename MeasureType>
148  int
149  ImageCalculator<MeasureType>
150  ::calculateOneThread(int posStart, int posStop){
151 
152  // perform all the calculations on the copies of original objects!!!
153 
154  // clone the necessary objects
155  Ox::Calculator<MeasureType> *calculator = _calculator->newByCloning();
156  Ox::Model<MeasureType> *model = 0;
157  if (_calculator->getModel()) {
158  model = _calculator->getModel()->newByCloning();
159  }
160  Ox::Fitter<MeasureType> *fitter = 0;
161  if (_calculator->getFitter()) {
162  fitter = _calculator->getFitter()->newByCloning();
163  }
164  Ox::SignCalculator<MeasureType> *signCalculator = 0;
165  if (_calculator->getSignCalculator()){
166  signCalculator = _calculator->getSignCalculator()->newByCloning();
167  }
168  Ox::StartPointCalculator<MeasureType> *startPointCalculator = 0;
169  if (_calculator->getStartPointCalculator()) {
170  startPointCalculator = _calculator->getStartPointCalculator()->newByCloning();
171  }
172 
173  // configure
174  if (model) calculator->setModel(model);
175  if (fitter) calculator->setFitter(fitter);
176  if (signCalculator) calculator->setSignCalculator(signCalculator);
177  if (startPointCalculator) calculator->setStartPointCalculator(startPointCalculator);
178 
179  calculator->setNSamples(_nSamples);
180  calculator->setInvTimes(_invTimes);
181  calculator->setEchoTimes(_echoTimes);
182 
183  for (int pos = posStart; pos < posStop; ++pos) {
184  // set the data
185  MeasureType *sigMag = new MeasureType[_nSamples];
186  MeasureType *sigPha = new MeasureType[_nSamples];
187 
188  for (int iSample = 0; iSample < _nSamples; ++iSample) {
189  sigMag[iSample] = _imageMag[iSample * (_nCols * _nRows) + pos];
190  if (_imagePha) sigPha[iSample] = _imagePha[iSample * (_nCols * _nRows) + pos];
191  }
192 
193  calculator->setSigMag(sigMag);
194  if(_imagePha) calculator->setSigPha(sigPha);
195 
196  calculator->calculate();
197 
198  // store results as array
199  if (_imageResultsArray) {
200  for (int iDim = 0; iDim < calculator->getNDims(); iDim++){
201  _imageResultsArray[iDim * (_nCols * _nRows) + pos] = calculator->getParametersAfterFitting()[iDim];
202  }
203  }
204 
205  // store results as map
206  if (_imageResultsMap) {
207  // iterate over each pair in the map
208  typename std::map<std::string, MeasureType*>::iterator it;
209  for ( it = _imageResultsMap->begin(); it != _imageResultsMap->end(); it++ ){
210  it->second[pos] = calculator->getResults()[it->first];
211  }
212  }
213 
214  delete [] sigMag;
215  delete [] sigPha;
216  }
217 
218  delete calculator;
219  delete model;
220  delete fitter;
221  delete signCalculator;
222  delete startPointCalculator;
223 
224  return 0; // EXIT_SUCCESS
225  }
226 
227  template<typename MeasureType>
228  void ImageCalculator<MeasureType>::setImageResultsMap(std::map<std::string, MeasureType *> *imageResultsMap) {
229  _imageResultsMap = imageResultsMap;
230  }
231 
232  template<typename MeasureType>
233  std::map<std::string, MeasureType *> *ImageCalculator<MeasureType>::getImageResultsMap() const {
234  return _imageResultsMap;
235  }
236 
237  template<typename MeasureType>
238  void ImageCalculator<MeasureType>::setNThreads(int nThreads) {
239  _nThreads = nThreads;
240  }
241 
242  template<typename MeasureType>
243  bool ImageCalculator<MeasureType>::isUseThreads() const {
244  return _useThreads;
245  }
246 
247  template<typename MeasureType>
248  unsigned ImageCalculator<MeasureType>::getNThreads() const {
249  return _nThreads;
250  }
251 
252 } // namespace Ox
253 
254 #endif //Tomato_OxImageCalculator_H
virtual SignCalculator< MeasureType > * newByCloning()=0
virtual int getNDims() const
Definition: OxCalculator.hxx:153
Container for a model function, cost function and Least-Squares function. And derivatives.
Definition: OxModel.h:26
Definition: OxCalculator.h:28
virtual Model< MeasureType > * newByCloning()=0
Definition: OxSignCalculator.h:21
virtual StartPointCalculator< MeasureType > * newByCloning()=0
Definition: OxStartPointCalculator.h:21
virtual int calculate()=0
virtual Fitter< MeasureType > * newByCloning()=0
Definition: OxFitter.h:22
virtual Calculator< MeasureType > * newByCloning()=0
Definition: OxCalculator.h:19
virtual void setNSamples(int _nSamples)
Definition: OxCalculator.hxx:240