STIR  6.2.0
CListRecordSAFIR.h
Go to the documentation of this file.
1 /* CListRecordSAFIR.h
2 
3  Coincidence Event Class for SAFIR: Header File
4 
5  Copyright 2015 ETH Zurich, Institute of Particle Physics
6  Copyright 2017 ETH Zurich, Institute of Particle Physics and Astrophysics
7  Copyright 2020, 2022 Positrigo AG, Zurich
8 
9  Licensed under the Apache License, Version 2.0 (the "License");
10  you may not use this file except in compliance with the License.
11  You may obtain a copy of the License at
12 
13  http://www.apache.org/licenses/LICENSE-2.0
14 
15  Unless required by applicable law or agreed to in writing, software
16  distributed under the License is distributed on an "AS IS" BASIS,
17  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  See the License for the specific language governing permissions and
19  limitations under the License.
20 
21  */
22 
34 #ifndef __stir_listmode_CListRecordSAFIR_H__
35 #define __stir_listmode_CListRecordSAFIR_H__
36 
37 #include <random>
38 
41 #include "stir/Succeeded.h"
42 #include "stir/ByteOrder.h"
43 #include "stir/ByteOrderDefine.h"
44 
45 #include "boost/static_assert.hpp"
46 #include "boost/cstdint.hpp"
47 
49 #include "boost/make_shared.hpp"
50 
51 START_NAMESPACE_STIR
52 
71 template <class Derived>
73 {
74 public:
78  inline CListEventSAFIR() {}
79 
81  inline LORAs2Points<float> get_LOR() const override;
82 
84  inline void get_bin(Bin& bin, const ProjDataInfo& proj_data_info) const override;
85 
87 
91  inline bool is_valid_template(const ProjDataInfo&) const override { return true; }
92 
94  inline bool is_prompt() const override { return !(static_cast<const Derived*>(this)->is_prompt()); }
96 
97  inline void set_map_sptr(shared_ptr<const DetectorCoordinateMap> new_map_sptr) { map_sptr = new_map_sptr; }
100  inline void set_scanner_sptr(shared_ptr<const Scanner> new_scanner_sptr) { scanner_sptr = new_scanner_sptr; }
101 
102 private:
103  shared_ptr<const DetectorCoordinateMap> map_sptr;
104  shared_ptr<const Scanner> scanner_sptr;
105 
106  const DetectorCoordinateMap& map_to_use() const { return map_sptr ? *map_sptr : *this->scanner_sptr->get_detector_map_sptr(); }
107 };
108 
110 
112 {
113 public:
115  inline void get_detection_position_pair(DetectionPositionPair<>& det_pos_pair);
116 
118  inline bool is_prompt() const { return !isDelayed; }
119 
121  inline bool is_time() const { return type; }
122 
124  inline Succeeded set_prompt(const bool prompt = true)
125  {
126  isDelayed = !prompt;
127  return Succeeded::yes;
128  }
129 
130 private:
131 #if STIRIsNativeByteOrderBigEndian
132  unsigned type : 1;
133  unsigned isDelayed : 1;
134  unsigned reserved : 6;
135  unsigned layerB : 4;
136  unsigned layerA : 4;
137  unsigned detB : 16;
138  unsigned detA : 16;
139  unsigned ringB : 8;
140  unsigned ringA : 8;
141 #else
142  unsigned ringA : 8;
143  unsigned ringB : 8;
144  unsigned detA : 16;
145  unsigned detB : 16;
146  unsigned layerA : 4;
147  unsigned layerB : 4;
148  unsigned reserved : 6;
149  unsigned isDelayed : 1;
150  unsigned type : 1;
151 #endif
152 };
153 
155 
157 {
158 public:
160  inline void get_detection_position_pair(DetectionPositionPair<>& det_pos_pair);
161 
163  inline bool is_prompt() const { return !isDelayed; }
164 
166  inline bool is_time() const { return type; }
167 
169  inline Succeeded set_prompt(const bool prompt = true)
170  {
171  isDelayed = !prompt;
172  return Succeeded::yes;
173  }
174 
175 private:
176 #if STIRIsNativeByteOrderBigEndian
177  unsigned type : 1;
178  unsigned isDelayed : 1;
179  unsigned reserved : 8;
180  unsigned layerB : 3;
181  unsigned layerA : 3;
182  unsigned detB : 16;
183  unsigned detA : 16;
184  unsigned ringB : 8;
185  unsigned ringA : 8;
186 #else
187  unsigned ringA : 8;
188  unsigned ringB : 8;
189  unsigned detA : 16;
190  unsigned detB : 16;
191  unsigned layerA : 3;
192  unsigned layerB : 3;
193  unsigned reserved : 8;
194  unsigned isDelayed : 1;
195  unsigned type : 1;
196 #endif
197 };
198 
200 
202 {
203 public:
204  inline unsigned long get_time_in_millisecs() const { return static_cast<unsigned long>(time); }
205  inline Succeeded set_time_in_millisecs(const unsigned long time_in_millisecs)
206  {
207  time = ((boost::uint64_t(1) << 49) - 1) & static_cast<boost::uint64_t>(time_in_millisecs);
208  return Succeeded::yes;
209  }
210  inline bool is_time() const { return type; }
211 
212 private:
213 #if STIRIsNativeByteOrderBigEndian
214  boost::uint64_t type : 1;
215  boost::uint64_t reserved : 15;
216  boost::uint64_t time : 48;
217 #else
218  boost::uint64_t time : 48;
219  boost::uint64_t reserved : 15;
220  boost::uint64_t type : 1;
221 #endif
222 };
223 
225 
226 template <class DataType>
227 class CListRecordSAFIR : public CListRecord, public ListTime, public CListEventSAFIR<CListRecordSAFIR<DataType>>
228 {
229 public:
231  DataType get_data() const { return this->event_data; }
232 
235  {}
236 
237  ~CListRecordSAFIR() override {}
238 
239  bool is_time() const override { return time_data.is_time(); }
240 
241  bool is_event() const override { return !time_data.is_time(); }
242 
243  CListEvent& event() override { return *this; }
244 
245  const CListEvent& event() const override { return *this; }
246 
247  virtual CListEventSAFIR<CListRecordSAFIR<DataType>>& event_SAFIR() { return *this; }
248 
249  virtual const CListEventSAFIR<CListRecordSAFIR<DataType>>& event_SAFIR() const { return *this; }
250 
251  ListTime& time() override { return *this; }
252 
253  const ListTime& time() const override { return *this; }
254 
255  virtual bool operator==(const CListRecord& e2) const
256  {
257  return dynamic_cast<CListRecordSAFIR<DataType> const*>(&e2) != 0
258  && raw == static_cast<CListRecordSAFIR<DataType> const&>(e2).raw;
259  }
260 
261  inline unsigned long get_time_in_millisecs() const override { return time_data.get_time_in_millisecs(); }
262 
263  inline Succeeded set_time_in_millisecs(const unsigned long time_in_millisecs) override
264  {
265  return time_data.set_time_in_millisecs(time_in_millisecs);
266  }
267 
268  inline bool is_prompt() const override { return event_data.is_prompt(); }
269 
270  Succeeded init_from_data_ptr(const char* const data_ptr, const std::size_t size_of_record, const bool do_byte_swap)
271  {
272  assert(size_of_record >= 8);
273  std::copy(data_ptr, data_ptr + 8, reinterpret_cast<char*>(&raw)); // TODO necessary for operator==
274  if (do_byte_swap)
275  ByteOrder::swap_order(raw);
276  return Succeeded::yes;
277  }
278 
279  std::size_t size_of_record_at_ptr(const char* const /*data_ptr*/, const std::size_t /*size*/, const bool /*do_byte_swap*/) const
280  {
281  return 8;
282  }
283 
284 private:
285  // use C++ union to save data, you can only use one at a time,
286  // but compiler will not check which one was used!
287  // Be careful not to read event data from time record and vice versa!!
288  // However, this is used as a feature if comparing events over the 'raw' type.
289  union
290  {
291  DataType event_data;
292  CListTimeDataSAFIR time_data;
293  boost::int64_t raw;
294  };
295  BOOST_STATIC_ASSERT(sizeof(boost::uint64_t) == 8);
296  BOOST_STATIC_ASSERT(sizeof(DataType) == 8);
297  BOOST_STATIC_ASSERT(sizeof(CListTimeDataSAFIR) == 8);
298 };
299 
300 END_NAMESPACE_STIR
301 
302 #include "CListRecordSAFIR.inl"
303 
304 #endif
Class for record with coincidence data using NeuroLF bitfield definition.
Definition: CListRecordSAFIR.h:156
This file declares the stir::ByteOrder class.
Declaration of class stir::Succeeded.
Succeeded set_prompt(const bool prompt=true)
Can be used to set "promptness" of event.
Definition: CListRecordSAFIR.h:124
Class for record with coincidence data using SAFIR bitfield definition.
Definition: CListRecordSAFIR.h:111
bool is_prompt() const
Returns 0 if event is prompt and 1 if delayed.
Definition: CListRecordSAFIR.h:163
DataType get_data() const
Returns event_data (without checking if the type is really event and not time).
Definition: CListRecordSAFIR.h:231
bool is_prompt() const
Returns 0 if event is prompt and 1 if delayed.
Definition: CListRecordSAFIR.h:118
bool is_time() const
Returns 1 if if event is time and 0 if it is prompt.
Definition: CListRecordSAFIR.h:121
Class for records in a PET list mode file.
Definition: CListRecord.h:66
bool is_prompt() const override
Returns 0 if event is prompt and 1 if delayed.
Definition: CListRecordSAFIR.h:94
Definition: CListRecordSAFIR.h:72
Declaration of class stir::DetectorCoordinateMap.
Class for storing and using a coincidence event from a list mode file.
Definition: CListRecord.h:52
Inline implementation of class stir::CListEventSAFIR and stir::CListRecordSAFIR with supporting class...
CListEventSAFIR()
Definition: CListRecordSAFIR.h:78
Definition: DetectorCoordinateMap.h:50
A class for storing coordinates and value of a single projection bin.
Definition: Bin.h:48
bool is_time() const
Returns 1 if if event is time and 0 if it is prompt.
Definition: CListRecordSAFIR.h:166
Class for record with time data using SAFIR bitfield definition.
Definition: CListRecordSAFIR.h:201
Class for general SAFIR record, containing a union of data, time and raw record and providing access ...
Definition: CListRecordSAFIR.h:227
Definition of STIRIsNativeByteOrderBigEndian and STIRIsNativeByteOrderLittleEndian preprocessor symbo...
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
Declarations of classes stir::CListRecord, and stir::CListEvent which are used for list mode data...
Succeeded set_prompt(const bool prompt=true)
Can be used to set "promptness" of event.
Definition: CListRecordSAFIR.h:169
A class for storing and using a timing record from a listmode file.
Definition: ListTime.h:46
A class for storing 2 coordinates-sets of a detection, together with a timing-position index (for TOF...
Definition: DetectionPositionPair.h:40
bool is_valid_template(const ProjDataInfo &) const override
This method checks if the template is valid for LmToProjData.
Definition: CListRecordSAFIR.h:91
void set_scanner_sptr(shared_ptr< const Scanner > new_scanner_sptr)
Definition: CListRecordSAFIR.h:100
void set_map_sptr(shared_ptr< const DetectorCoordinateMap > new_map_sptr)
Function to set map for detector indices to coordinates.
Definition: CListRecordSAFIR.h:97
Declaration of class stir::DetectionPositionPair.