CASToR  2.0
Tomographic Reconstruction (PET/SPECT/CT)
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
iProjectorIncrementalSiddonMulti.cc
Go to the documentation of this file.
1 /*
2 This file is part of CASToR.
3 
4  CASToR is free software: you can redistribute it and/or modify it under the
5  terms of the GNU General Public License as published by the Free Software
6  Foundation, either version 3 of the License, or (at your option) any later
7  version.
8 
9  CASToR is distributed in the hope that it will be useful, but WITHOUT ANY
10  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
12  details.
13 
14  You should have received a copy of the GNU General Public License along with
15  CASToR (in file GNU_GPL.TXT). If not, see <http://www.gnu.org/licenses/>.
16 
17 Copyright 2017-2018 all CASToR contributors listed below:
18 
19  --> current contributors: Thibaut MERLIN, Simon STUTE, Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Mael MILLARDET
20  --> past contributors: Valentin VIELZEUF
21 
22 This is CASToR version 2.0.
23 */
24 
32 #include "sOutputManager.hh"
33 
34 // =====================================================================
35 // ---------------------------------------------------------------------
36 // ---------------------------------------------------------------------
37 // =====================================================================
38 
40 {
41  m_nbLines = -1;
42  // This projector is not compatible with SPECT attenuation correction because
43  // the voxels contributing to the line are not strictly ordered with respect to
44  // their distance to point 2 (due to the use of multiple lines that are
45  // stack one after the other)
47  // This projector is not compatible with compression as it works only with the
48  // detection element indices
50 }
51 
52 // =====================================================================
53 // ---------------------------------------------------------------------
54 // ---------------------------------------------------------------------
55 // =====================================================================
56 
58 {
59 }
60 
61 // =====================================================================
62 // ---------------------------------------------------------------------
63 // ---------------------------------------------------------------------
64 // =====================================================================
65 
66 int iProjectorIncrementalSiddonMulti::ReadConfigurationFile(const string& a_configurationFile)
67 {
68  // Read the transaxial FWHM option
69  string key_word = "number of lines";
70  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_nbLines, 1, KEYWORD_MANDATORY))
71  {
72  Cerr("***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
73  return 1;
74  }
75  // Normal end
76  return 0;
77 }
78 
79 // =====================================================================
80 // ---------------------------------------------------------------------
81 // ---------------------------------------------------------------------
82 // =====================================================================
83 
84 int iProjectorIncrementalSiddonMulti::ReadOptionsList(const string& a_optionsList)
85 {
86  // Read them
87  if (ReadStringOption(a_optionsList, &m_nbLines, 1, ",", "Multi-Siddon configuration"))
88  {
89  Cerr("***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to correctly read the list of options !" << endl);
90  return 1;
91  }
92  // Normal end
93  return 0;
94 }
95 
96 // =====================================================================
97 // ---------------------------------------------------------------------
98 // ---------------------------------------------------------------------
99 // =====================================================================
100 
102 {
103  cout << "This projector uses multiple ray-tracing for a single event in order to estimate the solid angle contribution." << endl;
104  cout << "For each line of an event, the end points of the line are randomly chosen inside the detector element." << endl;
105  cout << "The ray-tracing is performed with the incremental Siddon algorithm (see incrementalSiddon projector)." << endl;
106  cout << "The only parameter of this projector is the number of lines to use per event:" << endl;
107  cout << " number of lines: the number of lines used per event" << endl;
108 }
109 
110 // =====================================================================
111 // ---------------------------------------------------------------------
112 // ---------------------------------------------------------------------
113 // =====================================================================
114 
116 {
117  // Send an error if less than 1 line
118  if (m_nbLines<1)
119  {
120  Cerr("***** iProjectorIncrementalSiddonMulti::CheckSpecificParameters() -> The provided number of lines is less than 1 !" << endl);
121  return 1;
122  }
123  // Normal end
124  return 0;
125 }
126 
127 // =====================================================================
128 // ---------------------------------------------------------------------
129 // ---------------------------------------------------------------------
130 // =====================================================================
131 
133 {
134  // Verbose
135  if (m_verbose>=2) Cout("iProjectorIncrementalSiddonMulti::Initialize() -> Use incremental Siddon projector with " << m_nbLines << " lines per event" << endl);
136  // Normal end
137  return 0;
138 }
139 
140 // =====================================================================
141 // ---------------------------------------------------------------------
142 // ---------------------------------------------------------------------
143 // =====================================================================
144 
146 {
147  // Find the maximum number of voxels along a given dimension
148  INTNB max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxX();
149  if (mp_ImageDimensionsAndQuantification->GetNbVoxY()>max_nb_voxels_in_dimension) max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxY();
150  if (mp_ImageDimensionsAndQuantification->GetNbVoxZ()>max_nb_voxels_in_dimension) max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxZ();
151  // We should have at most 4 voxels in a given plane, so multiply by 4
152  // (note: this is not true however it ensures no overflow and is already quite optimized for RAM usage !)
153  max_nb_voxels_in_dimension *= 4;
154  // Finally multiply by the number of lines
155  max_nb_voxels_in_dimension *= ((INTNB)m_nbLines);
156  // Return the value
157  return max_nb_voxels_in_dimension;
158 }
159 
160 // =====================================================================
161 // ---------------------------------------------------------------------
162 // ---------------------------------------------------------------------
163 // =====================================================================
164 
166 {
167  #ifdef CASTOR_DEBUG
168  if (!m_initialized)
169  {
170  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithoutTOF() -> Called while not initialized !" << endl);
171  Exit(EXIT_DEBUG);
172  }
173  #endif
174 
175  #ifdef CASTOR_VERBOSE
176  if (m_verbose>=10)
177  {
178  string direction = "";
179  if (a_direction==FORWARD) direction = "forward";
180  else direction = "backward";
181  Cout("iProjectorIncrementalSiddonMulti::Project without TOF -> Project line '" << ap_ProjectionLine << "' in " << direction << " direction" << endl);
182  }
183  #endif
184 
185  // Loop on the number of lines
186  for (int line=0; line<m_nbLines; line++)
187  {
188  // Get random positions from the scanner (mean depth of interaction intrinsicaly taken into account), taking POI into account if any
189  if (mp_Scanner->GetRdmPositionsAndOrientations( ap_ProjectionLine->GetIndex1(), ap_ProjectionLine->GetIndex2(),
190  ap_ProjectionLine->GetPosition1(), ap_ProjectionLine->GetPosition2(),
191  ap_ProjectionLine->GetOrientation1(), ap_ProjectionLine->GetOrientation2() ))
192  {
193  Cerr("***** vProjector::Project() -> A problem occured while getting positions and orientations from scanner !" << endl);
194  return 1;
195  }
196 
197  // Get end points position
198  FLTNB* event1Float = ap_ProjectionLine->GetPosition1();
199  FLTNB* event2Float = ap_ProjectionLine->GetPosition2();
200  HPFLTNB event1[3] = { event1Float[0], event1Float[1], event1Float[2] };
201  HPFLTNB event2[3] = { event2Float[0], event2Float[1], event2Float[2] };
202 
203 
204 
205 
206 
207 
208 
209 
210  // **************************************
211  // STEP 1: LOR length calculation
212  // **************************************
213  HPFLTNB length_LOR = ap_ProjectionLine->GetLength();
214 
215  // **************************************
216  // STEP 2: Compute entrance voxel indexes
217  // **************************************
218  HPFLTNB alphaFirst[] = { 0.0, 0.0, 0.0 };
219  HPFLTNB alphaLast[] = { 0.0, 0.0, 0.0 };
220 
221  HPFLTNB alphaMin = 0.0f, alphaMax = 1.0f;
222  HPFLTNB delta_pos[] = {
223  event2[ 0 ] - event1[ 0 ],
224  event2[ 1 ] - event1[ 1 ],
225  event2[ 2 ] - event1[ 2 ]
226  };
227 
228  // Computation of alphaMin et alphaMax values (entrance and exit point of the ray)
229  for( int i = 0; i < 3; ++i )
230  {
231  if( delta_pos[ i ] != 0.0 )
232  {
233  alphaFirst[i] = (-mp_halfFOV[i] - event1[i]) / (delta_pos[ i ]);
234  alphaLast[i] = ( mp_halfFOV[i] - event1[i]) / (delta_pos[ i ]);
235  alphaMin = (std::max)(alphaMin,(std::min)(alphaFirst[i],alphaLast[i]));
236  alphaMax = (std::min)(alphaMax,(std::max)(alphaFirst[i],alphaLast[i]));
237  }
238  }
239 
240  // if alphaMax is less than or equal to alphaMin no intersection
241  // and return an empty buffer
242  if( alphaMax <= alphaMin ) return 0;
243 
244  // Now we have to find the indices of the particular plane
245  // (iMin,iMax), (jMin,jMax), (kMin,kMax)
246  int iMin = 0, iMax = 0;
247  int jMin = 0, jMax = 0;
248  int kMin = 0, kMax = 0;
249 
250  // For the X-axis
251  if( delta_pos[ 0 ] > 0.0f)
252  {
253  iMin = ::ceil( ( mp_nbVox[ 0 ] + 1 ) - ( mp_halfFOV[ 0 ] - alphaMin * delta_pos[ 0 ] - event1[ 0 ] ) / mp_sizeVox[0] );
254  iMax = ::floor( 1 + ( event1[ 0 ] + alphaMax * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] );
255  }
256  else if( delta_pos[ 0 ] < 0.0 )
257  {
258  iMin = ::ceil( ( mp_nbVox[ 0 ] + 1 ) - ( mp_halfFOV[ 0 ] - alphaMax * delta_pos[ 0 ] - event1[ 0 ] ) / mp_sizeVox[0] );
259  iMax = ::floor( 1 + ( event1[ 0 ] + alphaMin * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] );
260  }
261  if( delta_pos[ 0 ] == 0 )
262  {
263  iMin = 1, iMax = 0;
264  }
265 
266  // For the Y-axis
267  if( delta_pos[ 1 ] > 0 )
268  {
269  jMin = ::ceil( ( mp_nbVox[ 1 ] + 1 ) - ( mp_halfFOV[ 1 ] - alphaMin * delta_pos[ 1 ] - event1[ 1 ] ) / mp_sizeVox[1] );
270  jMax = ::floor( 1 + ( event1[ 1 ] + alphaMax * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] );
271  }
272  else if( delta_pos[ 1 ] < 0 )
273  {
274  jMin = ::ceil( ( mp_nbVox[ 1 ] + 1 ) - ( mp_halfFOV[ 1 ] - alphaMax * delta_pos[ 1 ] - event1[ 1 ] ) / mp_sizeVox[1] );
275  jMax = ::floor( 1 + ( event1[ 1 ] + alphaMin * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] );
276  }
277  else if( delta_pos[ 1 ] == 0 )
278  {
279  jMin = 1, jMax = 0;
280  }
281 
282  // For the Z-axis
283  if( delta_pos[ 2 ] > 0 )
284  {
285  kMin = ::ceil( ( mp_nbVox[ 2 ] + 1 ) - ( mp_halfFOV[ 2 ] - alphaMin * delta_pos[ 2 ] - event1[ 2 ] ) / mp_sizeVox[2] );
286  kMax = ::floor( 1 + ( event1[ 2 ] + alphaMax * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] );
287  }
288  else if( delta_pos[ 2 ] < 0 )
289  {
290  kMin = ::ceil( ( mp_nbVox[ 2 ] + 1 ) - ( mp_halfFOV[ 2 ] - alphaMax * delta_pos[ 2 ] - event1[ 2 ] ) / mp_sizeVox[2] );
291  kMax = ::floor( 1 + ( event1[ 2 ] + alphaMin * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] );
292  }
293  else if( delta_pos[ 2 ] == 0 )
294  {
295  kMin = 1, kMax = 0;
296  }
297 
298  // Computing the last term n number of intersection
299  INTNB n = ( iMax - iMin + 1 ) + ( jMax - jMin + 1 )
300  + ( kMax - kMin + 1 );
301 
302  // Array storing the first alpha in X, Y and Z
303  HPFLTNB alpha_XYZ[ 3 ] = { 1.0, 1.0, 1.0 };
304 
305  // Computing the first alpha in X
306  if( delta_pos[ 0 ] > 0 )
307  alpha_XYZ[ 0 ] = ( ( (-mp_halfFOV[ 0 ]) + ( iMin - 1 ) * mp_sizeVox[0] ) - event1[ 0 ] ) / delta_pos[ 0 ];
308  else if( delta_pos[ 0 ] < 0 )
309  alpha_XYZ[ 0 ] = ( ( (-mp_halfFOV[ 0 ]) + ( iMax - 1 ) * mp_sizeVox[0] ) - event1[ 0 ] ) / delta_pos[ 0 ];
310 
311  // Computing the first alpha in Y
312  if( delta_pos[ 1 ] > 0 )
313  alpha_XYZ[ 1 ] = ( ( (-mp_halfFOV[ 1 ]) + ( jMin - 1 ) * mp_sizeVox[1] ) - event1[ 1 ] ) / delta_pos[ 1 ];
314  else if( delta_pos[ 1 ] < 0 )
315  alpha_XYZ[ 1 ] = ( ( (-mp_halfFOV[ 1 ]) + ( jMax - 1 ) * mp_sizeVox[1] ) - event1[ 1 ] ) / delta_pos[ 1 ];
316 
317  // Computing the first alpha in Z
318  if( delta_pos[ 2 ] > 0 )
319  alpha_XYZ[ 2 ] = ( ( (-mp_halfFOV[ 2 ]) + ( kMin - 1 ) * mp_sizeVox[2] ) - event1[ 2 ] ) / delta_pos[ 2 ];
320  else if( delta_pos[ 2 ] < 0 )
321  alpha_XYZ[ 2 ] = ( ( (-mp_halfFOV[ 2 ]) + ( kMax - 1 ) * mp_sizeVox[2] ) - event1[ 2 ] ) / delta_pos[ 2 ];
322 
323  // Computing the alpha updating
324  HPFLTNB alpha_u[ 3 ] = {
325  mp_sizeVox[0] / std::fabs( delta_pos[ 0 ] ),
326  mp_sizeVox[1] / std::fabs( delta_pos[ 1 ] ),
327  mp_sizeVox[2] / std::fabs( delta_pos[ 2 ] )
328  };
329 
330  // Computing the index updating
331  INTNB index_u[ 3 ] = {
332  (delta_pos[ 0 ] < 0) ? -1 : 1,
333  (delta_pos[ 1 ] < 0) ? -1 : 1,
334  (delta_pos[ 2 ] < 0) ? -1 : 1
335  };
336 
337  // Check which alpha is the min/max and increment
338  if( alpha_XYZ[ 0 ] == alphaMin ) alpha_XYZ[ 0 ] += alpha_u[ 0 ];
339  if( alpha_XYZ[ 1 ] == alphaMin ) alpha_XYZ[ 1 ] += alpha_u[ 1 ];
340  if( alpha_XYZ[ 2 ] == alphaMin ) alpha_XYZ[ 2 ] += alpha_u[ 2 ];
341 
342  // Computing the minimum value in the alpha_XYZ buffer
343  HPFLTNB const min_alpha_XYZ = (std::min)( alpha_XYZ[ 0 ],
344  (std::min)( alpha_XYZ[ 1 ], alpha_XYZ[ 2 ] ) );
345 
346  // Computing the first index of intersection
347  HPFLTNB const alphaMid = ( min_alpha_XYZ + alphaMin ) / 2.0f;
348  INTNB index_ijk[ 3 ] = {
349  1 + (int)( ( event1[ 0 ] + alphaMid * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] ),
350  1 + (int)( ( event1[ 1 ] + alphaMid * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] ),
351  1 + (int)( ( event1[ 2 ] + alphaMid * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] )
352  };
353 
354  INTNB const w = mp_nbVox[ 0 ];
355  INTNB const wh = w * mp_nbVox[ 1 ];
356 
357  // Loop over the number of plane to cross
358  HPFLTNB alpha_c = alphaMin;
359  FLTNB coeff = 0.0;
360  INTNB numVox = 0;
361  for( int nP = 0; nP < n - 1; ++nP )
362  {
363  if( ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 1 ] )
364  && ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 2 ] ) )
365  {
366  // Storing values
367  if( ( alpha_XYZ[ 0 ] >= alphaMin )
368  && ( index_ijk[ 0 ] - 1 >= 0 )
369  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
370  && ( index_ijk[ 1 ] - 1 >= 0 )
371  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
372  && ( index_ijk[ 2 ] - 1 >= 0 )
373  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
374  {
375  coeff = ( alpha_XYZ[ 0 ] - alpha_c ) * length_LOR;
376  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
377  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
378  }
379 
380  // Increment values
381  alpha_c = alpha_XYZ[ 0 ];
382  alpha_XYZ[ 0 ] += alpha_u[ 0 ];
383  index_ijk[ 0 ] += index_u[ 0 ];
384  }
385  else if( ( alpha_XYZ[ 1 ] < alpha_XYZ[ 0 ] )
386  && ( alpha_XYZ[ 1 ] <= alpha_XYZ[ 2 ] ) )
387  {
388  // Storing values
389  if( ( alpha_XYZ[ 1 ] >= alphaMin )
390  && ( index_ijk[ 0 ] - 1 >= 0 )
391  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
392  && ( index_ijk[ 1 ] - 1 >= 0 )
393  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
394  && ( index_ijk[ 2 ] - 1 >= 0 )
395  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
396  {
397  coeff = ( alpha_XYZ[ 1 ] - alpha_c ) * length_LOR;
398  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
399  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
400  }
401 
402  // Increment values
403  alpha_c = alpha_XYZ[ 1 ];
404  alpha_XYZ[ 1 ] += alpha_u[ 1 ];
405  index_ijk[ 1 ] += index_u[ 1 ];
406  }
407  else if( ( alpha_XYZ[ 2 ] < alpha_XYZ[ 0 ] )
408  && ( alpha_XYZ[ 2 ] < alpha_XYZ[ 1 ] ) )
409  {
410  // Storing values
411  if( ( alpha_XYZ[ 2 ] >= alphaMin )
412  && ( index_ijk[ 0 ] - 1 >= 0 )
413  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
414  && ( index_ijk[ 1 ] - 1 >= 0 )
415  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
416  && ( index_ijk[ 2 ] - 1 >= 0 )
417  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
418  {
419  coeff = ( alpha_XYZ[ 2 ] - alpha_c ) * length_LOR;
420  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
421  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
422  }
423 
424  // Increment values
425  alpha_c = alpha_XYZ[ 2 ];
426  alpha_XYZ[ 2 ] += alpha_u[ 2 ];
427  index_ijk[ 2 ] += index_u[ 2 ];
428  }
429  }
430  }
431 
432  return 0;
433 }
434 
435 // =====================================================================
436 // ---------------------------------------------------------------------
437 // ---------------------------------------------------------------------
438 // =====================================================================
439 
441 {
442  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithTOFPos() -> Not yet implemented !" << endl);
443  return 1;
444 }
445 
446 // =====================================================================
447 // ---------------------------------------------------------------------
448 // ---------------------------------------------------------------------
449 // =====================================================================
450 
452 {
453  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithTOFBin() -> Not yet implemented !" << endl);
454  return 1;
455 }
456 
457 // =====================================================================
458 // ---------------------------------------------------------------------
459 // ---------------------------------------------------------------------
460 // =====================================================================
void ShowHelpSpecific()
A function used to show help about the child module.
bool m_compatibleWithSPECTAttenuationCorrection
Definition: vProjector.hh:355
FLTNB * GetOrientation1()
This function is used to get the pointer to the mp_orientation1 (3-values tab).
FLTNB mp_sizeVox[3]
Definition: vProjector.hh:338
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
INTNB mp_nbVox[3]
Definition: vProjector.hh:339
#define FLTNB
Definition: gVariables.hh:81
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
Definition: vProjector.hh:344
#define HPFLTNB
Definition: gVariables.hh:83
This class is designed to generically described any on-the-fly projector.
Definition: vProjector.hh:76
int ProjectWithTOFPos(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project with TOF continuous information.
int InitializeSpecific()
This function is used to initialize specific stuff to the child projector.
FLTNB GetLength()
This function is used to get the length of the line.
FLTNB * GetOrientation2()
This function is used to get the pointer to the mp_orientation2 (3-values tab).
void Exit(int code)
#define Cerr(MESSAGE)
int GetIndex2()
This function is used to get the index associated to point 2.
FLTNB * GetPosition1()
This function is used to get the pointer to the mp_position1 (3-values tab).
bool m_initialized
Definition: vProjector.hh:364
int ProjectWithTOFBin(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project with TOF binned information.
INTNB EstimateMaxNumberOfVoxelsPerLine()
This function is used to compute and provide an estimate of the maximum number of voxels that could c...
void AddVoxel(int a_direction, INTNB a_voxelIndice, FLTNB a_voxelWeight)
This function is used to add a voxel contribution to the line, assuming TOF bin 0 (i...
int ReadDataASCIIFile(const string &a_file, const string &a_keyword, T *ap_return, int a_nbElts, bool a_mandatoryFlag)
Look for "a_nbElts" elts in the "a_file" file matching the "a_keyword" string passed as parameter a...
Definition: gOptions.cc:123
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child projector.
Declaration of class iProjectorIncrementalSiddonMulti.
#define KEYWORD_MANDATORY
Definition: gOptions.hh:48
virtual int GetRdmPositionsAndOrientations(int a_index1, int a_index2, FLTNB ap_Position1[3], FLTNB ap_Position2[3], FLTNB ap_Orientation1[3], FLTNB ap_Orientation2[3])=0
This is a pure virtual method that must be implemented by children. Get random positions of the sca...
~iProjectorIncrementalSiddonMulti()
The destructor of iProjectorIncrementalSiddonMulti.
#define INTNB
Definition: gVariables.hh:92
This class is designed to manage and store system matrix elements associated to a vEvent...
Declaration of class sOutputManager.
iProjectorIncrementalSiddonMulti()
The constructor of iProjectorIncrementalSiddonMulti.
FLTNB mp_halfFOV[3]
Definition: vProjector.hh:341
#define EXIT_DEBUG
Definition: gVariables.hh:97
FLTNB * GetPosition2()
This function is used to get the pointer to the mp_position2 (3-values tab).
INTNB GetNbVoxX()
Get the number of voxels along the X axis.
INTNB GetNbVoxZ()
Get the number of voxels along the Z axis.
#define FORWARD
#define Cout(MESSAGE)
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
bool m_compatibleWithCompression
Definition: vProjector.hh:358
int GetIndex1()
This function is used to get the index associated to point 1.
int ReadStringOption(const string &a_input, T *ap_return, int a_nbElts, const string &sep, const string &a_option)
Parse the 'a_input' string corresponding to the 'a_option' into 'a_nbElts' elements, using the 'sep' separator. The results are returned in the templated 'ap_return' dynamic templated array. Call "ConvertFromString()" to perform the correct conversion depending on the type of the data to convert.
Definition: gOptions.cc:62
vScanner * mp_Scanner
Definition: vProjector.hh:346
int ProjectWithoutTOF(int a_direction, oProjectionLine *ap_ProjectionLine)
A function to project without TOF.
INTNB GetNbVoxY()
Get the number of voxels along the Y axis.