CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
oProjectorManager.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-2019 all CASToR contributors listed below:
18 
19  --> Didier BENOIT, Claude COMTAT, Marina FILIPOVIC, Thibaut MERLIN, Mael MILLARDET, Simon STUTE, Valentin VIELZEUF
20 
21 This is CASToR version 3.0.
22 */
23 
30 #include "oProjectorManager.hh"
31 #include "sOutputManager.hh"
32 #include "sAddonManager.hh"
33 #include "iDataFilePET.hh"
34 
35 // =====================================================================
36 // ---------------------------------------------------------------------
37 // ---------------------------------------------------------------------
38 // =====================================================================
39 
41 {
42  // Scanner and image dimensions
43  mp_Scanner = NULL;
45  // Data file (used to get some info about TOF bins and POI)
46  mp_DataFile = NULL;
47  // TOF and POI options
48  m_TOFMethod = -1;
49  m_applyPOI = false;
50  m_nbTOFBins = -1;
51  // Computation strategy for projection lines
53  // Forward and backward options for projectors
54  m_optionsForward = "";
55  m_optionsBackward = "";
56  // Common options
57  m_optionsCommon = "";
58  // Forward and backward projectors
63  mp_ProjectorForward = NULL;
64  mp_ProjectorBackward = NULL;
67  m_useProjectorForward = false;
68  m_useProjectorBackward = false;
69  m_useMatchedProjectors = false;
70  // Forward and backward projection lines (as many as threads)
71  m2p_ProjectionLines = NULL;
72  // Verbosity
73  m_verbose = 0;
74  // Not checked yet
75  m_checked = false;
76  // Not initialized yet
77  m_initialized = false;
78  m_applyMask = false;
79  mp_mask = NULL;
80  m_TOFBinSizeInMm = -1.;
81  m_TOFResolutionInMm = -1.;
83 }
84 
85 // =====================================================================
86 // ---------------------------------------------------------------------
87 // ---------------------------------------------------------------------
88 // =====================================================================
89 
91 {
92  // Go through the destructor only if the object was initialized
93  if (m_initialized)
94  {
95  // Delete projection lines
97  {
99  if (m2p_ProjectionLines[th]) delete m2p_ProjectionLines[th];
100  delete[] m2p_ProjectionLines;
101  }
102  // Delete projectors
105  if (m_applyMask) delete[] mp_mask;
107  {
110  }
111 
112  }
113 }
114 
115 // =====================================================================
116 // ---------------------------------------------------------------------
117 // ---------------------------------------------------------------------
118 // =====================================================================
119 
121 {
122  // Case for a vProjector
124  // Case for a system matrix
126 }
127 
128 // =====================================================================
129 // ---------------------------------------------------------------------
130 // ---------------------------------------------------------------------
131 // =====================================================================
132 
134 {
135  // Case for a vProjector
137  // Case for a system matrix
139 }
140 
141 // =====================================================================
142 // ---------------------------------------------------------------------
143 // ---------------------------------------------------------------------
144 // =====================================================================
145 
147 {
148  // Check scanner
149  if (mp_Scanner==NULL)
150  {
151  Cerr("***** oProjectorManager::CheckParameters() -> No scanner provided !" << endl);
152  return 1;
153  }
154  // Check image dimensions
156  {
157  Cerr("***** oProjectorManager::CheckParameters() -> No image dimensions provided !" << endl);
158  return 1;
159  }
160  // Check data file
161  if (mp_DataFile==NULL)
162  {
163  Cerr("***** oProjectorManager::CheckParameters() -> No data file provided !" << endl);
164  return 1;
165  }
166  // Check computation strategy
170  {
171  Cerr("***** oProjectorManager::CheckParameters() -> Unknown computation strategy provided !" << endl);
172  return 1;
173  }
174  // Check forward projector options
175  if (m_optionsForward=="")
176  {
177  Cerr("***** oProjectorManager::CheckParameters() -> No forward projector options provided !" << endl);
178  return 1;
179  }
180  // Check backward projector options
181  if (m_optionsBackward=="")
182  {
183  Cerr("***** oProjectorManager::CheckParameters() -> No backward projector options provided !" << endl);
184  return 1;
185  }
186  // Check verbosity
187  if (m_verbose<0)
188  {
189  Cerr("***** oProjectorManager::CheckParameters() -> Wrong verbosity level provided !" << endl);
190  return 1;
191  }
192  // Normal end
193  m_checked = true;
194  return 0;
195 }
196 
197 // =====================================================================
198 // ---------------------------------------------------------------------
199 // ---------------------------------------------------------------------
200 // =====================================================================
201 
202 int oProjectorManager::CheckSPECTAttenuationCompatibility(const string& a_pathToAttenuationImage)
203 {
204  // In SPECT with attenuation correction, there are some requirements with the projection method
205  if (a_pathToAttenuationImage!="" && mp_DataFile->GetDataType()==TYPE_SPECT)
206  {
207  // Check that the projection line strategy is not IMAGE_COMPUTATION_STRATEGY (this is not compatible)
208  // Note that we cannot do this check in the oProjectionLine directly, because we cannot now in advance
209  // that the projection method including attenuation will be used...
211  {
212  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The image-computation strategy of the oProjectionLine is not compatible with SPECT attenuation correction !");
213  return 1;
214  }
215  // Check that the forward projector is compatible with SPECT with attenuation correction
217  {
218  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The forward projector is not compatible with SPECT attenuation correction !" << endl);
219  return 1;
220  }
221  // Check that the backward projector is compatible with SPECT with attenuation correction
223  {
224  Cerr("***** oProjectorManager::CheckSPECTAttenuationCompatibility() -> The backward projector is not compatible with SPECT attenuation correction !" << endl);
225  return 1;
226  }
227  }
228  // End
229  return 0;
230 }
231 
232 // =====================================================================
233 // ---------------------------------------------------------------------
234 // ---------------------------------------------------------------------
235 // =====================================================================
236 
238 {
239  // Forbid initialization without check
240  if (!m_checked)
241  {
242  Cerr("***** oProjectorManager::Initialize() -> Must call CheckParameters() before Initialize() !" << endl);
243  return 1;
244  }
245 
246  // Verbose
247  if (m_verbose>=1) Cout("oProjectorManager::Initialize() -> Initialize projectors and projection lines" << endl);
248 
249  // -------------------------------------------------------------------
250  // Manage TOF
251  // -------------------------------------------------------------------
252 
253  // TOF is only for PET data
255  {
256  // Cast the datafile pointer
257  iDataFilePET* p_pet_datafile = (dynamic_cast<iDataFilePET*>(mp_DataFile));
258  // Case of TOF information in the datafile
259  if (p_pet_datafile->GetTOFInfoFlag())
260  {
261  // Case where it is asked to ignore TOF info
262  if (p_pet_datafile->GetIgnoreTOFFlag())
263  {
265  m_nbTOFBins = 1;
266  }
267  // Otherwise, we use TOF
268  else
269  {
270  // Get the TOF resolution (FWHM in ps) from the data file, and convert it to mm
272 
273  // For list-mode data
275  {
276  m_nbTOFBins = 1;
278  // Get the TOF quantization bin size in ps and convert it to mm
281  }
282  // For histogram data
283  else
284  {
286  // Get the number of TOF bins from the data file
287  m_nbTOFBins = p_pet_datafile->GetNbTOFBins();
288  // Get the TOF bin size in ps
291  }
292  }
293  // Verbose
295  {
296  if (m_TOFMethod==USE_NOTOF) Cout(" --> Do not use the TOF projections" << endl);
297  else if (m_TOFMethod==USE_TOFHISTO) Cout(" --> Use TOF projector for histogram data" << endl);
298  else if (m_TOFMethod==USE_TOFLIST) Cout(" --> Use TOF projector for listmode data" << endl);
299  }
300  }
301  // Case no TOF
302  else
303  {
305  m_nbTOFBins = 1;
306  }
307  }
308  // Not PET data
309  else
310  {
311  m_nbTOFBins = 1;
313  }
314 
315  // -------------------------------------------------------------------
316  // Manage POI
317  // -------------------------------------------------------------------
318 
319  // Case we have POI and it is not asked to ignore the information
321  {
322  // Cannot use POI with histogram mode
324  {
325  Cerr("***** oProjectorManager::Initialize() -> POI information has no sense with histogram data !" << endl);
326  return 1;
327  }
328  // Apply POI
329  m_applyPOI = true;
330  }
331  // Case we do not use POI
332  else m_applyPOI = false;
333  // Get POI resolution from the data file
334  FLTNB* poi_resolution = mp_DataFile->GetPOIResolution();
335 
336  // -------------------------------------------------------------------
337  // Initialize projectors and or system matrix
338  // -------------------------------------------------------------------
339 
340  // Compare projector options to know if we use matched ones for forward and backward operations
342  else m_useMatchedProjectors = false;
343 
344  // Parse projector options and initialize them
346  {
347  Cerr("***** oProjectorManager::Initialize() -> A problem occurred while parsing projector options and initializing it !" << endl);
348  return 1;
349  }
350 
351  // -------------------------------------------------------------------
352  // If compression, loaded SM and some projectors are not compatible
353  // -------------------------------------------------------------------
354 
355  // Compression can currently occur only in PET
357  {
358  // Check if there is some compression
359  if ( (dynamic_cast<iDataFilePET*>(mp_DataFile))->GetMaxNumberOfLinesPerEvent() > 1 )
360  {
361  // It is not compatible with loaded forward system matrices
363  {
364  Cerr("***** oProjectorManager::Initialize() -> Cannot use a loaded forward system matrix with compression in the datafile !" << endl);
365  return 1;
366  }
367  // It is not compatible with forward projectors declared as not compatible !
369  {
370  Cerr("***** oProjectorManager::Initialize() -> Selected forward projector '" << m_forwardProjectorName << "' is not compatible with compression in the datafile !" << endl);
371  return 1;
372  }
373  // It is not compatible with loaded backward system matrices
375  {
376  Cerr("***** oProjectorManager::Initialize() -> Cannot use a loaded backward system matrix with compression in the datafile !" << endl);
377  return 1;
378  }
379  // It is not compatible with backward projectors declared as not compatible !
381  {
382  Cerr("***** oProjectorManager::Initialize() -> Selected backward projector '" << m_backwardProjectorName << "' is not compatible with compression in the datafile !" << endl);
383  return 1;
384  }
385  }
386  }
387 
388  // -------------------------------------------------------------------
389  // Transfer the mask to projectors
390  // -------------------------------------------------------------------
391 
392  if (m_applyMask)
393  {
396  }
397 
398 
399  // -------------------------------------------------------------------
400  // Initialize projection lines
401  // -------------------------------------------------------------------
402 
403  // Initialize as many projection lines as threads
406  {
411  m2p_ProjectionLines[th]->SetPOIResolution(poi_resolution);
418  {
419  Cerr("***** oProjectorManager::Initialize() -> An error occurred while checking parameters of an oProjectionLine !" << endl);
420  return 1;
421  }
422  if (m2p_ProjectionLines[th]->Initialize())
423  {
424  Cerr("***** oProjectorManager::Initialize() -> An error occurred while initializing an oProjectionLine !" << endl);
425  return 1;
426  }
427  }
428 
429  // Normal end
430  m_initialized = true;
431  return 0;
432 }
433 
434 // =====================================================================
435 // ---------------------------------------------------------------------
436 // ---------------------------------------------------------------------
437 // =====================================================================
438 
440 {
441  string list_options = "";
442  string file_options = "";
443 
444  // This is for the automatic initialization of the projectors
445  typedef vProjector *(*maker_projector) ();
446 
447  // ---------------------------------------------------------------------------------------------------
448  // Manage forward projector
449  // ---------------------------------------------------------------------------------------------------
450 
451  // ______________________________________________________________________________
452  // Get the projector name in the options and isolate the real projector's options
453 
454  // Search for a colon ":", this indicates that a configuration file is provided after the projector name
455  size_t colon = m_optionsForward.find_first_of(":");
456  size_t comma = m_optionsForward.find_first_of(",");
457 
458  // Case 1: we have a colon
459  if (colon!=string::npos)
460  {
461  // Get the projector name before the colon
462  m_forwardProjectorName = m_optionsForward.substr(0,colon);
463  // Get the configuration file after the colon
464  file_options = m_optionsForward.substr(colon+1);
465  // List of options is empty
466  list_options = "";
467  }
468  // Case 2: we have a comma
469  else if (comma!=string::npos)
470  {
471  // Get the projector name before the first comma
472  m_forwardProjectorName = m_optionsForward.substr(0,comma);
473  // Get the list of options after the first comma
474  list_options = m_optionsForward.substr(comma+1);
475  // Configuration file is empty
476  file_options = "";
477  }
478  // Case 3: no colon and no comma (a single projector name)
479  else
480  {
481  // Get the projector name
483  // List of options is empty
484  list_options = "";
485  // Build the default configuration file
486  file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/projector/" + m_forwardProjectorName + ".conf";
487  }
488 
489  // ______________________________________________________________________________
490  // Case 1: projector is equal to keyword 'matrix', then use a system matrix
492  {
493  mp_ProjectorForward = NULL;
494  m_useProjectorForward = false;
496  // TODO: put all these limitations into a dedicated function from oSystemMatrix
497  // TODO: forbid TOF in PET with system matrix
498  // TODO: forbid simultaneous bed reconstruction with system matrix
499  // TODO: forbid image offset with system matrix
500  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Loading of custom system matrices is not yet implemented !" << endl);
501  return 1;
502  }
503  // ______________________________________________________________________________
504  // Case 2: on-the-fly projector
505  else
506  {
507  // Unset system matrix
508  mp_SystemMatrixForward = NULL;
509  m_useSystemMatrixForward = false;
510  // Set projector on
511  m_useProjectorForward = true;
512  // Get projector's listfrom addon manager
513  std::map <string,maker_projector> list = sAddonManager::GetInstance()->mp_listOfProjectors;
514  // Create the projector
516  else
517  {
518  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Projector '" << m_forwardProjectorName << "' does not exist !" << endl);
519  return 1;
520  }
521  // Set parameters
524  {
525  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while setting the image dimensions of the forward projector !" << endl);
526  return 1;
527  }
534 
535  // Provide common options list
537  {
538  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's common options !" << endl);
539  return 1;
540  }
541  // Provide configuration file if any
542  if (file_options!="" && mp_ProjectorForward->ReadConfigurationFile(file_options))
543  {
544  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's configuration file !" << endl);
545  return 1;
546  }
547  // Provide options if any
548  if (list_options!="" && mp_ProjectorForward->ReadOptionsList(list_options))
549  {
550  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading forward projector's options !" << endl);
551  return 1;
552  }
553  // Check parameters
555  {
556  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while checking forward projector parameters !" << endl);
557  return 1;
558  }
559  // Initialize the projector
561  {
562  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while initializing the forward projector !" << endl);
563  return 1;
564  }
565  }
566 
567  // ---------------------------------------------------------------------------------------------------
568  // Manage backward projector
569  // ---------------------------------------------------------------------------------------------------
570 
571  // If options are the same, then forward and backward are the same
573  {
574  // In this case, matched projectors
579  }
580  // Else, unmatched projectors
581  else
582  {
583  // ______________________________________________________________________________
584  // Get the projector name in the options and isolate the real projector's options
585 
586  // Search for a colon ":", this indicates that a configuration file is provided after the projector name
587  colon = m_optionsBackward.find_first_of(":");
588  comma = m_optionsBackward.find_first_of(",");
589 
590  // Case 1: we have a colon
591  if (colon!=string::npos)
592  {
593  // Get the projector name before the colon
594  m_backwardProjectorName = m_optionsBackward.substr(0,colon);
595  // Get the configuration file after the colon
596  file_options = m_optionsBackward.substr(colon+1);
597  // List of options is empty
598  list_options = "";
599  }
600  // Case 2: we have a comma
601  else if (comma!=string::npos)
602  {
603  // Get the projector name before the first comma
604  m_backwardProjectorName = m_optionsBackward.substr(0,comma);
605  // Get the list of options after the first comma
606  list_options = m_optionsBackward.substr(comma+1);
607  // Configuration file is empty
608  file_options = "";
609  }
610  // Case 3: no colon and no comma (a single projector name)
611  else
612  {
613  // Get the projector name
615  // List of options is empty
616  list_options = "";
617  // Build the default configuration file
618  file_options = sOutputManager::GetInstance()->GetPathToConfigDir() + "/projector/" + m_backwardProjectorName + ".conf";
619  }
620 
621  // ______________________________________________________________________________
622  // Case 1: projector is equal to keyword 'matrix', then use a system matrix
624  {
625  mp_ProjectorBackward = NULL;
626  m_useProjectorBackward = false;
628  // TODO: put all these limitations into a dedicated function from oSystemMatrix
629  // TODO: forbid TOF in PET with system matrix
630  // TODO: forbid simultaneous bed reconstruction with system matrix
631  // TODO: forbid image offset with system matrix
632  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Loading of custom system matrices is not yet implemented !" << endl);
633  return 1;
634  }
635  // ______________________________________________________________________________
636  // Case 2: on-the-fly projector
637  else
638  {
639  // Unset system matrix
642  // Set projector on
643  m_useProjectorBackward = true;
644  // Get projector's listfrom addon manager
645  std::map <string,maker_projector> list = sAddonManager::GetInstance()->mp_listOfProjectors;
646  // Create the projector
648  else
649  {
650  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> Projector '" << m_backwardProjectorName << "' does not exist !" << endl);
651  return 1;
652  }
653  // Set parameters
656  {
657  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while setting the image dimensions of the backward projector !" << endl);
658  return 1;
659  }
666  // Provide common options list
668  {
669  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's common options !" << endl);
670  return 1;
671  }
672  // Provide configuration file if any
673  if (file_options!="" && mp_ProjectorBackward->ReadConfigurationFile(file_options))
674  {
675  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's configuration file !" << endl);
676  return 1;
677  }
678  // Provide options if any
679  if (list_options!="" && mp_ProjectorBackward->ReadOptionsList(list_options))
680  {
681  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while parsing and reading backward projector's options !" << endl);
682  return 1;
683  }
684  // Check parameters
686  {
687  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while checking backward projector parameters !" << endl);
688  return 1;
689  }
690  // Initialize the projector
692  {
693  Cerr("***** oProjectorManager::ParseOptionsAndInitializeProjectors() -> A problem occurred while initializing backward projector !" << endl);
694  return 1;
695  }
696  }
697  }
698 
699  // Normal end
700  return 0;
701 }
702 
703 // =====================================================================
704 // ---------------------------------------------------------------------
705 // ---------------------------------------------------------------------
706 // =====================================================================
707 
709 {
710  // Set the sensitivity ON in the projectors, if used
713  // If the data file is a list-mode, then deactivate the TOF usage in the projector
715  {
718  }
719 }
720 
721 // =====================================================================
722 // ---------------------------------------------------------------------
723 // ---------------------------------------------------------------------
724 // =====================================================================
725 
727 {
728  // Set the sensitivity OFF in the projectors, if used
731  // Reset TOF and POI parameters to original values
733  {
736  }
738  {
741  }
742 }
743 
744 // =====================================================================
745 // ---------------------------------------------------------------------
746 // ---------------------------------------------------------------------
747 // =====================================================================
748 
750 {
751  // Apply it to all projection lines (only if more than one bed position)
755 }
756 
757 // =====================================================================
758 // ---------------------------------------------------------------------
759 // ---------------------------------------------------------------------
760 // =====================================================================
761 
763 {
764  #ifdef CASTOR_DEBUG
765  if (!m_initialized)
766  {
767  Cerr("***** oProjectorManager::ComputeProjectionLine() -> Called while not initialized !" << endl);
768  return NULL;
769  }
770  #endif
771 
773 
774  // Get the list of indices
775  uint32_t *index1 = ap_Event->GetEventID1();
776  uint32_t *index2 = ap_Event->GetEventID2();
777  int nb_indices = ap_Event->GetNbLines();
778 
779  // Clean the projection line
780  m2p_ProjectionLines[a_th]->Reset();
781 
782  // With list-mode data, we may need POI and/or TOF measurements
783  if (ap_Event->GetDataMode()==MODE_LIST)
784  {
785  // Set POI measurement
786  if (m_applyPOI)
787  {
788  // For PET
789  if (ap_Event->GetDataType()==TYPE_PET)
790  {
791  // Have to dynamic_cast the event into a iEventPETList to access the GetPOI functions
792  m2p_ProjectionLines[a_th]->SetPOI1((dynamic_cast<iEventListPET*>(ap_Event))->GetPOI1());
793  m2p_ProjectionLines[a_th]->SetPOI2((dynamic_cast<iEventListPET*>(ap_Event))->GetPOI2());
794  }
795  // For SPECT
796  else if (ap_Event->GetDataType()==TYPE_SPECT)
797  {
798  // By convention in SPECT, the second end point is in the camera (the first one being outside)
799  //m2p_ProjectionLines[a_th]->SetPOI2((dynamic_cast<iEventListModeSPECT*>(ap_Event))->GetPOI());
800  }
801  // For CT
802  else if (ap_Event->GetDataType()==TYPE_CT)
803  {
804  ;
805  }
806  }
807  // Set TOF measurement (only for PET obviously)
808  if (m_TOFMethod!=USE_NOTOF && ap_Event->GetDataType()==TYPE_PET)
809  {
810  // Have to dynamic_cast the event into a iEventPETList to access the GetTOF function
811  m2p_ProjectionLines[a_th]->SetTOFMeasurementInPs((dynamic_cast<iEventListPET*>(ap_Event))->GetTOFMeasurementInPs());
812  }
813  }
814 
815  // Project forward (and also compute line length)
816  int return_value = 0;
818  return_value = mp_ProjectorForward->Project( FORWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
819  else if (m_useSystemMatrixForward)
820  return_value = mp_SystemMatrixForward->Project( FORWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
821  if (return_value)
822  {
823  Cerr("***** oProjectorManager::ComputeProjectionLine() -> A problem occurred while forward projecting an event !" << endl);
824  return NULL;
825  }
826 
827  // Project backward
829  {
830  // Then project
832  return_value = mp_ProjectorBackward->Project( BACKWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices );
833  else if (m_useSystemMatrixBackward)
834  return_value = mp_SystemMatrixBackward->Project( BACKWARD, m2p_ProjectionLines[a_th], index1, index2, nb_indices);
835  if (return_value)
836  {
837  Cerr("***** oProjectorManager::ComputeProjectionLine() -> A problem occurred while backward projecting an event !" << endl);
838  return NULL;
839  }
840  }
841 
842  // Return the line
843  return m2p_ProjectionLines[a_th];
844 }
845 
846 // =====================================================================
847 // ---------------------------------------------------------------------
848 // ---------------------------------------------------------------------
849 // =====================================================================
851 {
852  // Check that the mask has not already been set
853  if (mp_mask!=NULL)
854  {
855  Cerr("***** oProjectorManager::ProcessAndSetMask() -> Mask already initialized !" << endl);
856  return 1;
857  }
858  // Allocate
860  // Fill the mask
862  {
863  // Currently, values not greater than 0 are regarded as background
864  // As the mask has a real number type, to avoid issues with zeros potentially written
865  // as extremely tiny floating point values, the values are first rounded to an integer type
866  // and then checked for greater than zero, improve this in the future (implicit behaviour)
867  mp_mask[v] = ((INTNB)std::round(ap_maskImage[v]))>0;
868  }
869  // Mask on
870  m_applyMask = true;
871  // End
872  return 0;
873 }
oProjectionLine ** m2p_ProjectionLines
#define VERBOSE_DEBUG_EVENT
bool GetTOFInfoFlag()
#define MODE_HISTOGRAM
Definition: vDataFile.hh:58
#define TYPE_PET
Definition: vDataFile.hh:73
FLTNB GetTOFMeasurementRangeInPs()
#define IMAGE_COMPUTATION_STRATEGY
#define MODE_LIST
Definition: vDataFile.hh:56
void SetMask(bool *ap_mask)
Set a mask for voxels.
Definition: vProjector.hh:331
void SetThreadNumber(int a_threadNumber)
This function is used to set the thread number of this particular line.
#define FLTNB
Definition: gVariables.hh:81
int GetDataType()
Definition: vEvent.hh:125
#define SPEED_OF_LIGHT_IN_MM_PER_PS
Definition: gVariables.hh:106
void SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
This function is used to set the pointer to the oImageDimensionsAndQuantification in use...
void SetScanner(vScanner *ap_Scanner)
Set the pointer to the scanner in use.
Definition: vProjector.hh:284
void SetMatchedProjectors(bool a_UseMatchedProjectors)
This function is used to set the boolean that says if we use matched projectors.
int Initialize()
A function used to initialize the manager and the projectors or system matrices it manages...
FLTNB GetBedPosition(int a_bedIndex)
Get the bed position associated to a bed index.
uint32_t * GetEventID2()
Definition: vEvent.hh:119
bool GetPOIInfoFlag()
Definition: vDataFile.hh:385
This class is designed to generically described any on-the-fly projector.
Definition: vProjector.hh:75
#define USE_TOFHISTO
Definition: vProjector.hh:47
bool GetCompatibilityWithSPECTAttenuationCorrection()
int Initialize()
A public function used to initialize the projector.
Definition: vProjector.cc:251
int Project(int a_direction, oProjectionLine *ap_ProjectionLine, uint32_t *ap_index1, uint32_t *ap_index2, int a_nbIndices)
A function use to computed the projection elements with respect to the provided parameters.
Definition: vProjector.cc:424
void SetTOFMeasurementInPs(FLTNB a_TOFMeasurementInPs)
This function is used to set the TOF measurement associated to the line.
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
static sOutputManager * GetInstance()
Instanciate the singleton object and Initialize member variables if not already done, return a pointer to this object otherwise.
#define TYPE_SPECT
Definition: vDataFile.hh:75
#define TYPE_CT
Definition: vDataFile.hh:77
Declaration of class iDataFilePET.
bool GetCompatibilityWithSPECTAttenuationCorrection()
Definition: vProjector.hh:318
void SetTOFBinSizeInMm(FLTNB a_TOFBinSizeInMm)
This function is used to set the size of a TOF bin in mm.
Definition: vProjector.hh:372
int GetDataMode()
Definition: vEvent.hh:131
void SetApplyTOF(int a_applyTOF)
Set the TOF mode.
Definition: vProjector.hh:298
static sAddonManager * GetInstance()
#define USE_TOFLIST
Definition: vProjector.hh:49
int ReadCommonOptionsList(const string &a_optionsList)
This function is used to read options common to all projectors given as a string. ...
Definition: vProjector.cc:160
oSystemMatrix * mp_SystemMatrixBackward
void SetVerbose(int a_verbose)
Set the verbose level.
Definition: vProjector.hh:277
#define FIXED_LIST_COMPUTATION_STRATEGY
~oProjectorManager()
The destructor of oProjectorManager.
#define Cerr(MESSAGE)
bool GetIgnorePOIFlag()
Definition: vDataFile.hh:391
void SetComputationStrategy(int a_computationStrategy)
This function is used to set the computation strategy in use.
int ParseOptionsAndInitializeProjectors()
Parse forward and backward projection options contained in the previously provided strings...
const string & GetPathToConfigDir()
Return the path to the CASTOR config directory.
void SetSensitivityMode(bool a_sensitivityMode)
Set the sensitivity mode on or off.
Definition: vProjector.hh:291
int GetNbBeds()
Get the number of bed positions.
int CheckParameters()
A public function used to check the parameters settings.
Definition: vProjector.cc:184
oSystemMatrix * mp_SystemMatrixForward
virtual int ReadOptionsList(const string &a_optionsList)=0
A function used to read options from a list of options.
FLTNB GetTOFQuantizationBinSizeInPs()
void SetNbTOFBins(int a_nbTOFBins)
This function is used to set the number of TOF bins in use.
virtual int ReadConfigurationFile(const string &a_configurationFile)=0
A function used to read options from a configuration file.
void SetTOFMeasurementRangeInMm(FLTNB a_TOFMeasurementRangeInMm)
This function is used to set the TOF measurement range in mm.
Definition: vProjector.hh:358
void SetPOI2(FLTNB *ap_POI2)
This function is used to set the POI of point 2.
oProjectionLine * ComputeProjectionLine(vEvent *ap_Event, int a_th)
This function is used to compute system matrix elements from the associated projector or pre-computed...
#define VERBOSE_NORMAL
FLTNB * GetPOIResolution()
Definition: vDataFile.hh:373
void Reset()
Reset length and all the voxel indices and weights tabs.
int GetDataType()
Definition: vDataFile.hh:310
int CheckParameters()
A function used to check the parameters settings.
void ApplyBedOffset(int a_bed)
Compute the bed offset from the provided bed index and apply it to all projection lines...
void SetSensitivityModeOn()
Say that the projector will be used to compute the global sensitivity.
void SetVerbose(int a_verbose)
This function is used to set the verbose level.
std::map< string, maker_projector > mp_listOfProjectors
void SetTOFResolutionInMm(FLTNB a_TOFResolutionInMm)
This function is used to set the TOF resolution in use.
Definition: vProjector.hh:344
oImageDimensionsAndQuantification * mp_ImageDimensionsAndQuantification
bool GetCompatibilityWithCompression()
Definition: vProjector.hh:324
void SetBackwardProjector(vProjector *ap_Projector)
This function is used to set the pointer to the backward projector.
#define SYSTEM_MATRIX_KEYWORD
int ProcessAndSetMask(FLTNB *ap_maskImage)
Process and set the provided mask image for projector masking.
bool IsBackwardOperatorCompatibleWithSPECTAttenuationCorrection()
void SetPOI1(FLTNB *ap_POI1)
This function is used to set the POI of point 1.
FLTNB GetTOFBinSizeInPs()
FLTNB GetTOFResolutionInPs()
#define INTNB
Definition: gVariables.hh:92
This class is designed to manage and store system matrix elements associated to a vEvent...
vProjector * mp_ProjectorBackward
vProjector * mp_ProjectorForward
void SetPOIResolution(FLTNB *ap_POIResolution)
This function is used to set the POI resolution along the 3 axes.
uint16_t GetNbLines()
Definition: vEvent.hh:93
void SetForwardProjector(vProjector *ap_Projector)
This function is used to set the pointer to the forward projector.
Declaration of class sOutputManager.
Mother class for the Event objects.
Definition: vEvent.hh:42
bool GetIgnoreTOFFlag()
int GetDataMode()
Definition: vDataFile.hh:299
INTNB GetNbVoxXYZ()
Get the total number of voxels.
int GetNbThreadsForProjection()
Get the number of threads used for projections.
int GetNbTOFBins()
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
#define USE_NOTOF
Definition: vProjector.hh:51
uint32_t * GetEventID1()
Definition: vEvent.hh:113
int Project(int a_direction, oProjectionLine *ap_ProjectionLine, uint32_t *ap_index1, uint32_t *ap_index2, int a_nbIndices)
#define FORWARD
#define Cout(MESSAGE)
void SetApplyPOI(bool a_applyPOI)
Set the POI mode.
Definition: vProjector.hh:305
int CheckSPECTAttenuationCompatibility(const string &a_pathToAttenuationImage)
A function used to check specific compatibility with SPECT and attenuation correction.
Declaration of class oProjectorManager.
int SetImageDimensionsAndQuantification(oImageDimensionsAndQuantification *ap_ImageDimensionsAndQuantification)
Set the pointer to the image dimensions in use and copy locally some often use variables.
Definition: vProjector.cc:89
Inherit from vDataFile. Class that manages the reading of a PET input file (header + data)...
Definition: iDataFilePET.hh:43
Declaration of class sAddonManager.
bool IsForwardOperatorCompatibleWithSPECTAttenuationCorrection()
#define BACKWARD