69 string key_word =
"number of lines";
72 Cerr(
"***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to get the '" << key_word <<
"' keyword !" << endl);
89 Cerr(
"***** iProjectorIncrementalSiddonMulti::ReadConfigurationFile() -> Failed to correctly read the list of options !" << endl);
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;
120 Cerr(
"***** iProjectorIncrementalSiddonMulti::CheckSpecificParameters() -> The provided number of lines is less than 1 !" << endl);
135 if (
m_verbose>=2)
Cout(
"iProjectorIncrementalSiddonMulti::Initialize() -> Use incremental Siddon projector with " <<
m_nbLines <<
" lines per event" << endl);
153 max_nb_voxels_in_dimension *= 4;
157 return max_nb_voxels_in_dimension;
170 Cerr(
"***** iProjectorIncrementalSiddonMulti::ProjectWithoutTOF() -> Called while not initialized !" << endl);
175 #ifdef CASTOR_VERBOSE
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);
193 Cerr(
"***** vProjector::Project() -> A problem occured while getting positions and orientations from scanner !" << endl);
200 HPFLTNB event1[3] = { event1Float[0], event1Float[1], event1Float[2] };
201 HPFLTNB event2[3] = { event2Float[0], event2Float[1], event2Float[2] };
218 HPFLTNB alphaFirst[] = { 0.0, 0.0, 0.0 };
219 HPFLTNB alphaLast[] = { 0.0, 0.0, 0.0 };
221 HPFLTNB alphaMin = 0.0f, alphaMax = 1.0f;
223 event2[ 0 ] - event1[ 0 ],
224 event2[ 1 ] - event1[ 1 ],
225 event2[ 2 ] - event1[ 2 ]
229 for(
int i = 0; i < 3; ++i )
231 if( delta_pos[ i ] != 0.0 )
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]));
242 if( alphaMax <= alphaMin )
return 0;
246 int iMin = 0, iMax = 0;
247 int jMin = 0, jMax = 0;
248 int kMin = 0, kMax = 0;
251 if( delta_pos[ 0 ] > 0.0f)
254 iMax = ::floor( 1 + ( event1[ 0 ] + alphaMax * delta_pos[ 0 ] - (-
mp_halfFOV[ 0 ]) ) /
mp_sizeVox[0] );
256 else if( delta_pos[ 0 ] < 0.0 )
259 iMax = ::floor( 1 + ( event1[ 0 ] + alphaMin * delta_pos[ 0 ] - (-
mp_halfFOV[ 0 ]) ) /
mp_sizeVox[0] );
261 if( delta_pos[ 0 ] == 0 )
267 if( delta_pos[ 1 ] > 0 )
270 jMax = ::floor( 1 + ( event1[ 1 ] + alphaMax * delta_pos[ 1 ] - (-
mp_halfFOV[ 1 ]) ) /
mp_sizeVox[1] );
272 else if( delta_pos[ 1 ] < 0 )
275 jMax = ::floor( 1 + ( event1[ 1 ] + alphaMin * delta_pos[ 1 ] - (-
mp_halfFOV[ 1 ]) ) /
mp_sizeVox[1] );
277 else if( delta_pos[ 1 ] == 0 )
283 if( delta_pos[ 2 ] > 0 )
286 kMax = ::floor( 1 + ( event1[ 2 ] + alphaMax * delta_pos[ 2 ] - (-
mp_halfFOV[ 2 ]) ) /
mp_sizeVox[2] );
288 else if( delta_pos[ 2 ] < 0 )
291 kMax = ::floor( 1 + ( event1[ 2 ] + alphaMin * delta_pos[ 2 ] - (-
mp_halfFOV[ 2 ]) ) /
mp_sizeVox[2] );
293 else if( delta_pos[ 2 ] == 0 )
299 INTNB n = ( iMax - iMin + 1 ) + ( jMax - jMin + 1 )
300 + ( kMax - kMin + 1 );
303 HPFLTNB alpha_XYZ[ 3 ] = { 1.0, 1.0, 1.0 };
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 ];
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 ];
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 ];
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
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 ];
343 HPFLTNB const min_alpha_XYZ = (std::min)( alpha_XYZ[ 0 ],
344 (std::min)( alpha_XYZ[ 1 ], alpha_XYZ[ 2 ] ) );
347 HPFLTNB const alphaMid = ( min_alpha_XYZ + alphaMin ) / 2.0f;
348 INTNB index_ijk[ 3 ] = {
361 for(
int nP = 0; nP < n - 1; ++nP )
363 if( ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 1 ] )
364 && ( alpha_XYZ[ 0 ] <= alpha_XYZ[ 2 ] ) )
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 ) )
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));
381 alpha_c = alpha_XYZ[ 0 ];
382 alpha_XYZ[ 0 ] += alpha_u[ 0 ];
383 index_ijk[ 0 ] += index_u[ 0 ];
385 else if( ( alpha_XYZ[ 1 ] < alpha_XYZ[ 0 ] )
386 && ( alpha_XYZ[ 1 ] <= alpha_XYZ[ 2 ] ) )
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 ) )
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));
403 alpha_c = alpha_XYZ[ 1 ];
404 alpha_XYZ[ 1 ] += alpha_u[ 1 ];
405 index_ijk[ 1 ] += index_u[ 1 ];
407 else if( ( alpha_XYZ[ 2 ] < alpha_XYZ[ 0 ] )
408 && ( alpha_XYZ[ 2 ] < alpha_XYZ[ 1 ] ) )
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 ) )
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));
425 alpha_c = alpha_XYZ[ 2 ];
426 alpha_XYZ[ 2 ] += alpha_u[ 2 ];
427 index_ijk[ 2 ] += index_u[ 2 ];
442 Cerr(
"***** iProjectorIncrementalSiddonMulti::ProjectWithTOFPos() -> Not yet implemented !" << endl);
453 Cerr(
"***** iProjectorIncrementalSiddonMulti::ProjectWithTOFBin() -> Not yet implemented !" << endl);
void ShowHelpSpecific()
A function used to show help about the child module.
bool m_compatibleWithSPECTAttenuationCorrection
FLTNB * GetOrientation1()
This function is used to get the pointer to the mp_orientation1 (3-values tab).
int ReadConfigurationFile(const string &a_configurationFile)
A function used to read options from a configuration file.
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
This class is designed to generically described any on-the-fly projector.
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).
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).
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...
int CheckSpecificParameters()
A private function used to check the parameters settings specific to the child projector.
Declaration of class iProjectorIncrementalSiddonMulti.
#define KEYWORD_MANDATORY
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.
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 * 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.
int ReadOptionsList(const string &a_optionsList)
A function used to read options from a list of options.
bool m_compatibleWithCompression
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.
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.