STIR 6.4.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
21namespace SPECTUB_mph
22{
23
24//::: structures ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
25
26//.....structure for distribution function information
27
28typedef 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
55typedef 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
97typedef 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
112typedef 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
137typedef 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
148typedef 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
160typedef 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
198typedef 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
228typedef 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
271typedef 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
289typedef 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
316typedef 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
326typedef 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
345typedef 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
355typedef 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
384void wm_alloc(const int* Nitems, wm_da_type& wm, const wmh_mph_type& wmh); // allocate wm
385
386void read_prj_params_mph(wmh_mph_type& wmh); // read ring parameters from a file
387
388void read_coll_params_mph(wmh_mph_type& wmh); // read collimator parameters from a file
389
390// void which_hole();
391
392void fill_pcf(const wmh_mph_type& wmh, pcf_type& pcf); // fill precalculated functions
393
394void calc_cumsum(discrf2d_type* f);
395
396void 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
400void 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
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
NUMBER square(const NUMBER &x)
returns the square of a number, templated.
Definition common.h:154
int round(const float x)
Implements rounding of floating point numbers.
Definition round.inl:59