CASToR  3.2
Tomographic Reconstruction (PET/SPECT/CT)
code/src/projector/oProjectorManager.cc
Go to the documentation of this file.
1 
8 #include "oProjectorManager.hh"
9 #include "sOutputManager.hh"
10 #include "sAddonManager.hh"
11 #include "iDataFilePET.hh"
12 
13 // =====================================================================
14 // ---------------------------------------------------------------------
15 // ---------------------------------------------------------------------
16 // =====================================================================
17 
19 {
20  // Scanner and image dimensions
21  mp_Scanner = NULL;
23  // Data file (used to get some info about TOF bins and POI)
24  mp_DataFile = NULL;
25  // TOF and POI options
26  m_TOFMethod = -1;
27  m_applyPOI = false;
28  m_nbTOFBins = -1;
29  // Computation strategy for projection lines
31  // Forward and backward options for projectors
32  m_optionsForward = "";
33  m_optionsBackward = "";
34  // Common options
35  m_optionsCommon = "";
36  // Forward and backward projectors
41  mp_ProjectorForward = NULL;
42  mp_ProjectorBackward = NULL;
45  m_useProjectorForward = false;
46  m_useProjectorBackward = false;
47  m_useMatchedProjectors = false;
48  // Forward and backward projection lines (as many as threads)
49  m2p_ProjectionLines = NULL;
50  // Verbosity
51  m_verbose = 0;
52  // Not checked yet
53  m_checked = false;
54  // Not initialized yet
55  m_initialized = false;
56  m_applyMask = false;
57  mp_mask = NULL;
58  m_TOFBinSizeInMm = -1;
59  mp_TOFResolutionInMm = NULL;
60  mp_TOFProbabilities = NULL;
61  mp_TOFOffsetInMm = NULL;
64 }
65 
66 // =====================================================================
67 // ---------------------------------------------------------------------
68 // ---------------------------------------------------------------------
69 // =====================================================================
70 
72 {
73  // Go through the destructor only if the object was initialized
74  if (m_initialized)
75  {
76  // Delete projection lines
78  {
80  if (m2p_ProjectionLines[th]) delete m2p_ProjectionLines[th];
81  delete[] m2p_ProjectionLines;
82  }
83  // Delete projectors
86  if (m_applyMask) delete[] mp_mask;
88  {
91  }
92 
93  //if( mp_TOFResolutionInMm ) delete[] mp_TOFResolutionInMm;
94  //if( mp_TOFProbabilities ) delete[] mp_TOFProbabilities;
95  //if( mp_TOFOffsetInMm) delete[] mp_TOFOffsetInMm;
96  }
97 }
98 
99 // =====================================================================
100 // ---------------------------------------------------------------------
101 // ---------------------------------------------------------------------
102 // =====================================================================
103 
105 {
106  // Case for a vProjector
108  // Case for a system matrix
110 }
111 
112 // =====================================================================
113 // ---------------------------------------------------------------------
114 // ---------------------------------------------------------------------
115 // =====================================================================
116 
118 {
119  // Case for a vProjector
121  // Case for a system matrix
123 }
124 
125 // =====================================================================
126 // ---------------------------------------------------------------------
127 // ---------------------------------------------------------------------
128 // =====================================================================
129 
131 {
132  // Check scanner
133  if (mp_Scanner==NULL)
134  {
135  Cerr("***** oProjectorManager::CheckParameters() -> No scanner provided !" << endl);
136  return 1;
137  }
138  // Check image dimensions
140  {
141  Cerr("***** oProjectorManager::CheckParameters() -> No image dimensions provided !" << endl);
142  return 1;
143  }
144  // Check data file
145  if (mp_DataFile==NULL)
146  {
147  Cerr("***** oProjectorManager::CheckParameters() -> No data file provided !" << endl);
148  return 1;
149  }
150  // Check computation strategy
154  {
155  Cerr("***** oProjectorManager::CheckParameters() -> Unknown computation strategy provided !" << endl);
156  return 1;
157  }
158  // Check forward projector options
159  if (m_optionsForward=="")
160  {
161  Cerr("***** oProjectorManager::CheckParameters() -> No forward projector options provided !" << endl);
162  return 1;
163  }
164  // Check backward projector options
165  if (m_optionsBackward=="")
166  {
167  Cerr("***** oProjectorManager::CheckParameters() -> No backward projector options provided !" << endl);
168  return 1;
169  }
170  // Check verbosity
171  if (m_verbose<0)
172  {
173  Cerr("***** oProjectorManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
174  return 1;
175  }
176  // Normal end
177  m_checked = true;
178  return 0;
179 }
180 
181 // =====================================================================
182 // ---------------------------------------------------------------------
183 // ---------------------------------------------------------------------
184 // =====================================================================
185 
186 int oProjectorManager::CheckSPECTAttenuationCompatibility(const string& a_pathToAttenuationImage)
187 {
188  // In SPECT with attenuation correction, there are some requirements with the projection method
189  if (a_pathToAttenuationImage!="" && mp_DataFile->GetDataType()==TYPE_SPECT)
190  {
191  // Check that the projection line strategy is not IMAGE_COMPUTATION_STRATEGY (this is not compatible)
192  // Note that we cannot do this check in the oProjectionLine directly, because we cannot now in advance
193  // that the projection method including attenuation will be used...
195  {
196  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The image-computation strategy of the oProjectionLine is not compatible with SPECT attenuation correction !");
197  return 1;
198  }
199  // Check that the forward projector is compatible with SPECT with attenuation correction
201  {
202  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The forward projector is not compatible with SPECT attenuation correction !" << endl);
203  return 1;
204  }
205  // Check that the backward projector is compatible with SPECT with attenuation correction
207  {
208  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The backward projector is not compatible with SPECT attenuation correction !" << endl);
209  return 1;
210  }
211  }
212  // End
213  return 0;
214 }
215 
216 // =====================================================================
217 // ---------------------------------------------------------------------
218 // ---------------------------------------------------------------------
219 // =====================================================================
220 
222 {
223  // Forbid initialization without check
224  if (!m_checked)
225  {
226  Cerr("***** oProjectorManager::Initialize() -> Must call CheckParameters() before Initialize() !" << endl);
227  return 1;
228  }
229 
230  // Verbose
231  if (m_verbose>=1) Cout("oProjectorManager::Initialize() -> Initialize projectors and projection lines" << endl);
232 
233  // -------------------------------------------------------------------
234  // Manage TOF
235  // -------------------------------------------------------------------
236 
237  // TOF is only for PET data
239  {
240  // Cast the datafile pointer
241  iDataFilePET* p_pet_datafile = (dynamic_cast<iDataFilePET*>(mp_DataFile));
242  // Case of TOF information in the datafile
243  if (p_pet_datafile->GetTOFInfoFlag())
244  {
245  // Case where it is asked to ignore TOF info
246  if (p_pet_datafile->GetIgnoreTOFFlag())
247  {
249  m_nbTOFBins = 1;
250  }
251  // Otherwise, we use TOF
252  // TODO TM implement TOF bin size for multi-kernel TOF
253  else
254  {
255  mp_TOFResolutionInMm = new FLTNB[ p_pet_datafile->GetNbTOFResolutions() ];
256  mp_TOFProbabilities = new FLTNB[ p_pet_datafile->GetNbTOFResolutions() ];
257  mp_TOFOffsetInMm = new FLTNB[ p_pet_datafile->GetNbTOFResolutions() ];
259 
260  // Get the TOF resolution (FWHM in ps) from the data file, and convert it to mm
261  for(int r=0 ; r<p_pet_datafile->GetNbTOFResolutions() ; r++)
262  {
263  mp_TOFResolutionInMm[ r ] = p_pet_datafile->GetTOFResolutionInPs( r ) * SPEED_OF_LIGHT_IN_MM_PER_PS * 0.5;
264  mp_TOFProbabilities[ r ] = p_pet_datafile->GetTOFProbabilities( r );
265  mp_TOFOffsetInMm[ r ] = p_pet_datafile->GetTOFOffsetPs( r ) * SPEED_OF_LIGHT_IN_MM_PER_PS * 0.5;
266  }
267  // For list-mode data
269  {
270  m_nbTOFBins = 1;
272 
273  // Get the TOF quantization bin size in ps and convert it to mm
276  }
277  // For histogram data
278  else
279  {
281  // Get the number of TOF bins from the data file
282  m_nbTOFBins = p_pet_datafile->GetNbTOFBins();
283  // Get the TOF bin size in ps
286  }
287  }
288  // Verbose
290  {
291  if (m_TOFMethod==USE_NOTOF) Cout(" --> Do not use the TOF projections" << endl);
292  else if (m_TOFMethod==USE_TOFHISTO) Cout(" --> Use TOF projector for histogram data" << endl);
293  else if (m_TOFMethod==USE_TOFLIST) Cout(" --> Use TOF projector for listmode data" << endl);
294  }
295  }
296  // Case no TOF
297  else
298  {
300  m_nbTOFBins = 1;
301  }
302  }
303  // Not PET data
304  else
305  {
306  m_nbTOFBins = 1;
308  }
309 
310  // -------------------------------------------------------------------
311  // Manage POI
312  // -------------------------------------------------------------------
313 
314  // Case we have POI and it is not asked to ignore the information
316  {
317  // Cannot use POI with histogram mode
319  {
320  Cerr("***** oProjectorManager::Initialize() -> POI information has no sense with histogram data !" << endl);
321  return 1;
322  }
323  // Apply POI
324  m_applyPOI = true;
325  }
326  // Case we do not use POI
327  else m_applyPOI = false;
328  // Get POI resolution from the data file
329  FLTNB* poi_resolution = mp_DataFile->GetPOIResolution();
330 
331  // -------------------------------------------------------------------
332  // Initialize projectors and or system matrix
333  // -------------------------------------------------------------------
334 
335  // Compare projector options to know if we use matched ones for forward and backward operations
337  else m_useMatchedProjectors = false;
338 
339  // Parse projector options and initialize them
341  {
342  Cerr("***** oProjectorManager::Initialize() -> A problem occurred while parsing projector options and initializing it !" << endl);
343  return 1;
344  }
345 
346  // -------------------------------------------------------------------
347  // If compression, loaded SM and some projectors are not compatible
348  // -------------------------------------------------------------------
349 
350  // Compression can currently occur only in PET
352  {
353  // Check if there is some compression
354  if ( (dynamic_cast<iDataFilePET*>(mp_DataFile))->GetMaxNumberOfLinesPerEvent() > 1 )
355  {
356  // It is not compatible with loaded forward system matrices
358  {
359  Cerr("***** oProjectorManager::Initialize() -> Cannot use a loaded forward system matrix with compression in the datafile !" << endl);
360  return 1;
361  }
362  // It is not compatible with forward projectors declared as not compatible !
364  {
365  Cerr("***** oProjectorManager::Initialize() -> Selected forward projector '" << m_forwardProjectorName << "' is not compatible with compression in the datafile !" << endl);
366  return 1;
367  }
368  // It is not compatible with loaded backward system matrices
370  {
371  Cerr("***** oProjectorManager::Initialize() -> Cannot use a loaded backward system matrix with compression in the datafile !" << endl);
372  return 1;
373  }
374  // It is not compatible with backward projectors declared as not compatible !
376  {
377  Cerr("***** oProjectorManager::Initialize() -> Selected backward projector '" << m_backwardProjectorName << "' is not compatible with compression in the datafile !" << endl);
378  return 1;
379  }
380  }
381  }
382 
383  // -------------------------------------------------------------------
384  // Transfer the mask to projectors
385  // -------------------------------------------------------------------
386 
387  if (m_applyMask)
388  {
391  }
392 
393 
394  // -------------------------------------------------------------------
395  // Initialize projection lines
396  // -------------------------------------------------------------------
397 
398  // Initialize as many projection lines as threads
401  {
406  m2p_ProjectionLines[th]->SetPOIResolution(poi_resolution);
413  {
414  Cerr("***** oProjectorManager::Initialize() -> An error occurred while checking parameters of an oProjectionLine !" << endl);
415  return 1;
416  }
417  if (m2p_ProjectionLines[th]->Initialize())
418  {
419  Cerr("***** oProjectorManager::Initialize() -> An error occurred while initializing an oProjectionLine !" << endl);
420  return 1;
421  }
422  }
423 
424  // Normal end
425  m_initialized = true;
426  return 0;
427 }
428 
429 // =====================================================================
430 // ---------------------------------------------------------------------
431 // ---------------------------------------------------------------------
432 // =====================================================================
433 
435 {
436  string list_options = "";
437  string file_options = "";
438 
439  // This is for the automatic initialization of the projectors
440  typedef vProjector *(*maker_projector) ();
441 
442  // ---------------------------------------------------------------------------------------------------
443  // Manage forward projector
444  // ---------------------------------------------------------------------------------------------------
445 
446  // ______________________________________________________________________________
447  // Get the projector name in the options and isolate the real projector's options
448 
449  // Search for a colon ":", this indicates that a configuration file is provided after the projector name
450  size_t colon = m_optionsForward.find_first_of(":");
451  size_t comma = m_optionsForward.find_first_of(",");
452 
453  // Case 1: we have a colon
454  if (colon!=string::npos)
455  {
456  // Get the projector name before the colon
457  m_forwardProjectorName = m_optionsForward.substr(0,colon);
458  // Get the configuration file after the colon
459  file_options = m_optionsForward.substr(colon+1);
460  // List of options is empty
461  list_options = "";
462  }
463  // Case 2: we have a comma
464  else if (comma!=string::npos)
465  {
466  // Get the projector name before the first comma
467  m_forwardProjectorName = m_optionsForward.substr(0,comma);
468  // Get the list of options after the first comma
469  list_options = m_optionsForward.substr(comma+1);
470  // Configuration file is empty
471  file_options = "";
472  }
473  // Case 3: no colon and no comma (a single projector name)
474  else
475  {
476  // Get the projector name
478  // List of options is empty
479  list_options = "";
480  // Build the default configuration file
481  file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/projector/" + m_forwardProjectorName + ".conf";
482  }
483 
484  // ______________________________________________________________________________
485  // Case 1: projector is equal to keyword 'matrix', then use a system matrix
487  {
488  mp_ProjectorForward = NULL;
489  m_useProjectorForward = false;
491  // TODO: put all these limitations into a dedicated function from oSystemMatrix
492  // TODO: forbid TOF in PET with system matrix
493  // TODO: forbid simultaneous bed reconstruction with system matrix
494  // TODO: forbid image offset with system matrix
495  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Loading of custom system matrices is not yet implemented !" << endl);
496  return 1;
497  }
498  // ______________________________________________________________________________
499  // Case 2: on-the-fly projector
500  else
501  {
502  // Unset system matrix
503  mp_SystemMatrixForward = NULL;
504  m_useSystemMatrixForward = false;
505  // Set projector on
506  m_useProjectorForward = true;
507  // Get projector's listfrom addon manager
508  std::map <string,maker_projector> list = sAddonManager::GetInstance()->mp_listOfProjectors;
509  // Create the projector
511  else
512  {
513  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Projector '" << m_forwardProjectorName << "' does not exist !" << endl);
514  return 1;
515  }
516  // Set parameters
519  {
520  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while setting the image dimensions of the forward projector !" << endl);
521  return 1;
522  }
524  // TODO TM allocate TOF variables of vProjector instead of copying ProjectorManager variables
525  int nb_tof_res = 1;
527  nb_tof_res = (dynamic_cast<iDataFilePET*>(mp_DataFile))->GetNbTOFResolutions();
537 
538  // Provide common options list
540  {
541  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's common options !" << endl);
542  return 1;
543  }
544  // Provide configuration file if any
545  if (file_options!="" && mp_ProjectorForward->ReadConfigurationFile(file_options))
546  {
547  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's configuration file !" << endl);
548  return 1;
549  }
550  // Provide options if any
551  if (list_options!="" && mp_ProjectorForward->ReadOptionsList(list_options))
552  {
553  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's options !" << endl);
554  return 1;
555  }
556  // Check parameters
558  {
559  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while checking forward projector parameters !" << endl);
560  return 1;
561  }
562  // Initialize the projector
564  {
565  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while initializing the forward projector !" << endl);
566  return 1;
567  }
568  }
569 
570  // ---------------------------------------------------------------------------------------------------
571  // Manage backward projector
572  // ---------------------------------------------------------------------------------------------------
573 
574  // If options are the same, then forward and backward are the same
576  {
577  // In this case, matched projectors
582  }
583  // Else, unmatched projectors
584  else
585  {
586  // ______________________________________________________________________________
587  // Get the projector name in the options and isolate the real projector's options
588 
589  // Search for a colon ":", this indicates that a configuration file is provided after the projector name
590  colon = m_optionsBackward.find_first_of(":");
591  comma = m_optionsBackward.find_first_of(",");
592 
593  // Case 1: we have a colon
594  if (colon!=string::npos)
595  {
596  // Get the projector name before the colon
597  m_backwardProjectorName = m_optionsBackward.substr(0,colon);
598  // Get the configuration file after the colon
599  file_options = m_optionsBackward.substr(colon+1);
600  // List of options is empty
601  list_options = "";
602  }
603  // Case 2: we have a comma
604  else if (comma!=string::npos)
605  {
606  // Get the projector name before the first comma
607  m_backwardProjectorName = m_optionsBackward.substr(0,comma);
608  // Get the list of options after the first comma
609  list_options = m_optionsBackward.substr(comma+1);
610  // Configuration file is empty
611  file_options = "";
612  }
613  // Case 3: no colon and no comma (a single projector name)
614  else
615  {
616  // Get the projector name
618  // List of options is empty
619  list_options = "";
620  // Build the default configuration file
621  file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/projector/" + m_backwardProjectorName + ".conf";
622  }
623 
624  // ______________________________________________________________________________
625  // Case 1: projector is equal to keyword 'matrix', then use a system matrix
627  {
628  mp_ProjectorBackward = NULL;
629  m_useProjectorBackward = false;
631  // TODO: put all these limitations into a dedicated function from oSystemMatrix
632  // TODO: forbid TOF in PET with system matrix
633  // TODO: forbid simultaneous bed reconstruction with system matrix
634  // TODO: forbid image offset with system matrix
635  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Loading of custom system matrices is not yet implemented !" << endl);
636  return 1;
637  }
638  // ______________________________________________________________________________
639  // Case 2: on-the-fly projector
640  else
641  {
642  // Unset system matrix
645  // Set projector on
646  m_useProjectorBackward = true;
647  // Get projector's listfrom addon manager
648  std::map <string,maker_projector> list = sAddonManager::GetInstance()->mp_listOfProjectors;
649  // Create the projector
651  else
652  {
653  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Projector '" << m_backwardProjectorName << "' does not exist !" << endl);
654  return 1;
655  }
656  // Set parameters
659  {
660  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while setting the image dimensions of the backward projector !" << endl);
661  return 1;
662  }
664  int nb_tof_res = 1;
666  nb_tof_res = (dynamic_cast<iDataFilePET*>(mp_DataFile))->GetNbTOFResolutions();
676  // Provide common options list
678  {
679  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's common options !" << endl);
680  return 1;
681  }
682  // Provide configuration file if any
683  if (file_options!="" && mp_ProjectorBackward->ReadConfigurationFile(file_options))
684  {
685  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's configuration file !" << endl);
686  return 1;
687  }
688  // Provide options if any
689  if (list_options!="" && mp_ProjectorBackward->ReadOptionsList(list_options))
690  {
691  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's options !" << endl);
692  return 1;
693  }
694  // Check parameters
696  {
697  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while checking backward projector parameters !" << endl);
698  return 1;
699  }
700  // Initialize the projector
702  {
703  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while initializing backward projector !" << endl);
704  return 1;
705  }
706  }
707  }
708 
709  // Normal end
710  return 0;
711 }
712 
713 // =====================================================================
714 // ---------------------------------------------------------------------
715 // ---------------------------------------------------------------------
716 // =====================================================================
717 
719 {
720  // Set the sensitivity ON in the projectors, if used
723  // If the data file is a list-mode, then deactivate the TOF usage in the projector
725  {
728  }
729 }
730 
731 // =====================================================================
732 // ---------------------------------------------------------------------
733 // ---------------------------------------------------------------------
734 // =====================================================================
735 
737 {
738  // Set the sensitivity OFF in the projectors, if used
741  // Reset TOF and POI parameters to original values
743  {
746  }
748  {
751  }
752 }
753 
754 // =====================================================================
755 // ---------------------------------------------------------------------
756 // ---------------------------------------------------------------------
757 // =====================================================================
758 
760 {
761  // Apply it to all projection lines (only if more than one bed position)
765 }
766 
767 // =====================================================================
768 // ---------------------------------------------------------------------
769 // ---------------------------------------------------------------------
770 // =====================================================================
771 
773 {
774  #ifdef CASTOR_DEBUG
775  if (!m_initialized)
776  {
777  Cerr("***** oProjectorManager::ComputeProjectionLine() -> Called while not initialized !" << endl);
778  return NULL;
779  }
780  #endif
781 
783 
784  // Get the list of indices
785  uint32_t *index1 = ap_Event->GetEventID1();
786  uint32_t *index2 = ap_Event->GetEventID2();
787  int nb_indices = ap_Event->GetNbLines();
788 
789  // Clean the projection line
790  m2p_ProjectionLines[a_th]->Reset();
791 
792  // With list-mode data, we may need POI and/or TOF measurements
793  if (ap_Event->GetDataMode()==MODE_LIST)
794  {
795  // Set POI measurement
796  if (m_applyPOI)
797  {
798  // For PET
799  if (ap_Event->GetDataType()==TYPE_PET)
800  {
801  // Have to dynamic_cast the event into a iEventPETList to access the GetPOI functions
802  m2p_ProjectionLines[a_th]->SetPOI1((dynamic_cast<iEventListPET*>(ap_Event))->GetPOI1());
803  m2p_ProjectionLines[a_th]->SetPOI2((dynamic_cast<iEventListPET*>(ap_Event))->GetPOI2());
804  }
805  // For SPECT
806  else if (ap_Event->GetDataType()==TYPE_SPECT)
807  {
808  // By convention in SPECT, the second end point is in the camera (the first one being outside)
809  //m2p_ProjectionLines[a_th]->SetPOI2((dynamic_cast<iEventListModeSPECT*>(ap_Event))->GetPOI());
810  }
811  // For CT
812  else if (ap_Event->GetDataType()==TYPE_CT)
813  {
814  ;
815  }
816  }
817  // Set TOF measurement (only for PET obviously)
818  if (m_TOFMethod!=USE_NOTOF && ap_Event->GetDataType()==TYPE_PET)
819  {
820  // Have to dynamic_cast the event into a iEventPETList to access the GetTOF function
821  m2p_ProjectionLines[a_th]->SetTOFMeasurementInPs((dynamic_cast<iEventListPET*>(ap_Event))->GetTOFMeasurementInPs());
822 
823  // Per-event TOF resolution
825  {
826  mp_TOFResolutionInMm[ 0 ] = dynamic_cast<iEventListPET*>(ap_Event)->GetEventTOFResolutionInPs() * SPEED_OF_LIGHT_IN_MM_PER_PS * 0.5;
832  }
833  }
834  }
835 
836  // Project forward (and also compute line length)
837  int return_value = 0;
839  return_value = mp_ProjectorForward->Project( FORWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
840  else if (m_useSystemMatrixForward)
841  return_value = mp_SystemMatrixForward->Project( FORWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
842  if (return_value)
843  {
844  Cerr("***** oProjectorManager::ComputeProjectionLine() -> A problem occurred while forward projecting an event !" << endl);
845  return NULL;
846  }
847 
848  // Project backward
850  {
851  // Then project
853  return_value = mp_ProjectorBackward->Project( BACKWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
854  else if (m_useSystemMatrixBackward)
855  return_value = mp_SystemMatrixBackward->Project( BACKWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices);
856  if (return_value)
857  {
858  Cerr("***** oProjectorManager::ComputeProjectionLine() -> A problem occurred while backward projecting an event !" << endl);
859  return NULL;
860  }
861  }
862 
863  // Return the line
864  return m2p_ProjectionLines[a_th];
865 }
866 
867 // =====================================================================
868 // ---------------------------------------------------------------------
869 // ---------------------------------------------------------------------
870 // =====================================================================
872 {
873  // Check that the mask has not already been set
874  if (mp_mask!=NULL)
875  {
876  Cerr("***** oProjectorManager::ProcessAndSetMask() -> Mask already initialized !" << endl);
877  return 1;
878  }
879  // Allocate
881  // Fill the mask
883  {
884  // Currently, values not greater than 0 are regarded as background
885  // As the mask has a real number type, to avoid issues with zeros potentially written
886  // as extremely tiny floating point values, the values are first rounded to an integer type
887  // and then checked for greater than zero, improve this in the future (implicit behaviour)
888  mp_mask[v] = ((INTNB)std::round(ap_maskImage[v]))>0;
889  }
890  // Mask on
891  m_applyMask = true;
892  // End
893  return 0;
894 }
#define MODE_HISTOGRAM
#define Cerr(MESSAGE)
virtual int ReadOptionsList(const string &a_optionsList)=0
int Initialize()
A function used to initialize the manager and the projectors or system matrices it manages...
uint32_t * GetEventID2()
This class is designed to generically described any on-the-fly projector.
virtual int ReadConfigurationFile(const string &a_configurationFile)=0
#define SPEED_OF_LIGHT_IN_MM_PER_PS
int Initialize()
A public function used to initialize the projector.
int Project(int a_direction, oProjectionLine *ap_ProjectionLine, uint32_t *ap_index1, uint32_t *ap_index2, int a_nbIndices)
void SetVerbose(int a_verbose)
oProjectorManager()
The constructor of oProjectorManager.
void SetSensitivityModeOff()
Say that the projector will no longer be used to compute the global sensitivity.
#define ADAPTATIVE_LIST_COMPUTATION_STRATEGY
void SetScanner(vScanner *ap_Scanner)
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
void SetMatchedProjectors(bool a_UseMatchedProjectors)
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
void SetTOFResolutionInMm(FLTNB *ap_TOFResolutionInMm)
static sAddonManager * GetInstance()
int ReadCommonOptionsList(const string &a_optionsList)
#define FIXED_LIST_COMPUTATION_STRATEGY
void SetApplyTOF(int a_applyTOF)
Inherit from iEventPET. Class for PET list-mode events.
~oProjectorManager()
The destructor of oProjectorManager.
void SetPOIResolution(FLTNB *ap_POIResolution)
void SetNbTOFResolutions(int a_nbTOFResolutions)
int ParseOptionsAndInitializeProjectors()
Parse forward and backward projection options contained in the previously provided strings...
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
const string & GetPathToConfigDir()
Return the path to the CASTOR config directory.
void SetTOFOffsetInMm(FLTNB *ap_TOFOffsetsInMm)
This function is used to set the TOF Offset in use.
void SetTOFBinSizeInMm(FLTNB a_TOFBinSizeInMm)
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
int CheckParameters()
A public function used to check the parameters settings.
void SetTOFEventResolutionFlag(FLTNB a_TOFEventResolutionFlag)
This function sets the per-event TOF resolution flag.
oProjectionLine * ComputeProjectionLine(vEvent *ap_Event, int a_th)
void SetTOFMeasurementRangeInMm(FLTNB a_TOFMeasurementRangeInMm)
void Reset()
Reset length and all the voxel indices and weights tabs.
void SetThreadNumber(int a_threadNumber)
void SetTOFMeasurementInPs(FLTNB a_TOFMeasurementInPs)
std::map< string, maker_projector > mp_listOfProjectors
int CheckParameters()
A function used to check the parameters settings.
void SetSensitivityModeOn()
Say that the projector will be used to compute the global sensitivity.
int ProcessAndSetMask(FLTNB *ap_maskImage)
This class is designed to manage and store system matrix elements associated to a vEvent...
Mother class for the Event objects.
void SetForwardProjector(vProjector *ap_Projector)
FLTNB GetTOFResolutionInPs(int a_reso)
void SetApplyPOI(bool a_applyPOI)
void SetBackwardProjector(vProjector *ap_Projector)
int GetNbThreadsForProjection()
Get the number of threads used for projections.
void SetTOFProbabilities(FLTNB *ap_TOFProbabilities)
This function is used to set the TOF probabilities in use.
uint32_t * GetEventID1()
int Project(int a_direction, oProjectionLine *ap_ProjectionLine, uint32_t *ap_index1, uint32_t *ap_index2, int a_nbIndices)
int CheckSPECTAttenuationCompatibility(const string &a_pathToAttenuationImage)
void SetComputationStrategy(int a_computationStrategy)
int SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Inherit from vDataFile. Class that manages the reading of a PET input file (header + data)...
void SetSensitivityMode(bool a_sensitivityMode)
#define Cout(MESSAGE)