STIR 6.4.0
DetectorCoordinateMap.h
Go to the documentation of this file.
1/*
2 Copyright 2015, 2017 ETH Zurich, Institute of Particle Physics
3 Copyright 2020 Positrigo AG, Zurich
4 Copyright (C) 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
22
23#include <fstream>
24#include <string>
25#include <vector>
26#include <random>
27#include <map>
28#include <boost/algorithm/string.hpp>
29#include <boost/unordered_map.hpp>
30#ifdef STIR_OPENMP
31# include <omp.h>
32#endif
33
36
37#ifndef __stir_DetectorCoordinateMap_H__
38# define __stir_DetectorCoordinateMap_H__
39
40START_NAMESPACE_STIR
41
42class Succeeded;
43
51{
52 struct ihash
53 {
54 std::size_t operator()(stir::DetectionPosition<> const& detpos) const
55 {
56 std::size_t seed = 0;
57 boost::hash_combine(seed, detpos.axial_coord());
58 boost::hash_combine(seed, detpos.radial_coord());
59 boost::hash_combine(seed, detpos.tangential_coord());
60 return seed;
61 }
62 };
63
64public:
65 typedef boost::unordered_map<stir::DetectionPosition<>, stir::CartesianCoordinate3D<float>, ihash> det_pos_to_coord_type;
66 typedef boost::unordered_map<stir::DetectionPosition<>, stir::DetectionPosition<>, ihash> unordered_to_ordered_det_pos_type;
67
69 DetectorCoordinateMap(const std::string& filename, double sigma = 0.0)
71 {
73 }
74
75 DetectorCoordinateMap(const det_pos_to_coord_type& coord_map, double sigma = 0.0)
77 {
78 set_detector_map(coord_map);
79 }
80
82 void read_detectormap_from_file(const std::string& filename);
84
85 void set_detector_map(const det_pos_to_coord_type& coord_map);
86
87 stir::DetectionPosition<> get_det_pos_for_index(const stir::DetectionPosition<>& index) const
88 {
89 return input_index_to_det_pos.at(index);
90 }
93 {
94 auto coord = det_pos_to_coord.at(det_pos);
95 if (sigma == 0.0)
96 return coord;
97
98# ifdef STIR_OPENMP
99 auto thread_id = omp_get_thread_num();
100# else
101 auto thread_id = 0;
102# endif
103
104 coord.x() += static_cast<float>(distributions[thread_id](generators[thread_id]));
105 coord.y() += static_cast<float>(distributions[thread_id](generators[thread_id]));
106 coord.z() += static_cast<float>(distributions[thread_id](generators[thread_id]));
107 return coord;
108 }
109
111 {
112 return get_coordinate_for_det_pos(get_det_pos_for_index(index));
113 }
114
115 Succeeded find_detection_position_given_cartesian_coordinate(DetectionPosition<>& det_pos,
116 const CartesianCoordinate3D<float>& cart_coord) const;
117
118 unsigned get_num_tangential_coords() const { return num_tangential_coords; }
119 unsigned get_num_axial_coords() const { return num_axial_coords; }
120 unsigned get_num_radial_coords() const { return num_radial_coords; }
121
122protected:
123 explicit DetectorCoordinateMap(double sigma = 0.0)
124 : sigma(sigma)
125 {
126 if (sigma == 0.0)
127 return;
128# ifdef STIR_OPENMP
129 generators.resize(omp_get_max_threads());
130 distributions.resize(omp_get_max_threads());
131 for (auto& distribution : distributions)
132 distribution = std::normal_distribution<double>(0.0, sigma);
133# else
134 generators.resize(1);
135 distributions.resize(1);
136 distributions[0] = std::normal_distribution<double>(0.0, sigma);
137# endif
138 }
139
140private:
141 unsigned num_tangential_coords;
142 unsigned num_axial_coords;
143 unsigned num_radial_coords;
144 unordered_to_ordered_det_pos_type input_index_to_det_pos;
145 det_pos_to_coord_type det_pos_to_coord;
146 std::map<stir::CartesianCoordinate3D<float>, stir::DetectionPosition<>>
147 detection_position_map_given_cartesian_coord_keys_3_decimal;
148 std::map<stir::CartesianCoordinate3D<float>, stir::DetectionPosition<>>
149 detection_position_map_given_cartesian_coord_keys_2_decimal;
150
151 const double sigma;
152 mutable std::vector<std::default_random_engine> generators;
153 mutable std::vector<std::normal_distribution<double>> distributions;
154
155 static det_pos_to_coord_type read_detectormap_from_file_help(const std::string& crystal_map_name);
156};
157
158END_NAMESPACE_STIR
159#endif
defines the stir::CartesianCoordinate3D<coordT> class
Declaration of class stir::DetectionPosition.
coordT & at(const int d)
Return value at index t (which is 1-based), but with range checking (throws std::out_of_range)
Definition BasicCoordinate.inl:90
a templated class for 3-dimensional coordinates.
Definition CartesianCoordinate3D.h:53
A class for storing coordinates of a detection.
Definition DetectionPosition.h:61
DetectorCoordinateMap(const std::string &filename, double sigma=0.0)
Constructor calls read_detectormap_from_file( filename ).
Definition DetectorCoordinateMap.h:69
stir::CartesianCoordinate3D< float > get_coordinate_for_det_pos(const stir::DetectionPosition<> &det_pos) const
Returns a cartesian coordinate given a detection position.
Definition DetectorCoordinateMap.h:92
stir::CartesianCoordinate3D< float > get_coordinate_for_index(const stir::DetectionPosition<> &index) const
Returns a cartesian coordinate given an (unsorted) index.
Definition DetectorCoordinateMap.h:110
void read_detectormap_from_file(const std::string &filename)
Reads map from file and stores it.
Definition DetectorCoordinateMap.cxx:164
void set_detector_map(const det_pos_to_coord_type &coord_map)
stores the map
Definition DetectorCoordinateMap.cxx:74
DetectorCoordinateMap(const det_pos_to_coord_type &coord_map, double sigma=0.0)
Constructor calls set_detector_map(coord_map).
Definition DetectorCoordinateMap.h:75
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44