CASToR  1.1
Tomographic Reconstruction (PET/SPECT)
 All Classes Files Functions Variables Typedefs Macros Groups Pages
iProjectorIncrementalSiddonMulti.cc
Go to the documentation of this file.
1 
2 /*
3  Implementation of class iProjectorIncrementalSiddonMulti
4 
5  - separators: done
6  - doxygen: done
7  - default initialization: done
8  - CASTOR_DEBUG:
9  - CASTOR_VERBOSE:
10 */
11 
19 #include "sOutputManager.hh"
20 
21 // =====================================================================
22 // ---------------------------------------------------------------------
23 // ---------------------------------------------------------------------
24 // =====================================================================
25 
27 {
28  m_nbLines = -1;
29  // This projector is not compatible with SPECT attenuation correction because
30  // the voxels contributing to the line are not strictly ordered with respect to
31  // their distance to point 2 (due to the use of multiple lines that are
32  // stack one after the other)
34 }
35 
36 // =====================================================================
37 // ---------------------------------------------------------------------
38 // ---------------------------------------------------------------------
39 // =====================================================================
40 
42 {
43 }
44 
45 // =====================================================================
46 // ---------------------------------------------------------------------
47 // ---------------------------------------------------------------------
48 // =====================================================================
49 
50 int iProjectorIncrementalSiddonMulti::ReadConfigurationFile(const string& a_configurationFile)
51 {
52  // Read the transaxial FWHM option
53  string key_word = "number of lines";
54  if (ReadDataASCIIFile(a_configurationFile, key_word, &m_nbLines, 1, KEYWORD_MANDATORY))
55  {
56  Cerr("***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to get the '" << key_word << "' keyword !" << endl);
57  return 1;
58  }
59  // Normal end
60  return 0;
61 }
62 
63 // =====================================================================
64 // ---------------------------------------------------------------------
65 // ---------------------------------------------------------------------
66 // =====================================================================
67 
68 int iProjectorIncrementalSiddonMulti::ReadOptionsList(const string& a_optionsList)
69 {
70  // Read them
71  if (ReadStringOption(a_optionsList, &m_nbLines, 1, ",", "Multi-Siddon configuration"))
72  {
73  Cerr("***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to correctly read the list of options !" << endl);
74  return 1;
75  }
76  // Normal end
77  return 0;
78 }
79 
80 // =====================================================================
81 // ---------------------------------------------------------------------
82 // ---------------------------------------------------------------------
83 // =====================================================================
84 
86 {
87  cout << "This projector uses multiple ray-tracing for a single event in order to estimate the solid angle contribution." << endl;
88  cout << "For each line of an event, the end points of the line are randomly chosen inside the detector element." << endl;
89  cout << "The ray-tracing is performed with the incremental Siddon algorithm (see incrementalSiddon projector)." << endl;
90  cout << "The only parameter of this projector is the number of lines to use per event:" << endl;
91  cout << " number of lines: the number of lines used per event" << endl;
92 }
93 
94 // =====================================================================
95 // ---------------------------------------------------------------------
96 // ---------------------------------------------------------------------
97 // =====================================================================
98 
100 {
101  // Send an error if less than 1 line
102  if (m_nbLines<1)
103  {
104  Cerr("***** iProjectorIncrementalSiddonMulti::CheckSpecificParameters() -> The provided number of lines is less than 1 !" << endl);
105  return 1;
106  }
107  // Normal end
108  return 0;
109 }
110 
111 // =====================================================================
112 // ---------------------------------------------------------------------
113 // ---------------------------------------------------------------------
114 // =====================================================================
115 
117 {
118  // Verbose
119  if (m_verbose>=2) Cout("iProjectorIncrementalSiddonMulti::Initialize() -> Use incremental Siddon projector with " << m_nbLines << " lines per event" << endl);
120  // Normal end
121  return 0;
122 }
123 
124 // =====================================================================
125 // ---------------------------------------------------------------------
126 // ---------------------------------------------------------------------
127 // =====================================================================
128 
130 {
131  // Find the maximum number of voxels along a given dimension
132  INTNB max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxX();
133  if (mp_ImageDimensionsAndQuantification->GetNbVoxY()>max_nb_voxels_in_dimension) max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxY();
134  if (mp_ImageDimensionsAndQuantification->GetNbVoxZ()>max_nb_voxels_in_dimension) max_nb_voxels_in_dimension = mp_ImageDimensionsAndQuantification->GetNbVoxZ();
135  // We should have at most 4 voxels in a given plane, so multiply by 4
136  // (note: this is not true however it ensures no overflow and is already quite optimized for RAM usage !)
137  max_nb_voxels_in_dimension *= 4;
138  // Finally multiply by the number of lines
139  max_nb_voxels_in_dimension *= ((INTNB)m_nbLines);
140  // Return the value
141  return max_nb_voxels_in_dimension;
142 }
143 
144 // =====================================================================
145 // ---------------------------------------------------------------------
146 // ---------------------------------------------------------------------
147 // =====================================================================
148 
150 {
151  #ifdef CASTOR_DEBUG
152  if (!m_initialized)
153  {
154  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithoutTOF() -> Called while not initialized !" << endl);
155  Exit(EXIT_DEBUG);
156  }
157  #endif
158 
159  #ifdef CASTOR_VERBOSE
160  if (m_verbose>=10)
161  {
162  string direction = "";
163  if (a_direction==FORWARD) direction = "forward";
164  else direction = "backward";
165  Cout("iProjectorIncrementalSiddonMulti::Project without TOF -> Project line '" << ap_ProjectionLine << "' in " << direction << " direction" << endl);
166  }
167  #endif
168 
169  // Loop on the number of lines
170  for (int line=0; line<m_nbLines; line++)
171  {
172  // Get random positions from the scanner (mean depth of interaction intrinsicaly taken into account), taking POI into account if any
173  if (mp_Scanner->GetRdmPositionsAndOrientations( ap_ProjectionLine->GetIndex1(), ap_ProjectionLine->GetIndex2(),
174  ap_ProjectionLine->GetPosition1(), ap_ProjectionLine->GetPosition2(),
175  ap_ProjectionLine->GetOrientation1(), ap_ProjectionLine->GetOrientation2() ))
176  {
177  Cerr("***** vProjector::Project() -> A problem occured while getting positions and orientations from scanner !" << endl);
178  return 1;
179  }
180 
181  // Get end points position
182  FLTNB* event1Float = ap_ProjectionLine->GetPosition1();
183  FLTNB* event2Float = ap_ProjectionLine->GetPosition2();
184  double event1[3] = { event1Float[0], event1Float[1], event1Float[2] };
185  double event2[3] = { event2Float[0], event2Float[1], event2Float[2] };
186 
187 
188 
189 
190 
191 
192 
193 
194  // **************************************
195  // STEP 1: LOR length calculation
196  // **************************************
197  double length_LOR = ap_ProjectionLine->GetLength();
198 
199  // **************************************
200  // STEP 2: Compute entrance voxel indexes
201  // **************************************
202  double alphaFirst[] = { 0.0, 0.0, 0.0 };
203  double alphaLast[] = { 0.0, 0.0, 0.0 };
204 
205  double alphaMin = 0.0f, alphaMax = 1.0f;
206  double delta_pos[] = {
207  event2[ 0 ] - event1[ 0 ],
208  event2[ 1 ] - event1[ 1 ],
209  event2[ 2 ] - event1[ 2 ]
210  };
211 
212  // Computation of alphaMin et alphaMax values (entrance and exit point of the ray)
213  for( int i = 0; i < 3; ++i )
214  {
215  if( delta_pos[ i ] != 0.0 )
216  {
217  alphaFirst[i] = (-mp_halfFOV[i] - event1[i]) / (delta_pos[ i ]);
218  alphaLast[i] = ( mp_halfFOV[i] - event1[i]) / (delta_pos[ i ]);
219  alphaMin = (std::max)(alphaMin,(std::min)(alphaFirst[i],alphaLast[i]));
220  alphaMax = (std::min)(alphaMax,(std::max)(alphaFirst[i],alphaLast[i]));
221  }
222  }
223 
224  // if alphaMax is less than or equal to alphaMin no intersection
225  // and return an empty buffer
226  if( alphaMax <= alphaMin ) return 0;
227 
228  // Now we have to find the indices of the particular plane
229  // (iMin,iMax), (jMin,jMax), (kMin,kMax)
230  int iMin = 0, iMax = 0;
231  int jMin = 0, jMax = 0;
232  int kMin = 0, kMax = 0;
233 
234  // For the X-axis
235  if( delta_pos[ 0 ] > 0.0f)
236  {
237  iMin = ::ceil( ( mp_nbVox[ 0 ] + 1 ) - ( mp_halfFOV[ 0 ] - alphaMin * delta_pos[ 0 ] - event1[ 0 ] ) / mp_sizeVox[0] );
238  iMax = ::floor( 1 + ( event1[ 0 ] + alphaMax * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] );
239  }
240  else if( delta_pos[ 0 ] < 0.0 )
241  {
242  iMin = ::ceil( ( mp_nbVox[ 0 ] + 1 ) - ( mp_halfFOV[ 0 ] - alphaMax * delta_pos[ 0 ] - event1[ 0 ] ) / mp_sizeVox[0] );
243  iMax = ::floor( 1 + ( event1[ 0 ] + alphaMin * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] );
244  }
245  if( delta_pos[ 0 ] == 0 )
246  {
247  iMin = 1, iMax = 0;
248  }
249 
250  // For the Y-axis
251  if( delta_pos[ 1 ] > 0 )
252  {
253  jMin = ::ceil( ( mp_nbVox[ 1 ] + 1 ) - ( mp_halfFOV[ 1 ] - alphaMin * delta_pos[ 1 ] - event1[ 1 ] ) / mp_sizeVox[1] );
254  jMax = ::floor( 1 + ( event1[ 1 ] + alphaMax * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] );
255  }
256  else if( delta_pos[ 1 ] < 0 )
257  {
258  jMin = ::ceil( ( mp_nbVox[ 1 ] + 1 ) - ( mp_halfFOV[ 1 ] - alphaMax * delta_pos[ 1 ] - event1[ 1 ] ) / mp_sizeVox[1] );
259  jMax = ::floor( 1 + ( event1[ 1 ] + alphaMin * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] );
260  }
261  else if( delta_pos[ 1 ] == 0 )
262  {
263  jMin = 1, jMax = 0;
264  }
265 
266  // For the Z-axis
267  if( delta_pos[ 2 ] > 0 )
268  {
269  kMin = ::ceil( ( mp_nbVox[ 2 ] + 1 ) - ( mp_halfFOV[ 2 ] - alphaMin * delta_pos[ 2 ] - event1[ 2 ] ) / mp_sizeVox[2] );
270  kMax = ::floor( 1 + ( event1[ 2 ] + alphaMax * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] );
271  }
272  else if( delta_pos[ 2 ] < 0 )
273  {
274  kMin = ::ceil( ( mp_nbVox[ 2 ] + 1 ) - ( mp_halfFOV[ 2 ] - alphaMax * delta_pos[ 2 ] - event1[ 2 ] ) / mp_sizeVox[2] );
275  kMax = ::floor( 1 + ( event1[ 2 ] + alphaMin * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] );
276  }
277  else if( delta_pos[ 2 ] == 0 )
278  {
279  kMin = 1, kMax = 0;
280  }
281 
282  // Computing the last term n number of intersection
283  INTNB n = ( iMax - iMin + 1 ) + ( jMax - jMin + 1 )
284  + ( kMax - kMin + 1 );
285 
286  // Array storing the first alpha in X, Y and Z
287  double alpha_XYZ[ 3 ] = { 1.0, 1.0, 1.0 };
288 
289  // Computing the first alpha in X
290  if( delta_pos[ 0 ] > 0 )
291  alpha_XYZ[ 0 ] = ( ( (-mp_halfFOV[ 0 ]) + ( iMin - 1 ) * mp_sizeVox[0] ) - event1[ 0 ] ) / delta_pos[ 0 ];
292  else if( delta_pos[ 0 ] < 0 )
293  alpha_XYZ[ 0 ] = ( ( (-mp_halfFOV[ 0 ]) + ( iMax - 1 ) * mp_sizeVox[0] ) - event1[ 0 ] ) / delta_pos[ 0 ];
294 
295  // Computing the first alpha in Y
296  if( delta_pos[ 1 ] > 0 )
297  alpha_XYZ[ 1 ] = ( ( (-mp_halfFOV[ 1 ]) + ( jMin - 1 ) * mp_sizeVox[1] ) - event1[ 1 ] ) / delta_pos[ 1 ];
298  else if( delta_pos[ 1 ] < 0 )
299  alpha_XYZ[ 1 ] = ( ( (-mp_halfFOV[ 1 ]) + ( jMax - 1 ) * mp_sizeVox[1] ) - event1[ 1 ] ) / delta_pos[ 1 ];
300 
301  // Computing the first alpha in Z
302  if( delta_pos[ 2 ] > 0 )
303  alpha_XYZ[ 2 ] = ( ( (-mp_halfFOV[ 2 ]) + ( kMin - 1 ) * mp_sizeVox[2] ) - event1[ 2 ] ) / delta_pos[ 2 ];
304  else if( delta_pos[ 2 ] < 0 )
305  alpha_XYZ[ 2 ] = ( ( (-mp_halfFOV[ 2 ]) + ( kMax - 1 ) * mp_sizeVox[2] ) - event1[ 2 ] ) / delta_pos[ 2 ];
306 
307  // Computing the alpha updating
308  double alpha_u[ 3 ] = {
309  mp_sizeVox[0] / std::fabs( delta_pos[ 0 ] ),
310  mp_sizeVox[1] / std::fabs( delta_pos[ 1 ] ),
311  mp_sizeVox[2] / std::fabs( delta_pos[ 2 ] )
312  };
313 
314  // Computing the index updating
315  INTNB index_u[ 3 ] = {
316  (delta_pos[ 0 ] < 0) ? -1 : 1,
317  (delta_pos[ 1 ] < 0) ? -1 : 1,
318  (delta_pos[ 2 ] < 0) ? -1 : 1
319  };
320 
321  // Check which alpha is the min/max and increment
322  if( alpha_XYZ[ 0 ] == alphaMin ) alpha_XYZ[ 0 ] += alpha_u[ 0 ];
323  if( alpha_XYZ[ 1 ] == alphaMin ) alpha_XYZ[ 1 ] += alpha_u[ 1 ];
324  if( alpha_XYZ[ 2 ] == alphaMin ) alpha_XYZ[ 2 ] += alpha_u[ 2 ];
325 
326  // Computing the minimum value in the alpha_XYZ buffer
327  double const min_alpha_XYZ = (std::min)( alpha_XYZ[ 0 ],
328  (std::min)( alpha_XYZ[ 1 ], alpha_XYZ[ 2 ] ) );
329 
330  // Computing the first index of intersection
331  double const alphaMid = ( min_alpha_XYZ + alphaMin ) / 2.0f;
332  INTNB index_ijk[ 3 ] = {
333  1 + (int)( ( event1[ 0 ] + alphaMid * delta_pos[ 0 ] - (-mp_halfFOV[ 0 ]) ) / mp_sizeVox[0] ),
334  1 + (int)( ( event1[ 1 ] + alphaMid * delta_pos[ 1 ] - (-mp_halfFOV[ 1 ]) ) / mp_sizeVox[1] ),
335  1 + (int)( ( event1[ 2 ] + alphaMid * delta_pos[ 2 ] - (-mp_halfFOV[ 2 ]) ) / mp_sizeVox[2] )
336  };
337 
338  INTNB const w = mp_nbVox[ 0 ];
339  INTNB const wh = w * mp_nbVox[ 1 ];
340 
341  // Loop over the number of plane to cross
342  double alpha_c = alphaMin;
343  FLTNB coeff = 0.0;
344  INTNB numVox = 0;
345  for( int nP = 0; nP < n - 1; ++nP )
346  {
347  if( ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 1 ] )
348  && ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 2 ] ) )
349  {
350  // Storing values
351  if( ( alpha_XYZ[ 0 ] >= alphaMin )
352  && ( index_ijk[ 0 ] - 1 >= 0 )
353  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
354  && ( index_ijk[ 1 ] - 1 >= 0 )
355  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
356  && ( index_ijk[ 2 ] - 1 >= 0 )
357  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
358  {
359  coeff = ( alpha_XYZ[ 0 ] - alpha_c ) * length_LOR;
360  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
361  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
362  }
363 
364  // Increment values
365  alpha_c = alpha_XYZ[ 0 ];
366  alpha_XYZ[ 0 ] += alpha_u[ 0 ];
367  index_ijk[ 0 ] += index_u[ 0 ];
368  }
369  else if( ( alpha_XYZ[ 1 ] < alpha_XYZ[ 0 ] )
370  && ( alpha_XYZ[ 1 ] <= alpha_XYZ[ 2 ] ) )
371  {
372  // Storing values
373  if( ( alpha_XYZ[ 1 ] >= alphaMin )
374  && ( index_ijk[ 0 ] - 1 >= 0 )
375  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
376  && ( index_ijk[ 1 ] - 1 >= 0 )
377  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
378  && ( index_ijk[ 2 ] - 1 >= 0 )
379  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
380  {
381  coeff = ( alpha_XYZ[ 1 ] - alpha_c ) * length_LOR;
382  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
383  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
384  }
385 
386  // Increment values
387  alpha_c = alpha_XYZ[ 1 ];
388  alpha_XYZ[ 1 ] += alpha_u[ 1 ];
389  index_ijk[ 1 ] += index_u[ 1 ];
390  }
391  else if( ( alpha_XYZ[ 2 ] < alpha_XYZ[ 0 ] )
392  && ( alpha_XYZ[ 2 ] < alpha_XYZ[ 1 ] ) )
393  {
394  // Storing values
395  if( ( alpha_XYZ[ 2 ] >= alphaMin )
396  && ( index_ijk[ 0 ] - 1 >= 0 )
397  && ( index_ijk[ 0 ] - 1 <= mp_nbVox[ 0 ] - 1 )
398  && ( index_ijk[ 1 ] - 1 >= 0 )
399  && ( index_ijk[ 1 ] - 1 <= mp_nbVox[ 1 ] - 1 )
400  && ( index_ijk[ 2 ] - 1 >= 0 )
401  && ( index_ijk[ 2 ] - 1 <= mp_nbVox[ 2 ] - 1 ) )
402  {
403  coeff = ( alpha_XYZ[ 2 ] - alpha_c ) * length_LOR;
404  numVox = ( index_ijk[ 0 ] - 1 ) + ( ( index_ijk[ 1 ] - 1 ) ) * w + ( ( index_ijk[ 2 ] - 1 ) ) * wh;
405  ap_ProjectionLine->AddVoxel(a_direction, numVox, coeff/((FLTNB)m_nbLines));
406  }
407 
408  // Increment values
409  alpha_c = alpha_XYZ[ 2 ];
410  alpha_XYZ[ 2 ] += alpha_u[ 2 ];
411  index_ijk[ 2 ] += index_u[ 2 ];
412  }
413  }
414  }
415 
416  return 0;
417 }
418 
419 // =====================================================================
420 // ---------------------------------------------------------------------
421 // ---------------------------------------------------------------------
422 // =====================================================================
423 
425 {
426  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithTOFPos() -> Not yet implemented !" << endl);
427  return 1;
428 }
429 
430 // =====================================================================
431 // ---------------------------------------------------------------------
432 // ---------------------------------------------------------------------
433 // =====================================================================
434 
436 {
437  Cerr("***** iProjectorIncrementalSiddonMulti::ProjectWithTOFBin() -> Not yet implemented !" << endl);
438  return 1;
439 }
440 
441 // =====================================================================
442 // ---------------------------------------------------------------------
443 // ---------------------------------------------------------------------
444 // =====================================================================
void ShowHelpSpecific()
A function used to show help about the child module.
bool m_compatibleWithSPECTAttenuationCorrection
Definition: vProjector.hh:317
FLTNB * GetOrientation1()
This function is used to get the pointer to the mp_orientation1 (3-values tab).
FLTNB mp_sizeVox[3]
Definition: vProjector.hh:301
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
INTNB mp_nbVox[3]
Definition: vProjector.hh:302
#define FLTNB
Definition: gVariables.hh:55
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
Definition: vProjector.hh:307
This class is designed to generically described any on-the-fly projector.
Definition: vProjector.hh:54
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:323
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:111
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:25
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:64
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:304
#define EXIT_DEBUG
Definition: gVariables.hh:69
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.
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:50
vScanner * mp_Scanner
Definition: vProjector.hh:309
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.