STIR  6.2.0
PinholeSPECTUB_Tools.h
1 /*
2  Copyright (C) 2022, Matthew Strugari
3  Copyright (C) 2014, Biomedical Image Group (GIB), Universitat de Barcelona, Barcelona, Spain. All rights reserved.
4  Copyright (C) 2014, 2021, University College London
5  This file is part of STIR.
6 
7  This software is distributed WITHOUT ANY WARRANTY;
8  without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
9 
10  See STIR/LICENSE.txt for details
11 
12  \author Carles Falcon
13  \author Matthew Strugari
14 */
15 
16 #ifndef _WM_SPECT_mph_H
17 #define _WM_SPECT_mph_H
18 
19 #include <iostream>
20 #include <vector>
21 
22 namespace SPECTUB_mph
23 {
24 
25 //::: structures ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
26 
27 //.....structure for distribution function information
28 
29 typedef struct
30 {
31  int max_dimx; // maximum size in bins (for allocation purpose)
32  int max_dimz; // maximum size in bins (for allocation purpose)
33 
34  int dimx; // actual number of bins forming the PSF (dimx)
35  int dimz; // actual number of bins forming the PSF (dimz)
36 
37  int ib0; // first i index for the bins of the PSF
38  int jb0; // first j index for the bins of the PSF
39 
40  float lngxcmd2; // half of the lenght in cm, dimx
41  float lngzcmd2; // half of the lenght in cm, dimz
42 
43  float xc;
44  float zc;
45 
46  float sum; // sum of values (for intensity normalization)
47 
48  float** val; // array of values
49  // float res1; // resolution dimx
50  // float res2; // resolution dimz
51 
52 } psf2d_type;
53 
54 //... collimator's holes parametre structure................................
55 
56 typedef struct
57 {
58  // int idet; // index of the detel the hole projects to
59 
60  //... coordinates ......................
61 
62  float acy; // angular coordinate of the hole in volume framework: angle (deg) (cyl)
63  float acyR; // angular coordinate of the hole in rotated framework: ang (deg) (cyl)
64 
65  float x1; // x coordinate of the center of the hole (cm): rotated framework
66  float y1; // y coordinate of the center of the hole (cm): rotated framework
67  float z1; // z coordinate of the center of the hole (cm): rotated framework
68 
69  //... axial, edge and acceptance angles ...............................
70 
71  float ahx; // x angle of the hole axis (deg)
72  float ahz; // z angle of the hole axis (deg)
73 
74  float aa_x; // acceptance angle x (aperture with respect to hole axis: half of the total acceptance angle)
75  float aa_z; // acceptance angle z (aperture with respect to hole axis: half of the total acceptance angle)
76 
77  float egx; // absolute angle of the hole edge (x, minor) in rotated framework
78  float Egx; // absolute angle of the hole edge (x, major) in rotated framework
79  float egz; // absolute angle of the hole edge (z, minor) in rotated framework
80  float Egz; // absolute angle of the hole edge (z, major) in rotated framework
81 
82  float ax_M; // maximum angle of acceptance x
83  float ax_m; // minimum angle of acceptance x
84  float az_M; // maximum angle of acceptance z
85  float az_m; // minimum angle of acceptance z
86 
87  //... others ....................
88 
89  std::string shape; // hole shape { rect, round }
90  bool do_round; // true: round shape || false: rectangular shape
91  float dxcm; // horizontal size of the hole (cm): horizontal axis, diameter
92  float dzcm; // vertical size of the hole (cm): vertical axis, diameter
93 
94 } hole_type;
95 
96 //... structure for collimator information
97 
98 typedef struct
99 {
100  std::string model; // cylindrical (cyl) or polygonal prism (pol)
101 
102  float rad; // radius of cylinder containig holes (cyl) or apothem (pol)
103  float L; // collimator thickness
104  float Ld2; // half of the collimator thickness
105 
106  int Nht; // total number of holes
107  std::vector<hole_type> holes; // array hole_type structure
108 
109 } mphcoll_type;
110 
111 //.....structure for ring elements information
112 
113 typedef struct
114 {
115  int nh; // number of holes that project to this detel
116  std::vector<int> who; // array of indices of holes projecting to this detel
117 
118  float x0; // cartesian coordinates of the center (unrotated system of reference): x
119  float y0; // cartesian coordinates of the center (unrotated system of reference): y
120  float z0; // cartesian coordinates of the center (unrotated system of reference): z
121 
122  float xbin0; // x coordinate for the first bin of the detection row corresponding to this angle
123  float ybin0; // y coordinate for the first bin of the detection row corresponding to this angle
124  float zbin0; // z coordinate for the first bin of the detection row corresponding to this angle
125 
126  float incx; // increment in x to the following bin in detector row
127  float incy; // increment in y to the following bin in detector row
128  float incz; // increment in z to the following detector row
129 
130  float theta; // theta: in-plane angle radius vs x-axis. longitude (deg)
131  float costh; // cosinus of theta
132  float sinth; // sinus of theta
133 
134 } detel_type;
135 
136 //.....structure for distribution function information
137 
138 typedef struct
139 {
140  int dim; // length (in discretization intervals) (odd number)
141  int i_max; // last i-index = dim -1
142  float res; // spatial resolution of distfunc (discretization interval)
143  float* val; // double array of values
144 
145 } discrf1d_type;
146 
147 //.....structure for distribution function information
148 
149 typedef struct
150 {
151  int dim; // length (in discretization intervals) (odd number)
152  int i_max; // last i-index = dim -1
153  int j_max; // last j-index = dim -1
154  float res; // spatial resolution of distfunc (discretization interval)
155  float** val; // double array of values
156 
157 } discrf2d_type;
158 
159 //.....structure for projection information
160 
161 typedef struct
162 {
163  int Nbin; // number of bins per row
164  int Nsli; // number of slices
165 
166  int Ndt; // number of detels (detector elements)
167  int Nbd; // number of bins per detel
168  int Nbt; // total number of bins
169 
170  float szcm; // bin size in cm
171  float szcmd2; // bin size in cm divided by 2
172  float thcm; // slice thickness (cm)
173  float thcmd2; // slice thickness in cm divided by 2
174 
175  float crth; // crystal thickness (cm) to correction for depth
176  float crth_2; // power 2 of the above value
177  float crattcoef; // attenuation coefficient of crystal
178  float max_dcr; // maximum distance of a ray inside the crystal
179 
180  float FOVxcmd2; // FOVcmx divided by 2
181  float FOVzcmd2; // FOVcmz divided by 2
182 
183  float rad; // ring radius
184  float radc; // extended ring radius = radius + crystal thickness
185 
186  int NOS; // number of subsets
187  int NdOS; // Number of detels per subset = Ndt/NOS
188  int NbOS; // total number of bins per subset = Nbt/NOS
189 
190  int* order; // order of the angles of projection (array formed by indexs of angles belonging to consecutive subsets)
191  float sgm_i; // sigma of intrinsic PSF (cm)
192 
193  float* val;
194 
195 } prj_mph_type;
196 
197 //... structure for bin information..................................
198 
199 typedef struct
200 {
201 
202  int Dimx; // number of columns
203  int Dimy; // number of rows
204  int Dimz; // number of slices
205 
206  int Npix; // number of pixels (voxels) per axial slice
207  int Nvox; // number of voxels (the whole volume)
208 
209  int first_sl; // first slice to reconstruct (0->Nslic-1)
210  int last_sl; // last slice to reconstruct + 1 (end of the 'for' loop) (1->Nslic)
211 
212  float FOVxcmd2; // half of the size of the volume, dimension x (cm);
213  float FOVcmyd2; // half of the size of the volume, dimension y (cm);
214  float FOVzcmd2; // half of the size of the volume, dimension z (cm);
215 
216  float szcm; // voxel size (side length in cm)
217  float thcm; // voxel thickness (cm)
218 
219  float x0; // x coordinate (cm, ref center of volume) of the first voxel
220  float y0; // y coordinate (cm, ref center of volume) of the first voxel
221  float z0; // z coordinate (cm, ref center of volume) of the first voxel
222 
223  float* val; // array of values
224 
225 } volume_type;
226 
227 //... matrix header information ............................
228 
229 typedef struct
230 {
231  int subsamp; // bin subsampling factor for accurate PSF and convolution calculations (typically 2 to 5)
232  float mn_w; // minimum weight to be taken into account
233  float highres; // high spatial resolution of continous distributions in PSF calculation
234 
235  float Nsigm; // number of sigmas in PSF calculation
236  float mndvh2; // squared minimum distance voxel-hole (cm). Reference for efficiency
237  float ro; // radius of the object
238 
239  float max_hsxcm; // maximum hole size dimx (for allocation purposes)
240  float max_hszcm; // maximum hole size dimz (for allocation purposes)
241  float max_amp; // maximum amplification
242  float tmax_aix; // tangent of the maximum incidence angle x (for allocation purposes)
243  float tmax_aiz; // tangent of the maximum incidence angle z (for allocation purposes)
244 
245  bool do_psfi; // true: correct for intrinsic PSF
246  bool do_depth; // true: correct for impact depth
247  bool do_att; // true: correct for attenuation
248  bool do_full_att; // true: coef att for each bin of PSF || false: same att factor for all bins of PSF (central line)
249  bool do_msk_att; // true: to use att map as a mask
250  bool do_msk_file; // true: explicit mask
251 
252  // internal booleans variables
253 
254  bool do_subsamp;
255  bool do_round_cumsum;
256  bool do_square_cumsum;
257 
258  std::string att_fn; // attenuation map filename
259  std::string msk_fn; // explicit mask filename
260  std::string detector_fn; // ring parameter filename
261  std::string collim_fn; // collimator parameter filename
262 
263  volume_type vol; // structure with information of volume
264  std::vector<detel_type> detel; // structure with detection elements information
265  prj_mph_type prj; // structure with detection rings information
266  mphcoll_type collim; // structure with the collimator information
267 
268 } wmh_mph_type;
269 
270 //.......weight_mat structure definition. Structure for reading weight matrix
271 
272 typedef struct
273 {
274  //... weight matrix dimensions .....................
275 
276  int ne; // nonzero elements
277  int Nbt; // dimension 2 (rows) of the weight matrix (NbOS or Nbt)
278  int Nvox; // dimension 1 (columns) of the weight matrix (Nvox)
279 
280  //... weight matrix values .........................
281 
282  float* ar; // array of nonzero elements of weight matrix (by rows)
283  int* ja; // array of the column index of the above elements
284  int* ia; // array containing the indexes of the previous vector where a row change happens
285 
286 } wm_type;
287 
288 //.......weight_mat_da structure definition. Structure for generating weight matrix
289 
290 typedef struct
291 {
292  int Nbt; // dimension 2 (rows) of the weight matrix (NbOS or Nbt)
293  int Nvox; // dimension 1 (columns) of the weight matrix (Nvox)
294  float** val; // double array to store weights (index of the projection element, number of weight for that element)
295  int** col; // double array to store column indexs of the above element (index of the projection element, number of weight for
296  // that element)
297  int* ne; // array indicating how many elements has been stored for each element of projection
298 
299  //... filename .............................................
300 
301  std::string fn; // matrix name
302  std::string fn_hdr; // matrix header file name
303 
304  //... format ...............................................
305 
306  bool do_save_STIR; // to save weight matrix with STIR format
307 
308  //... indexs for STIR format ...............................
309 
310  int *na, *nb, *ns; // indexs for projection elements (angle, bin, slice respec.)
311  short int *nx, *ny, *nz; // indexs for image elements (x,y,z)
312 
313 } wm_da_type;
314 
315 //.....structure for distribution function information
316 
317 typedef struct
318 {
319  discrf2d_type square; // distribution for square shape hole
320  discrf2d_type round; // distribution for round shape hole
321  discrf1d_type cr_att; // exponential to correct for crystal attenuation when do_depth
322 
323 } pcf_type;
324 
325 //.....structure for voxel information
326 
327 typedef struct
328 {
329  int ix; // column index
330  int iy; // row index
331  int iz; // slice index
332  int ip; // inplane index (slice as an array)
333  int iv; // volume index (considering the volume as an array) of the voxel
334 
335  float x; // x coordinate (cm, ref center of volume)
336  float y; // y coordinate (cm, ref center of volume)
337  float z; // z coordinate (cm, ref center of volume)
338 
339  float x1; // x coordinate in rotated framework (cm)
340  float y1; // y coordinate in rotated framework (cm)
341 
342 } voxel_type;
343 
344 //.....structure for bin information
345 
346 typedef struct
347 {
348  float x; // x coordinate (cm, ref center of volume)
349  float y; // y coordinate (cm, ref center of volume)
350  float z; // z coordinate (cm, ref center of volume)
351 
352 } bin_type;
353 
354 //...... structure for LOR information
355 
356 typedef struct
357 {
358  //... all the following distances in cm .....................
359 
360  float x1d_l; // x coordiante of intersection lor-detection plane in rotated reference system
361  float z1d_l; // z coordiante of intersection lor-detection plane in rotated reference system
362  float x1dc_l; // x coordiante of intersection lor-detection plane + crystal in rotated reference system
363  float z1dc_l; // z coordiante of intersection lor-detection plane + crystal in rotated reference system
364 
365  float hsxcm_d; // size (cm) of the shadow of the hole at detector plane (x-azis)
366  float hszcm_d; // size (cm) of the shadow of the hole at detector plane (z-axis)
367  float hsxcm_d_d2; // half of the size (cm) of the shadow of the hole at detector plane (x-azis)
368  float hszcm_d_d2; // half of the size (cm) of the shadow of the hole at detector plane (z-axis)
369 
370  float hsxcm_dc; // size (cm) of the shadow of the hole at detector + crystal plane (x-axis)
371  float hszcm_dc; // size (cm) of the shadow of the hole at detector + crystal plane (z-axis)
372  float hsxcm_dc_d2; // half of the size (cm) of the shadow of the hole at detector plane (x-azis)
373  float hszcm_dc_d2; // half of the size (cm) of the shadow of the hole at detector plane (z-axis)
374 
375  //... others .......................................................
376 
377  float eff; // effectiveness
378 
379 } lor_type; // voxel-hole link
380 
381 //::: functions :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
382 
383 //... functions from wmtools_SPECT.cpp .........................................
384 
385 void wm_alloc(int* Nitems, wm_da_type& wm, wmh_mph_type& wmh); // allocate wm
386 
387 // void free_wm () ; // delete wm
388 
389 // void write_wm_FC_mph (); // write double array weight matrix
390 
391 // void write_wm_hdr_mph (); // write header of a matrix
392 
393 // void write_wm_STIR_mph (); // write matrix in STIR format
394 
395 void read_prj_params_mph(wmh_mph_type& wmh); // read ring parameters from a file
396 
397 void read_coll_params_mph(wmh_mph_type& wmh); // read collimator parameters from a file
398 
399 // void which_hole();
400 
401 void fill_pcf(wmh_mph_type& wmh, pcf_type& pcf); // fill precalculated functions
402 
403 // void free_pcf (); // fill precalculated functions
404 
405 void calc_cumsum(discrf2d_type* f);
406 
407 void generate_msk_mph(bool* msk_3d, float* att, wmh_mph_type& wmh); // create a boolean mask for wm (no weights outside the msk)
408 
409 // void read_msk_file_mph ( bool * msk ); // read mask from a file
410 
411 std::string wm_SPECT_read_value_1d(std::ifstream* stream1, char DELIMITER);
412 
413 void wm_SPECT_read_hvalues_mph(std::ifstream* stream1, char DELIMITER, int* nh, bool do_cyl, wmh_mph_type& wmh);
414 
415 // void read_att_map_mph ( float *attmap ); // read attenuation map from a file
416 
417 // char *itoa ( int n, char *s); // to convert integer to ascii
418 
419 void error_wmtools_SPECT_mph(int nerr, int ip, std::string txt); // error messages in wm_SPECT
420 
421 } // namespace SPECTUB_mph
422 
423 #endif //_WM_SPECT_H
int round(const float x)
Implements rounding of floating point numbers.
Definition: round.inl:59
NUMBER square(const NUMBER &x)
returns the square of a number, templated.
Definition: common.h:146
elemT sum(IterT start, IterT end, elemT init)
Compute the sum of a sequence using operator+=(), using an initial value.
Definition: more_algorithms.inl:52
Definition: PinholeSPECTUB_Tools.h:22