Skip to content

Commit 468fb4a

Browse files
add make_detection_bin helpers
inverse of expand_detection_bin
1 parent e4ac367 commit 468fb4a

File tree

6 files changed

+116
-11
lines changed

6 files changed

+116
-11
lines changed

cpp/petsird_analysis.cpp

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -157,24 +157,29 @@ main(int argc, char const* argv[])
157157
// Note: just doing one module-type ATM
158158
for (auto& event : event_time_block.prompt_events[type_of_module_pair[0]][type_of_module_pair[1]])
159159
{
160-
const auto expanded_det_bin0
160+
const auto expanded_detection_bin0
161161
= petsird_helpers::expand_detection_bin(header.scanner, type_of_module_pair[0], event.detection_bins[0]);
162-
const auto expanded_det_bin1
162+
const auto expanded_detection_bin1
163163
= petsird_helpers::expand_detection_bin(header.scanner, type_of_module_pair[1], event.detection_bins[1]);
164-
energy_1 += energy_mid_points[expanded_det_bin0.energy_index];
165-
energy_2 += energy_mid_points[expanded_det_bin1.energy_index];
164+
165+
// TODO move this test to separate unit-tests
166+
assert(event.detection_bins[0]
167+
== petsird_helpers::make_detection_bin(header.scanner, type_of_module_pair[0], expanded_detection_bin0));
168+
169+
energy_1 += energy_mid_points[expanded_detection_bin0.energy_index];
170+
energy_2 += energy_mid_points[expanded_detection_bin1.energy_index];
166171

167172
if (print_events)
168173
{
169174
std::cout << "CoincidenceEvent(detectionBins=[" << event.detection_bins[0] << ", " << event.detection_bins[1]
170175
<< "], tofIdx=" << event.tof_idx << "])\n";
171176
std::cout << " "
172-
<< "[ExpandedDetectionBin(module=" << expanded_det_bin0.module_index << ", "
173-
<< "el=" << expanded_det_bin0.element_index << ", "
174-
<< "energy_index=" << expanded_det_bin0.energy_index
175-
<< "), ExpandedDetectionBin(module=" << expanded_det_bin1.module_index << ", "
176-
<< "el=" << expanded_det_bin1.element_index << ", "
177-
<< "energy_index=" << expanded_det_bin0.energy_index << ")]\n";
177+
<< "[ExpandedDetectionBin(module=" << expanded_detection_bin0.module_index << ", "
178+
<< "el=" << expanded_detection_bin0.element_index << ", "
179+
<< "energy_index=" << expanded_detection_bin0.energy_index
180+
<< "), ExpandedDetectionBin(module=" << expanded_detection_bin1.module_index << ", "
181+
<< "el=" << expanded_detection_bin1.element_index << ", "
182+
<< "energy_index=" << expanded_detection_bin0.energy_index << ")]\n";
178183
std::cout << " efficiency:"
179184
<< petsird_helpers::get_detection_efficiency(header.scanner, type_of_module_pair, event) << "\n";
180185
}

cpp/petsird_helpers.h

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ get_num_detection_bins(const ScannerInformation& scanner, const TypeOfModule& ty
5454
return det_els.transforms.size() * rep_module.transforms.size() * energy_bin_edges.NumberOfBins();
5555
}
5656

57+
//! Create a vector of ExpandedDetectionBins from a list/vector of DetectionBins
5758
template <class T>
5859
inline std::vector<ExpandedDetectionBin>
5960
expand_detection_bins(const ScannerInformation& scanner, const TypeOfModule& type_of_module, const T& list_of_detection_bins)
@@ -74,6 +75,7 @@ expand_detection_bins(const ScannerInformation& scanner, const TypeOfModule& typ
7475
return result;
7576
}
7677

78+
//! Expand a DetectionBin into a ExpandedDetectionBin
7779
inline ExpandedDetectionBin
7880
expand_detection_bin(const ScannerInformation& scanner, const TypeOfModule& type_of_module, const DetectionBin& detection_bin)
7981
{
@@ -83,6 +85,41 @@ expand_detection_bin(const ScannerInformation& scanner, const TypeOfModule& type
8385
return expanded_bins[0];
8486
}
8587

88+
//! Create a vector of DetectionBins from a list/vector of ExpandedDetectionBins
89+
template <class T>
90+
inline std::vector<DetectionBin>
91+
make_detection_bins(const ScannerInformation& scanner, const TypeOfModule& type_of_module,
92+
const T& list_of_expanded_detection_bins)
93+
{
94+
assert(type_of_module < scanner.scanner_geometry.replicated_modules.size());
95+
const auto& rep_module = scanner.scanner_geometry.replicated_modules[type_of_module];
96+
const auto& energy_bin_edges = scanner.event_energy_bin_edges[type_of_module];
97+
const auto num_en = energy_bin_edges.NumberOfBins();
98+
const auto num_el_per_module = rep_module.object.detecting_elements.transforms.size();
99+
100+
std::vector<DetectionBin> result;
101+
// TODO call reserve()
102+
for (auto bin : list_of_expanded_detection_bins)
103+
{
104+
// need to do static_cast to avoid compiler warning on narrowing from std::size_t to uint32_t
105+
const auto detection_bin
106+
= static_cast<DetectionBin>(bin.energy_index + (bin.element_index + bin.module_index * num_el_per_module) * num_en);
107+
result.push_back({ detection_bin });
108+
}
109+
return result;
110+
}
111+
112+
//! Create a DetectionBin from a ExpandedDetectionBin
113+
inline DetectionBin
114+
make_detection_bin(const ScannerInformation& scanner, const TypeOfModule& type_of_module,
115+
const ExpandedDetectionBin& expanded_detection_bin)
116+
{
117+
// TODO very inefficient, but avoid re-implementation of code above.
118+
std::vector<ExpandedDetectionBin> expanded_detection_bins{ expanded_detection_bin };
119+
const auto detection_bins = make_detection_bins(scanner, type_of_module, expanded_detection_bins);
120+
return detection_bins[0];
121+
}
122+
86123
inline float
87124
get_detection_efficiency(const ScannerInformation& scanner, const TypeOfModulePair& type_of_module_pair,
88125
const CoincidenceEvent& event)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
function detection_bin = make_detection_bin(scanner_geometry, type_of_module, detection_bin)
2+
% Find DetectionBin for a ExpandedDetectionBin
3+
4+
arguments
5+
scanner_geometry (1,1) petsird.ScannerGeometry
6+
type_of_module (1,1) petsird.TypeOfModule
7+
expanded_detection_bin (1,1) petsird.ExpandedDetectionBin
8+
end
9+
10+
rep_module = scanner_geometry.replicated_modules(type_of_module);
11+
num_el_per_module = length(rep_module.object.detecting_elements.transforms);
12+
energy_bin_edges = rep_module.event_energy_bin_edges(type_of_module);
13+
num_en = energy_bin_edges.number_of_bins();
14+
% use shorter name
15+
bin = expanded_detection_bin;
16+
detection_bin = petsird.DetectionBin(bin.energy_index + (bin.element_index + bin.module_index * num_el_per_module) * num_en);
17+
18+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
function detection_bins = make_detection_bins(scanner, type_of_module, expanded_detection_bins)
2+
% Find DetectionBin for a list of ExpandedDetectionBins
3+
4+
arguments
5+
scanner_geometry (1,1) petsird.ScannerInformation
6+
type_of_module (1,1) petsird.TypeOfModule
7+
expanded_detection_bins (:,1) petsird.ExpandedDetectionBin
8+
end
9+
10+
% TODO slow but avoids re-implementation
11+
detection_bins = arrayfun(@(bin) make_detection_bin(scanner, type_of_module, bin)), expanded_detection_bins);
12+
13+
end

python/petsird/helpers/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,33 @@ def expand_detection_bin(
5656
return expand_detection_bins(scanner, type_of_module, [detection_bin])[0]
5757

5858

59+
def make_detection_bins(
60+
scanner: petsird.ScannerInformation, type_of_module: petsird.TypeOfModule,
61+
expanded_detection_bins: typing.Iterable[petsird.ExpandedDetectionBin]
62+
) -> list[petsird.ExpandedDetectionBin]:
63+
"""Find DetectionBin for a list of expanded_detection_bins"""
64+
rep_module = scanner.scanner_geometry.replicated_modules[type_of_module]
65+
num_el_per_module = len(rep_module.object.detecting_elements.transforms)
66+
energy_bin_edges = scanner.event_energy_bin_edges[type_of_module]
67+
num_en = energy_bin_edges.number_of_bins()
68+
69+
return [
70+
(bin.energy_index +
71+
(bin.element_index + bin.module_index * num_el_per_module) * num_en)
72+
for bin in expanded_detection_bins
73+
]
74+
75+
76+
def make_detection_bin(
77+
scanner: petsird.ScannerInformation, type_of_module: petsird.TypeOfModule,
78+
expanded_detection_bin: petsird.DetectionBin
79+
) -> petsird.ExpandedDetectionBin:
80+
"""Find DetectionBin for an expanded_detection_bin"""
81+
# TODO probably slow implementation, but avoids re-implementation for now
82+
return make_detection_bins(scanner, type_of_module,
83+
[expanded_detection_bin])[0]
84+
85+
5986
def get_detection_efficiency(scanner: petsird.ScannerInformation,
6087
type_of_module_pair: petsird.TypeOfModulePair,
6188
event: petsird.CoincidenceEvent) -> float:

python/petsird/helpers/analysis.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
import petsird
1010
from petsird.helpers import (expand_detection_bin, get_detection_efficiency,
11-
get_num_det_els)
11+
get_num_det_els, make_detection_bin)
1212

1313

1414
def parserCreator():
@@ -103,6 +103,11 @@ def parserCreator():
103103
scanner, type_of_module_pair[1],
104104
event.detection_bins[1])
105105

106+
# TODO move this test to separate unit-tests
107+
assert event.detection_bins[0] == make_detection_bin(
108+
scanner, type_of_module_pair[0],
109+
expanded_detection_bin0)
110+
106111
energy_1 += energy_mid_points[
107112
expanded_detection_bin0.energy_index]
108113
energy_2 += energy_mid_points[

0 commit comments

Comments
 (0)