CASToR  3.0
Tomographic Reconstruction (PET/SPECT/CT)
vScanner.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 "sScannerManager.hh"
31 #include "vScanner.hh"
32 
33 // =====================================================================
34 // ---------------------------------------------------------------------
35 // ---------------------------------------------------------------------
36 // =====================================================================
37 
39 {
40  // Initialize all members to default values
42  m_verbose = -1;
43  mp_ID = NULL;
44  m_allParametersChecked = false;
45  mp_rotationMatrix = NULL;
46  mp_positionMatrix_ref = NULL;
47  mp_positionMatrix_out = NULL;
50 }
51 
52 // =====================================================================
53 // ---------------------------------------------------------------------
54 // ---------------------------------------------------------------------
55 // =====================================================================
56 
58 {
62 }
63 
64 
65 
66 
67 // =====================================================================
68 // ---------------------------------------------------------------------
69 // ---------------------------------------------------------------------
70 // =====================================================================
71 /*
72  \fn int vScanner::Describe()
73  \brief A function used to describe the generic parts of the datafile
74 */
76 {
78  if (m_verbose==0) return;
79 
80  // Describe the datafile
81  Cout("vScanner::Describe() -> Here is some generic content of the scanner" << endl);
82  if (m_scannerType == 0)
83  Cout(" --> Scanner type: " << GetScannerTypeString() << endl);
84 
85  // Call the specific function of the scanner
87 }
88 
89 
90 
91 // =====================================================================
92 // ---------------------------------------------------------------------
93 // ---------------------------------------------------------------------
94 // =====================================================================
101 {
102  if (m_scannerType == SCANNER_PET)
103  return "SCANNER PET";
105  return "SCANNER SPECT PINHOLE";
107  return "SCANNER SPECT CONVERGENT";
108  else if (m_scannerType == SCANNER_CT)
109  return "SCANNER CT";
110  else if (m_scannerType == SCANNER_SINOGRAM)
111  return "SCANNER SINOGRAM";
112 
113  // Default
114  return "Unknown";
115 }
116 
117 
118 
119 
120 // =====================================================================
121 // ---------------------------------------------------------------------
122 // ---------------------------------------------------------------------
123 // =====================================================================
124 /*
125  \fn ComputeLUT
126  \brief Virtual function which should be implemented by the child classes.
127  It computes the LUT of the scanner from a generic (.geom) file.
128  The vScanner implementation throws error by default as it should be implemented by the child class
129  \todo Make the mother function virtual pure ? (should iScannerSinogram also implement this function ?)
130  \todo iScannerCT implementation will probably consists in computing one projection, then computing
131  the others on-the-fly during reconstruction (Often too much data to keep in memory for CT)
132  Have to check if we offer the precomputation of the entire LUT in some situation, as for PET/SPECT
133  \return 1 (error) if not surcharged by a daughter class
134 */
136 {
137  Cerr("***** vScanner::ComputeLUT() -> Call to ComputeLUT() which is not implemented by the scanner child class !" << endl);
138  return 1;
139 }
140 
141 
142 
143 // =====================================================================
144 // ---------------------------------------------------------------------
145 // ---------------------------------------------------------------------
146 // =====================================================================
147 /*
148  \fn LoadLUT
149  \brief Virtual function which should be implemented by the child classes.
150  Load a precomputed scanner LUT.
151  The vScanner implementation throws error by default as it should be implemented by the child class
152  \todo Make the mother function virtual pure ? (should iScannerSinogram also implement this function ?)
153  \todo iScannerCT implementation will probably consists in computing one projection, then computing
154  the others on-the-fly during reconstruction (Often too much data to keep in memory for CT)
155  Have to check if we offer the precomputation of the entire LUT in some situation, as for PET/SPECT
156  \return 1 (error) if not surcharged by a daughter class
157 */
159 {
160  Cerr("***** vScanner::ComputeLUT() -> Call to ComputeLUT() which is not implemented by the scanner child class !" << endl);
161  return 1;
162 }
163 
164 
165 
166 // =====================================================================
167 // ---------------------------------------------------------------------
168 // ---------------------------------------------------------------------
169 // =====================================================================
170 // ----- PET Specific Functions --- //
171 /*
172  \fn IsAvailableLOR
173  \param a_elt1 : index of the 1st scanner element
174  \param a_elt2 : index of the 2nd scanner element
175  \brief This function is implemented in child classes.
176  Check if the LOR is available according to the scanner restrictions
177  \details This function is related to analytic projection and list-mode sensitivity image generation
178  \return 1 if the LOR is available, 0 otherwise (vScanner implementation returns 1 by default)
179 */
180 int vScanner::IsAvailableLOR(int a_elt1, int a_elt2)
181 {
182  Cerr("***** vScanner::IsAvailableLOR() -> This function is not implemented by the Instantiated scanner class !!" << endl);
183  Cerr(" This function only works with PET scanner objects !!" << endl);
184  return 1;
185 }
186 
187 
188 
189 
190 // =====================================================================
191 // ---------------------------------------------------------------------
192 // ---------------------------------------------------------------------
193 // =====================================================================
194 /*
195  \fn SetPETMaxRingDiff
196  \param a_maxAxialDiffmm
197  \brief Set the maximal axial difference in mm between 2 crystals forming a lor
198  \details This function is surcharged by the PET scanner daughter class
199  Returns an error by default.
200  \return 1 (error) if not surcharged by a daughter class
201 */
203 {
204  Cerr("***** vScanner::SetPETMaxAxialDiffmm() -> This function is not implemented by the Instantiated scanner class !!" << endl);
205  Cerr(" This function only works with PET scanner objects !!" << endl);
206  return 1;
207 }
208 
209 
210 
211 // =====================================================================
212 // ---------------------------------------------------------------------
213 // ---------------------------------------------------------------------
214 // =====================================================================
215 /*
216  \fn PROJ_GetPETSpecificParameters
217  \param ap_maxRingDiff
218  \brief Get geometric PET specific parameters to initialize the datafile
219  \details This function is surcharged by the PET scanner daughter classes
220  Returns an error by default.
221  \return 1 (error) if not surcharged by a daughter class
222 */
224 {
225  Cerr("***** vScanner::PROJ_GetPETSpecificParameters() -> This function is not implemented by the Instantiated scanner class !!" << endl);
226  Cerr(" This function only works with PET scanner objects !!" << endl);
227  return 1;
228 }
229 
230 
231 
232 // =====================================================================
233 // ---------------------------------------------------------------------
234 // ---------------------------------------------------------------------
235 // =====================================================================
236 
237 int vScanner::GetSPECTSpecificParameters(uint16_t* ap_nbOfProjections,
238  uint16_t* ap_nbHeads,
239  FLTNB* ap_acquisitionZoom,
240  uint16_t* ap_nbOfBins,
241  FLTNB* ap_pixSizeXY,
242  FLTNB*& ap_angles,
243  FLTNB*& ap_CORtoDetectorDistance,
244  int* ap_headRotDirection)
245 {
246  Cerr("***** vScanner::GetSPECTSpecificParameters() -> This function is not implemented by the Instantiated scanner class !!" << endl);
247  Cerr(" This function only works with SPECT scanner objects !!" << endl);
248  return 1;
249 }
250 
251 
252 // =====================================================================
253 // ---------------------------------------------------------------------
254 // ---------------------------------------------------------------------
255 // =====================================================================
256 // ----- CT Specific Functions --- //
257 /*
258  \fn GetCTSpecificParameters
259  \param ap_nbOfProjections
260  \param ap_angles
261  \param ap_detectorRotDirection
262  \brief Recover geometric CT specific parameters from the scanner to initialize the datafile
263  \details This function is surcharged by the CT scanner daughter classes
264  Returns an error by default.
265  \return 1 (error) if not surcharged by a daughter class
266 */
267 int vScanner::GetCTSpecificParameters(uint16_t* ap_nbOfProjections,
268  FLTNB*& ap_angles,
269  int* ap_detectorRotDirection)
270 {
271  Cerr("***** vScanner::GetCTSpecificParameters() -> This function is not implemented by the Instantiated scanner class !!" << endl);
272  Cerr(" This function only works with CT scanner objects !!" << endl);
273  return 1;
274 }
275 
276 
277 // =====================================================================
278 // ---------------------------------------------------------------------
279 // ---------------------------------------------------------------------
280 // =====================================================================
281 /*
282  \fn SetRotDirection
283  \param a_rotDirection
284  \brief Set rotation direction of the system
285  \details Set rotation direction of the scanner elements (head for SPECT, rsector/modules for PET)
286  for the generation of the geometry
287  \return 0 if success, positive value otherwise (unknown key)
288 */
289 int vScanner::SetRotDirection( string a_rotDirection )
290 {
291  if( a_rotDirection == "CCW" ||
292  a_rotDirection == "Ccw" ||
293  a_rotDirection == "ccw" )
295 
296  else if(a_rotDirection == "" || // Default
297  a_rotDirection == "CW" ||
298  a_rotDirection == "Cw" ||
299  a_rotDirection == "cw" )
301 
302  else
303  {
304  Cerr("***** vScanner::SetRotDirection -> Error while initializing rotation direction !" << endl);
305  Cerr(" "<< a_rotDirection <<"' is unknown. Direction must be 'CW' (clockwise) or 'CCW' (counter-clockwise).");
306  return 1;
307  }
308 
309  return 0;
310 }
311 
312 
313 // =====================================================================
314 // ---------------------------------------------------------------------
315 // ---------------------------------------------------------------------
316 // =====================================================================
317 /*
318  \fn PROJ_SetSPECTNbBins
319  \param ap_nbOfBins
320  \brief Set SPECT number of Bins
321  \details This function is surcharged by the SPECT scanner daughter classes
322  Returns an error by default.
323  \return 1 (error) if not surcharged by a daughter class
324 */
325 int vScanner::PROJ_SetSPECTNbBins(uint16_t* ap_nbOfBins)
326 {
327  Cerr("***** vScanner::PROJ_SetSPECTNbBins() -> This function is not implemented by the Instantiated scanner class !!" << endl);
328  Cerr(" This function only works with SPECT scanner objects !!" << endl);
329  return 1;
330 }
331 
332 
333 
334 // =====================================================================
335 // ---------------------------------------------------------------------
336 // ---------------------------------------------------------------------
337 // =====================================================================
338 /*
339  \fn PROJ_SetSPECTNbProjections
340  \param a_nbOfProjections
341  \brief Set SPECT number of views
342  \details This function is surcharged by the SPECT scanner daughter classes
343  Returns an error by default.
344  \return 1 (error) if not surcharged by a daughter class
345 */
346 int vScanner::PROJ_SetSPECTNbProjections(uint32_t a_nbOfProjections)
347 {
348  Cerr("***** vScanner::PROJ_SetSPECTNbProjections() -> This function is not implemented by the Instantiated scanner class !!" << endl);
349  Cerr(" This function only works with SPECT scanner objects !!" << endl);
350  return 1;
351 }
352 
353 
354 
355 
356 
357 
358 // =====================================================================
359 // ---------------------------------------------------------------------
360 // ---------------------------------------------------------------------
361 // =====================================================================
362 /*
363  \fn PROJ_SetSPECTAngles
364  \param ap_projectionAngles
365  \brief Set SPECT projection angles
366  \details This function is surcharged by the SPECT scanner daughter classes
367  Returns an error by default.
368  \return 1 (error) if not surcharged by a daughter class
369 */
370 int vScanner::PROJ_SetSPECTAngles(FLTNB* a2p_projectionAngles)
371 {
372  Cerr("***** vScanner::SetSPECTAngles() -> This function is not implemented by the Instantiated scanner class !!" << endl);
373  Cerr(" This function only works with SPECT scanner objects !!" << endl);
374  return 1;
375 }
376 
377 
378 
379 // =====================================================================
380 // ---------------------------------------------------------------------
381 // ---------------------------------------------------------------------
382 // =====================================================================
383 /*
384  \fn PROJ_SetSPECTCORtoDetectorDistance
385  \param a_CORtoDetectorDistance
386  \brief Set distance between center of rotation and SPECT detectors
387  \details This function is surcharged by the SPECT scanner daughter classes
388  Returns an error by default.
389  \return 1 (error) if not surcharged by a daughter class
390 */
392 {
393  Cerr("***** vScanner::SetSPECTCORtoDetectorDistance() -> This function is not implemented by the Instantiated scanner class !!" << endl);
394  Cerr(" This function only works with SPECT scanner objects !!" << endl);
395  return 1;
396 }
397 
398 
399 
400 // =====================================================================
401 // ---------------------------------------------------------------------
402 // ---------------------------------------------------------------------
403 // =====================================================================
404 /*
405  \fn PROJ_GetSPECTNbProjections
406  \brief return the total number of projections for a SPECT acquisition
407  \details This function is surcharged by the SPECT scanner daughter classes
408  Returns an error by default.
409  \return 1 (error) if not surcharged by a daughter class
410 */
412 {
413  Cerr("***** vScanner::GetSPECTNbProjections() -> This function is not implemented by the Instantiated scanner class !!" << endl);
414  Cerr(" This function only works with SPECT scanner objects !!" << endl);
415  return 1;
416 }
417 
418 
419 
420 // =====================================================================
421 // ---------------------------------------------------------------------
422 // ---------------------------------------------------------------------
423 // =====================================================================
424 /*
425  \fn PROJ_GetSPECTNbPixels
426  \brief return the total number of pixels for a SPECT reconstruction
427  \details This function is surcharged by the SPECT scanner daughter classes
428  Returns an error by default.
429  \return 1 (error) if not surcharged by a daughter class
430 */
432 {
433  Cerr("***** vScanner::GetSPECTNbPixels() -> This function is not implemented by the Instantiated scanner class !!" << endl);
434  Cerr(" This function only works with SPECT scanner objects !!" << endl);
435  return 1;
436 }
437 
virtual int PROJ_SetSPECTNbBins(uint16_t *ap_nbOfBins)
Set SPECT number of Bins.
Definition: vScanner.cc:325
virtual int PROJ_SetSPECTNbProjections(uint32_t a_nbOfProjections)
Set SPECT number of views.
Definition: vScanner.cc:346
#define FLTNB
Definition: gVariables.hh:81
virtual int PROJ_GetPETSpecificParameters(FLTNB *ap_maxRingDiff)
Get geometric PET specific parameters to initialize the datafile.
Definition: vScanner.cc:223
virtual int SetPETMaxAxialDiffmm(FLTNB a_maxAxialDiffmm)
Set the maximal axial difference in mm between 2 crystals forming a lor.
Definition: vScanner.cc:202
virtual int PROJ_SetSPECTAngles(FLTNB *ap_projectionAngles)
Set SPECT projection angles.
Definition: vScanner.cc:370
oMatrix * mp_positionMatrix_out
Definition: vScanner.hh:442
#define GEO_ROT_CCW
Definition: vScanner.hh:48
#define SCANNER_UNKNOWN
vScanner()
vScanner constructor. Initialize the member variables to their default values.
Definition: vScanner.cc:38
FLTNB m_defaultBedDisplacementInMm
Definition: vScanner.hh:444
virtual uint16_t PROJ_GetSPECTNbProjections()
return the total number of projections for a SPECT acquisition
Definition: vScanner.cc:411
#define SCANNER_PET
virtual uint16_t PROJ_GetSPECTNbPixels()
return the total number of pixels for a SPECT reconstruction
Definition: vScanner.cc:431
oImageDimensionsAndQuantification * mp_ID
Definition: vScanner.hh:438
virtual void DescribeSpecific()=0
A pure virtual function used to describe the specific parts of the scanner.
oMatrix * mp_rotationMatrix
Definition: vScanner.hh:440
#define Cerr(MESSAGE)
#define SCANNER_SPECT_CONVERGENT
#define VERBOSE_DEBUG_LIGHT
virtual int SetRotDirection(string a_rotDirection)
Set rotation direction of the system.
Definition: vScanner.cc:289
Declaration of class vScanner.
#define SCANNER_SINOGRAM
virtual ~vScanner()
vScanner destructor.
Definition: vScanner.cc:57
void Describe()
A function used to describe the generic parts of the datafile.
Definition: vScanner.cc:75
Declaration of class sScannerManager.
int m_verbose
Definition: vScanner.hh:437
virtual int ComputeLUT()
Virtual function which should be implemented by the child classes. It computes the LUT of the scann...
Definition: vScanner.cc:135
string GetScannerTypeString()
Definition: vScanner.cc:100
bool m_allParametersChecked
Definition: vScanner.hh:439
virtual int GetSPECTSpecificParameters(uint16_t *ap_nbOfProjections, uint16_t *ap_nbHeads, FLTNB *ap_acquisitionZoom, uint16_t *ap_nbOfBins, FLTNB *ap_pixSizeXY, FLTNB *&ap_angles, FLTNB *&ap_CORtoDetectorDistance, int *ap_headRotDirection)
Recover geometric SPECT specific parameters from the scanner to initialize the datafile.
Definition: vScanner.cc:237
#define SCANNER_SPECT_PINHOLE
virtual int PROJ_SetSPECTCORtoDetectorDistance(FLTNB a_CORtoDetectorDistance)
Set distance between center of rotation and SPECT detectors.
Definition: vScanner.cc:391
int m_scannerType
Definition: vScanner.hh:436
oMatrix * mp_positionMatrix_ref
Definition: vScanner.hh:441
#define DEBUG_VERBOSE(IGNORED1, IGNORED2)
virtual int LoadLUT()
Virtual function which should be implemented by the child classes. Load a precomputed scanner LUT...
Definition: vScanner.cc:158
#define Cout(MESSAGE)
#define SCANNER_CT
virtual int IsAvailableLOR(int a_elt1, int a_elt2)
This function is implemented in child classes. Check if the LOR is available according to the scann...
Definition: vScanner.cc:180
int m_rotDirection
Definition: vScanner.hh:443
virtual int GetCTSpecificParameters(uint16_t *ap_nbOfProjections, FLTNB *&ap_angles, int *ap_detectorRotDirection)
Recover geometric CT specific parameters from the scanner to initialize the datafile.
Definition: vScanner.cc:267
#define GEO_ROT_CW
Definition: vScanner.hh:46