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