STIR 6.4.0
DataSymmetriesForDensels_PET_CartesianGrid.inl
Go to the documentation of this file.
1//
2//
11/*
12 Copyright (C) 2001- 2002, IRSL
13 See STIR/LICENSE.txt for details
14*/
17
18#include <algorithm>
19
20START_NAMESPACE_STIR
21
22#if 0
23const DiscretisedDensityOnCartesianGrid<3,float> *
24DataSymmetriesForDensels_PET_CartesianGrid::
25cartesian_grid_info_ptr() const
26{
27 // we can use static_cast here, as the constructor already checked that it is type-safe
28 return static_cast<const DiscretisedDensityOnCartesianGrid<3,float> *>
29 (image_info_ptr.get());
30}
31#endif
32
33float
35{
36 return static_cast<float>(num_planes_per_axial_pos[segment_num]);
37}
38
39float
41{
42 return static_cast<float>(num_planes_per_scanner_ring);
43}
44
45float
46DataSymmetriesForDensels_PET_CartesianGrid::get_axial_pos_to_z_offset(const int segment_num) const
47{
48 return axial_pos_to_z_offset[segment_num];
49}
50
51SymmetryOperation*
52DataSymmetriesForDensels_PET_CartesianGrid::find_sym_op_general_densel(const int z, const int y, const int x) const
53{
54 const int z_shift = z - (z % num_independent_planes);
55 // TODO next shift might depend on the segment.
56 // Solving this will require removing the axial_pos_num_shift argument from the symmetry operations
57 const int axial_pos_num_shift = z_shift / num_independent_planes;
58 const int view180 = num_views;
59
60 if (x >= y && y >= 0) // [0,45]
61 {
62 if (z_shift == 0)
63 return new TrivialSymmetryOperation();
64 else
65 return new SymmetryOperation_PET_CartesianGrid_z_shift(axial_pos_num_shift, z_shift);
66 }
67 else if (x >= 0 && y > x) // [ 45, 90]
68 return new SymmetryOperation_PET_CartesianGrid_swap_xy_yx(view180, axial_pos_num_shift, z_shift);
69 else if (x < 0 && y > -x) //[90, 135 ]
70 return new SymmetryOperation_PET_CartesianGrid_swap_xmy_yx(view180, axial_pos_num_shift, z_shift);
71 else if (x < 0 && y >= 0) // [ 135, 180]
72 {
73 assert(y <= -x);
74 return new SymmetryOperation_PET_CartesianGrid_swap_xmx(view180, axial_pos_num_shift, z_shift);
75 }
76 else if (x < 0 && y <= 0 && -y <= -x) // [ 180, 225]
77 return new SymmetryOperation_PET_CartesianGrid_swap_xmx_ymy(view180, axial_pos_num_shift, z_shift);
78 else if (x <= 0 && y < 0) // [ 225, 270]
79 {
80 assert(-y > -x);
81 return new SymmetryOperation_PET_CartesianGrid_swap_xmy_ymx(view180, axial_pos_num_shift, z_shift);
82 }
83 else if (x > 0 && -y > x) // [ 270, 315]
84 return new SymmetryOperation_PET_CartesianGrid_swap_xy_ymx(view180, axial_pos_num_shift, z_shift);
85 else // [ 315, 360]
86 {
87 assert(x > 0 && y < 0 && -y <= x);
88 return new SymmetryOperation_PET_CartesianGrid_swap_ymy(view180, axial_pos_num_shift, z_shift);
89 }
90}
91
92bool
94{
95 int& z = c[1];
96 int& y = c[2];
97 int& x = c[3];
98 if (z == z % num_independent_planes && x >= 0 && y >= 0 && y <= x)
99 return false;
100 z = z % num_independent_planes;
101 if (x < 0)
102 x = -x;
103 if (y < 0)
104 y = -y;
105 if (y > x)
106 std::swap(x, y);
107 return true;
108}
109
110// TODO, optimise
111unique_ptr<SymmetryOperation>
113{
114 unique_ptr<SymmetryOperation> sym_op(find_sym_op_general_densel(c[1], c[2], c[3]));
115#ifndef NDEBUG
116 const Densel copy_original = c;
117#endif
119#ifndef NDEBUG
120 Densel copy = c;
121 sym_op->transform_image_coordinates(copy);
122 assert(copy_original == copy);
123#endif
124 return sym_op;
125}
126
127int
129{
130 int num = 1;
131 if (b[3] != 0)
132 num *= 2;
133 if (b[2] != 0)
134 num *= 2;
135 if (abs(b[3]) != abs(b[2]))
136 num *= 2;
137
138 num *= static_cast<int>(ceil(static_cast<float>(num_planes) / num_independent_planes));
139 return num;
140}
141
142void
144{
145#ifndef NDEBUG
146 {
147 Densel dcopy = d;
148 assert(find_basic_densel(dcopy));
149 }
150#endif
151 v.reserve(num_related_densels(d));
152 v.resize(0);
153
154 const int x = d[3];
155 const int y = d[2];
156 const int basic_z = d[1];
157 {
158 for (int z = basic_z; z < num_planes; z += num_independent_planes)
159 v.push_back(Densel(z, y, x));
160 }
161 if (x > 0)
162 {
163 for (int z = basic_z; z < num_planes; z += num_independent_planes)
164 v.push_back(Densel(z, y, -x));
165 }
166 if (y > 0)
167 {
168 for (int z = basic_z; z < num_planes; z += num_independent_planes)
169 v.push_back(Densel(z, -y, x));
170 }
171 if (x > 0 && y > 0)
172 {
173 for (int z = basic_z; z < num_planes; z += num_independent_planes)
174 v.push_back(Densel(z, -y, -x));
175 }
176 if (x != y)
177 {
178 {
179 for (int z = basic_z; z < num_planes; z += num_independent_planes)
180 v.push_back(Densel(z, x, y));
181 }
182 if (x > 0)
183 {
184 for (int z = basic_z; z < num_planes; z += num_independent_planes)
185 v.push_back(Densel(z, x, -y));
186 }
187 if (y > 0)
188 {
189 for (int z = basic_z; z < num_planes; z += num_independent_planes)
190 v.push_back(Densel(z, -x, y));
191 }
192 if (x > 0 && y > 0)
193 {
194 for (int z = basic_z; z < num_planes; z += num_independent_planes)
195 v.push_back(Densel(z, -x, -y));
196 }
197 }
198
199 assert(v.size() == static_cast<unsigned>(num_related_densels(d)));
200}
201
202END_NAMESPACE_STIR
Declaration of class stir::ProjDataInfoCylindrical.
Declaration of all symmetry classes for PET (cylindrical) scanners and cartesian images.
unique_ptr< SymmetryOperation > find_symmetry_operation_from_basic_densel(Densel &) const override
given an arbitrary Densel 'b', find the basic Densel
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:112
float get_num_planes_per_axial_pos(const int segment_num) const
find correspondence between axial_pos_num and image coordinates
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:34
bool find_basic_densel(Densel &b) const override
given an arbitrary Densel 'b', find the basic Densel
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:93
void get_related_densels(std::vector< Densel > &, const Densel &b) const override
fills in a vector with all the Densels that are related to 'b' (including itself)
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:143
int num_related_densels(const Densel &b) const override
returns the number of Densels related to 'b'
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:128
float get_num_planes_per_scanner_ring() const
find out how many image planes there are for every scanner ring
Definition DataSymmetriesForDensels_PET_CartesianGrid.inl:40
Coordinate3D< int > Densel
a typedef used for an element of a DiscretisedDensity
Definition Densel.h:36