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