STIR 6.4.0
ProjDataInfoCylindricalNoArcCorr.inl
Go to the documentation of this file.
1//
2//
14/*
15 Copyright (C) 2000- 2005, Hammersmith Imanet Ltd
16 This file is part of STIR.
17
18 SPDX-License-Identifier: Apache-2.0
19
20 See STIR/LICENSE.txt for details
21*/
22
23#include "stir/Bin.h"
24#include "stir/Succeeded.h"
25#include "stir/round.h"
26#include <math.h>
27
28START_NAMESPACE_STIR
29
30void
31ProjDataInfoCylindricalNoArcCorr::initialise_uncompressed_view_tangpos_to_det1det2_if_not_done_yet() const
32{
33 // for efficiency reasons, use "Double-Checked-Locking(DCL) pattern" with OpenMP atomic operation
34 // OpenMP v3.1 or later required
35 // thanks to yohjp:
36 // http://stackoverflow.com/questions/27975737/how-to-handle-cached-data-structures-with-multi-threading-e-g-openmp
37#if defined(STIR_OPENMP) && _OPENMP >= 201012
38 bool initialised;
39# pragma omp atomic read
40 initialised = uncompressed_view_tangpos_to_det1det2_initialised;
41
42 if (!initialised)
43#endif
44 {
45#if defined(STIR_OPENMP)
46# pragma omp critical(PROJDATAINFOCYLINDRICALNOARCCORR_VIEWTANGPOS_TO_DETS)
47#endif
48 {
49 if (!uncompressed_view_tangpos_to_det1det2_initialised)
50 initialise_uncompressed_view_tangpos_to_det1det2();
51 }
52 }
53}
54
55void
56ProjDataInfoCylindricalNoArcCorr::initialise_det1det2_to_uncompressed_view_tangpos_if_not_done_yet() const
57{
58 // as above
59#if defined(STIR_OPENMP) && _OPENMP >= 201012
60 bool initialised;
61# pragma omp atomic read
62 initialised = det1det2_to_uncompressed_view_tangpos_initialised;
63
64 if (!initialised)
65#endif
66 {
67#if defined(STIR_OPENMP)
68# pragma omp critical(PROJDATAINFOCYLINDRICALNOARCCORR_DETS_TO_VIEWTANGPOS)
69#endif
70 {
71 if (!det1det2_to_uncompressed_view_tangpos_initialised)
72 initialise_det1det2_to_uncompressed_view_tangpos();
73 }
74 }
75}
76
77float
79{
80 return ring_radius * sin(bin.tangential_pos_num() * angular_increment);
81}
82
83float
85{
86 return angular_increment;
87}
88
89void
91 int& det2_num,
92 const int view_num,
93 const int tang_pos_num) const
94{
95 assert(get_view_mashing_factor() == 1);
96 this->initialise_uncompressed_view_tangpos_to_det1det2_if_not_done_yet();
97
98 det1_num = uncompressed_view_tangpos_to_det1det2[view_num][tang_pos_num].det1_num;
99 det2_num = uncompressed_view_tangpos_to_det1det2[view_num][tang_pos_num].det2_num;
100}
101
102bool
104 int& tang_pos_num,
105 const int det1_num,
106 const int det2_num) const
107{
108 assert(det1_num != det2_num);
109 this->initialise_det1det2_to_uncompressed_view_tangpos_if_not_done_yet();
110
111 view_num = det1det2_to_uncompressed_view_tangpos[det1_num][det2_num].view_num / get_view_mashing_factor();
112 tang_pos_num = det1det2_to_uncompressed_view_tangpos[det1_num][det2_num].tang_pos_num;
113 return det1det2_to_uncompressed_view_tangpos[det1_num][det2_num].swap_detectors;
114}
115
117ProjDataInfoCylindricalNoArcCorr::get_bin_for_det_pair(
118 Bin& bin, const int det_num1, const int ring_num1, const int det_num2, const int ring_num2, const int timing_pos_num) const
119{
120 if (get_view_tangential_pos_num_for_det_num_pair(bin.view_num(), bin.tangential_pos_num(), det_num1, det_num2))
121 {
122 bin.timing_pos_num() = timing_pos_num;
123 return get_segment_axial_pos_num_for_ring_pair(bin.segment_num(), bin.axial_pos_num(), ring_num1, ring_num2);
124 }
125 else
126 {
127 bin.timing_pos_num() = -timing_pos_num;
128 return get_segment_axial_pos_num_for_ring_pair(bin.segment_num(), bin.axial_pos_num(), ring_num2, ring_num1);
129 }
130}
131
132Succeeded
134{
135 return get_bin_for_det_pair(bin,
136 dp.pos1().tangential_coord(),
137 dp.pos1().axial_coord(),
138 dp.pos2().tangential_coord(),
139 dp.pos2().axial_coord(),
140 this->get_tof_mash_factor() == 0
141 ? 0 // use timing_pos==0 in the nonTOF case
142 : stir::round((float)dp.timing_pos() / this->get_tof_mash_factor()));
143}
144void
146 int& det_num1, int& ring_num1, int& det_num2, int& ring_num2, const Bin& bin) const
147{
148 // if (bin.timing_pos_num()>=0)
149 // {
151 get_ring_pair_for_segment_axial_pos_num(ring_num1, ring_num2, bin.segment_num(), bin.axial_pos_num());
152 //}
153 // else
154 //{
155 // get_det_num_pair_for_view_tangential_pos_num(det_num2, det_num1, bin.view_num(), bin.tangential_pos_num());
156 // get_ring_pair_for_segment_axial_pos_num( ring_num2, ring_num1, bin.segment_num(), bin.axial_pos_num());
157 // }
158}
159
160void
162{
163 // This is a bit complicated as DetectionPositionPair<>::timing_pos() was an unsigned int at some point,
164 // while Bin uses an int. So swap detectors around.
165
166 // lousy work around because types don't match (short/int). TODO remove!
167 int t1, a1, t2, a2;
168 get_det_pair_for_bin(t1, a1, t2, a2, bin);
169 if (bin.timing_pos_num() >= 0)
170 {
171 dp.pos1().tangential_coord() = t1;
172 dp.pos1().axial_coord() = a1;
173 dp.pos2().tangential_coord() = t2;
174 dp.pos2().axial_coord() = a2;
175 }
176 else
177 {
178 dp.pos1().tangential_coord() = t2;
179 dp.pos1().axial_coord() = a2;
180 dp.pos2().tangential_coord() = t1;
181 dp.pos2().axial_coord() = a1;
182 }
183
184 dp.timing_pos() = std::abs(bin.timing_pos_num()) * this->get_tof_mash_factor();
185}
186
187END_NAMESPACE_STIR
Declaration of class stir::Bin.
Declaration of class stir::Succeeded.
A class for storing coordinates and value of a single projection bin.
Definition Bin.h:49
int tangential_pos_num() const
get tangential position number
Definition Bin.inl:76
int axial_pos_num() const
get axial position number
Definition Bin.inl:70
A class for storing 2 coordinates-sets of a detection, together with a timing-position index (for TOF...
Definition DetectionPositionPair.h:41
void get_det_num_pair_for_view_tangential_pos_num(int &det1_num, int &det2_num, const int view_num, const int tang_pos_num) const
This routine gets det_num1 and det_num2.
Definition ProjDataInfoCylindricalNoArcCorr.inl:90
void get_det_pair_for_bin(int &det_num1, int &ring_num1, int &det_num2, int &ring_num2, const Bin &bin) const
This routine gets the detector pair corresponding to a bin.
Definition ProjDataInfoCylindricalNoArcCorr.inl:145
bool get_view_tangential_pos_num_for_det_num_pair(int &view_num, int &tang_pos_num, const int det1_num, const int det2_num) const
This gets view_num and tang_pos_num for a particular detector pair.
Definition ProjDataInfoCylindricalNoArcCorr.inl:103
void get_det_pos_pair_for_bin(DetectionPositionPair<> &, const Bin &) const
This routine gets the detector pair corresponding to a bin.
Definition ProjDataInfoCylindricalNoArcCorr.inl:161
Succeeded get_bin_for_det_pos_pair(Bin &, const DetectionPositionPair<> &) const
This gets Bin coordinates for a particular detector pair.
Definition ProjDataInfoCylindricalNoArcCorr.inl:133
float get_angular_increment() const
Gets angular increment (in radians)
Definition ProjDataInfoCylindricalNoArcCorr.inl:84
float get_s(const Bin &) const override
Gets s coordinate in mm.
Definition ProjDataInfoCylindricalNoArcCorr.inl:78
virtual int get_view_mashing_factor() const
Get the mashing factor, i.e. how many 'original' views are combined.
Definition ProjDataInfoCylindrical.inl:207
void get_ring_pair_for_segment_axial_pos_num(int &ring1, int &ring2, const int segment_num, const int axial_pos_num) const
Find a ring pair that contributes to a segment and axial position.
Definition ProjDataInfoCylindrical.cxx:336
int get_tof_mash_factor() const
Get TOF mash factor.
Definition ProjDataInfo.inl:114
int segment_num() const
get segment number for const objects
Definition SegmentIndices.inl:32
int timing_pos_num() const
get TOF index for const objects
Definition SegmentIndices.inl:44
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
int view_num() const
get view number for const objects
Definition ViewgramIndices.inl:36
int round(const float x)
Implements rounding of floating point numbers.
Definition round.inl:59
Declaration of the stir::round functions.