STIR  6.2.0
ProjDataInfoCylindrical.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2000 PARAPET partners
3  Copyright (C) 2000-2009, Hammersmith Imanet Ltd
4  Copyright (C) 2013, 2022 University College London
5  Copyright (C) 2013, Institute for Bioengineering of Catalonia
6  Copyright (C) 2016, University of Hull
7  This file is part of STIR.
8 
9  SPDX-License-Identifier: Apache-2.0 AND License-ref-PARAPET-license
10 
11  See STIR/LICENSE.txt for details
12 */
25 #ifndef __stir_ProjDataInfoCylindrical_H__
26 #define __stir_ProjDataInfoCylindrical_H__
27 
28 #include "stir/ProjDataInfo.h"
30 #include <utility>
31 #include <vector>
32 
33 START_NAMESPACE_STIR
34 
35 class Succeeded;
36 
47 // TODOdoc more
49 {
50 private:
51  typedef ProjDataInfo base_type;
53 
54 public:
56  typedef std::vector<std::pair<int, int>> RingNumPairs;
57 
61 
68  ProjDataInfoCylindrical(const shared_ptr<Scanner>& scanner_ptr,
69  const VectorWithOffset<int>& num_axial_poss_per_segment,
70  const VectorWithOffset<int>& min_ring_diff,
71  const VectorWithOffset<int>& max_ring_diff,
72  const int num_views,
73  const int num_tangential_poss);
74 
75  inline float get_tantheta(const Bin&) const override;
76 
77  inline float get_phi(const Bin&) const override;
78 
79  inline float get_t(const Bin&) const override;
80 
82 
88  inline float get_m(const Bin&) const override;
89 
90  void get_LOR(LORInAxialAndNoArcCorrSinogramCoordinates<float>& lor, const Bin& bin) const override;
91 #if 0
92  // KT disabled these as untested (and unused)
93 
97  void
98  get_LOR_as_two_points(CartesianCoordinate3D<float>& coord_1,
100  const Bin& bin) const;
101 
104  void
105  get_LOR_as_two_points_alt(CartesianCoordinate3D<float>& coord_1,
107  const int det1,
108  const int det2,
109  const int ring1,
110  const int ring2,
111  const int timing_pos) const;
112 #endif
113  void set_azimuthal_angle_offset(const float angle);
116  void set_azimuthal_angle_sampling(const float angle);
117 
118  // void set_axial_sampling(const float samp, int segment_num);
119 
121 
129  void set_num_views(const int new_num_views) override;
130 
131  void set_tof_mash_factor(const int new_num) override;
132 
134  inline float get_azimuthal_angle_offset() const;
136  inline float get_azimuthal_angle_sampling() const;
137  inline float get_sampling_in_t(const Bin&) const override;
138  inline float get_sampling_in_m(const Bin&) const override;
139 
141 
147  virtual inline float get_axial_sampling(int segment_num) const;
149 
150  virtual inline bool axial_sampling_is_uniform() const
151  {
152  return true;
153  }
154 
156  inline float get_average_ring_difference(int segment_num) const;
158  inline int get_min_ring_difference(int segment_num) const;
160  inline int get_max_ring_difference(int segment_num) const;
161 
163  void set_min_ring_difference(int min_ring_diff_v, int segment_num);
165  void set_max_ring_difference(int max_ring_diff_v, int segment_num);
166 
167  void set_num_axial_poss_per_segment(const VectorWithOffset<int>& num_axial_poss_per_segment) override;
168  void set_min_axial_pos_num(const int min_ax_pos_num, const int segment_num) override;
169  void set_max_axial_pos_num(const int max_ax_pos_num, const int segment_num) override;
170  void reduce_segment_range(const int min_segment_num, const int max_segment_num) override;
171 
173  inline void set_ring_radii_for_all_views(const VectorWithOffset<float>& new_ring_radius);
174 
176  inline VectorWithOffset<float> get_ring_radii_for_all_views() const;
177 
179  inline float get_ring_radius() const;
180 
181  inline float get_ring_radius(const int view_num) const;
183  inline float get_ring_spacing() const;
184 
186  void set_ring_spacing(float ring_spacing_v);
187 
189 
196  inline int get_view_mashing_factor() const;
197 
199 
202  inline Succeeded get_segment_num_for_ring_difference(int& segment_num, const int ring_diff) const;
203 
205 
220  inline Succeeded
221  get_segment_axial_pos_num_for_ring_pair(int& segment_num, int& axial_pos_num, const int ring1, const int ring2) const;
222 
224 
232  inline const RingNumPairs& get_all_ring_pairs_for_segment_axial_pos_num(const int segment_num, const int axial_pos_num) const;
234 
240  inline unsigned get_num_ring_pairs_for_segment_axial_pos_num(const int segment_num, const int axial_pos_num) const;
241 
243 
254  void get_ring_pair_for_segment_axial_pos_num(int& ring1, int& ring2, const int segment_num, const int axial_pos_num) const;
255 
256  std::string parameter_info() const override;
257 
258 protected:
260 
276 
277 protected:
278  bool blindly_equals(const root_type* const) const override = 0;
279 
280 private:
281  float azimuthal_angle_offset;
282  float azimuthal_angle_sampling;
283  VectorWithOffset<float> ring_radius;
284  float ring_spacing;
285  VectorWithOffset<int> min_ring_diff;
286  VectorWithOffset<int> max_ring_diff;
287 
288  /*
289  Next members have to be mutable as they can be modified by const member
290  functions. We need this because of the presence of set_min_ring_difference()
291  which invalidates these precalculated arrays.
292  If your compiler does not support mutable (and you don't want to upgrade
293  it to something more sensible), your best bet is to remove the
294  set_*ring_difference functions, and move the content of
295  initialise_ring_diff_arrays() to the constructor. (Not recommended!)
296  */
297 
299  mutable bool ring_diff_arrays_computed;
301  mutable VectorWithOffset<float> m_offset;
302 
304  mutable VectorWithOffset<int> ax_pos_num_offset;
306  mutable VectorWithOffset<int> ring_diff_to_segment_num;
308  mutable VectorWithOffset<VectorWithOffset<int>> segment_axial_pos_to_ring1_plus_ring2;
309 
311  void initialise_ring_diff_arrays() const;
312 
314 
315  inline void initialise_ring_diff_arrays_if_not_done_yet() const;
316 
317  inline int get_num_axial_poss_per_ring_inc(const int segment_num) const;
318 
320  mutable VectorWithOffset<VectorWithOffset<shared_ptr<RingNumPairs>>> segment_axial_pos_to_ring_pair;
321 
323  void allocate_segment_axial_pos_to_ring_pair() const;
324 
326 
327  void compute_segment_axial_pos_to_ring_pair(const int segment_num, const int axial_pos_num) const;
328 };
329 
330 END_NAMESPACE_STIR
331 
333 
334 #endif
virtual bool axial_sampling_is_uniform() const
Return if axial sampling makes sense.
Definition: ProjDataInfoCylindrical.h:150
Declaration of class stir::ProjDataInfo.
double angle(const BasicCoordinate< num_dimensions, coordT > &p1, const BasicCoordinate< num_dimensions, coordT > &p2)
compute angle between 2 directions
Definition: BasicCoordinate.inl:440
std::vector< std::pair< int, int > > RingNumPairs
Type used by get_all_ring_pairs_for_segment_axial_pos_num()
Definition: ProjDataInfoCylindrical.h:56
A class for storing coordinates and value of a single projection bin.
Definition: Bin.h:48
A class for LORs.
Definition: LORCoordinates.h:40
Implementation of inline functions of class stir::ProjDataInfoCylindrical.
projection data info for data corresponding to a &#39;cylindrical&#39; sampling.
Definition: ProjDataInfoCylindrical.h:48
An (abstract base) class that contains information on the projection data.
Definition: ProjDataInfo.h:69
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition: Succeeded.h:43
defines the stir::CartesianCoordinate3D<coordT> class
bool sampling_corresponds_to_physical_rings
a variable that is set if the data corresponds to physical rings in the scanner
Definition: ProjDataInfoCylindrical.h:275