STIR 6.5.0
CListRecordECAT8_32bit.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2003-2011 Hammersmith Imanet Ltd
3 Copyright (C) 2013-2014 University College London
4 This file is part of STIR.
5
6 SPDX-License-Identifier: Apache-2.0
7
8 See STIR/LICENSE.txt for details
9*/
17
18#ifndef __stir_listmode_CListRecordECAT8_32bit_H__
19#define __stir_listmode_CListRecordECAT8_32bit_H__
20
25#include "stir/Succeeded.h"
26#include "stir/ByteOrder.h"
28#include "stir/round.h"
29#include "boost/static_assert.hpp"
30#include "boost/cstdint.hpp"
32
33START_NAMESPACE_STIR
34namespace ecat
35{
36
38
49{
50public:
51 /* 'delayed' bit:
52 0 if event is delayed (it fell in delayed time window) */
53
54#if STIRIsNativeByteOrderBigEndian
55 unsigned type : 1; /* 0-coincidence event, 1-time tick */
56 unsigned delayed : 1;
57 unsigned offset : 30;
58#else
59 // Do byteswapping first before using this bit field.
60 unsigned offset : 30;
61 unsigned delayed : 1;
62 unsigned type : 1; /* 0-coincidence event, 1-time tick */
63
64#endif
65}; /*-coincidence event*/
66
68
73class CListEventECAT8_32bit : public CListEventCylindricalScannerWithDiscreteDetectors
74{
75private:
76public:
77 typedef CListEventDataECAT8_32bit DataType;
78 DataType get_data() const { return this->data; }
79
80public:
81 CListEventECAT8_32bit(const shared_ptr<const ProjDataInfo>& proj_data_info_sptr);
82
85
88
89 Succeeded init_from_data_ptr(const void* const ptr)
90 {
91 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
92 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
93 return Succeeded::yes;
94 }
95 inline bool is_prompt() const override { return this->data.delayed == 1; }
96 inline Succeeded set_prompt(const bool prompt = true) override
97 {
98 if (prompt)
99 this->data.delayed = 1;
100 else
101 this->data.delayed = 0;
102 return Succeeded::yes;
103 }
104
105private:
106 BOOST_STATIC_ASSERT(sizeof(CListEventDataECAT8_32bit) == 4);
107 union
108 {
110 boost::int32_t raw;
111 };
112 std::vector<int> segment_sequence;
113 std::vector<int> timing_poss_sequence;
114 std::vector<int> sizes;
115};
116
118
125{
126public:
127#if STIRIsNativeByteOrderBigEndian
128 unsigned type : 1; /* 0-coincidence event, 1-time tick */
129 unsigned deadtimeetc : 2; /* extra bits differentiating between timing or other stuff, zero if timing event */
130 unsigned time : 29; /* since scan start */
131#else
132 // Do byteswapping first before using this bit field.
133 unsigned time : 29; /* since scan start */
134 unsigned deadtimeetc : 2; /* extra bits differentiating between timing or other stuff, zero if timing event */
135 unsigned type : 1; /* 0-coincidence event, 1-time tick */
136#endif
137};
138
140
148{
149public:
150#if STIRIsNativeByteOrderBigEndian
151 unsigned type : 1; /* 1 = non-event */
152 unsigned subtype : 2; /* 0b10 = singles record */
153 unsigned bucket : 10; /* singles bucket index */
154 unsigned singles : 19; /* singles count */
155#else
156 // Do byteswapping first before using this bit field.
157 unsigned singles : 19; /* singles count */
158 unsigned bucket : 10; /* singles bucket index */
159 unsigned subtype : 2; /* 0b10 = singles record */
160 unsigned type : 1; /* 1 = non-event */
161#endif
162};
163
165
171{
172public:
173 Succeeded init_from_data_ptr(const void* const ptr)
174 {
175 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
176 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
177 return Succeeded::yes;
178 }
179 bool is_time() const { return this->data.type == 1U && this->data.deadtimeetc == 0U; }
180 bool is_other() const { return this->data.type == 1U && this->data.deadtimeetc != 0U; }
181 bool is_event() const { return this->data.type == 0U; }
182
183private:
184 BOOST_STATIC_ASSERT(sizeof(CListTimeDataECAT8_32bit) == 4);
185 union
186 {
188 boost::int32_t raw;
189 };
190};
191
193
196{
197public:
198 Succeeded init_from_data_ptr(const void* const ptr)
199 {
200 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
201 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
202 return Succeeded::yes;
203 }
204 bool is_time() const { return this->data.type == 1U && this->data.deadtimeetc == 0U; }
205 inline unsigned long get_time_in_millisecs() const override { return static_cast<unsigned long>(this->data.time); }
206 inline Succeeded set_time_in_millisecs(const unsigned long time_in_millisecs) override
207 {
208 this->data.time = ((1U << 30) - 1) & static_cast<unsigned>(time_in_millisecs);
209 // TODO return more useful value
210 return Succeeded::yes;
211 }
212
213private:
214 BOOST_STATIC_ASSERT(sizeof(CListTimeDataECAT8_32bit) == 4);
215 union
216 {
218 boost::int32_t raw;
219 };
220};
221
223
232{
233public:
234 Succeeded init_from_data_ptr(const void* const ptr)
235 {
236 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
237 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
238 return Succeeded::yes;
239 }
240
242 bool is_accumulated_singles() const { return this->data.type == 1U && this->data.subtype == 1U; }
243
244 unsigned int get_bucket_index() const override { return this->data.bucket; }
246
248 float get_singles_count() const override { return 8.F * static_cast<float>(this->data.singles); }
249
250private:
251 BOOST_STATIC_ASSERT(sizeof(CListSinglesDataECAT8_32bit) == 4);
252 union
253 {
255 boost::int32_t raw;
256 };
257};
258
260
268class CListRecordECAT8_32bit : public CListRecord // currently no gating yet
269{
270
271public:
272 bool is_time() const override { return this->any_data.is_time(); }
273 /*
274 bool is_gating_input() const
275 { return this->is_time(); }
276 */
277 bool is_event() const override { return this->any_data.is_event(); }
278 CListEventECAT8_32bit& event() override { return this->event_data; }
279 const CListEventECAT8_32bit& event() const override { return this->event_data; }
280 CListTimeECAT8_32bit& time() override { return this->time_data; }
281 const CListTimeECAT8_32bit& time() const override { return this->time_data; }
282 bool is_accumulated_singles() const override { return this->singles_data.is_accumulated_singles(); }
283 CListSinglesECAT8_32bit& accumulated_singles() override { return this->singles_data; }
284 const CListSinglesECAT8_32bit& accumulated_singles() const override { return this->singles_data; }
285
286 bool operator==(const CListRecord& e2) const
287 {
288 return dynamic_cast<CListRecordECAT8_32bit const*>(&e2) != 0 && raw == dynamic_cast<CListRecordECAT8_32bit const&>(e2).raw;
289 }
290
291public:
292 CListRecordECAT8_32bit(const shared_ptr<const ProjDataInfo>& proj_data_info_sptr)
293 : event_data(proj_data_info_sptr)
294 {}
295
296 virtual Succeeded init_from_data_ptr(const char* const data_ptr,
297 const std::size_t
298#ifndef NDEBUG
299 size // only used within assert, so commented-out otherwise to avoid compiler warnings
300#endif
301 ,
302 const bool do_byte_swap)
303 {
304 assert(size >= 4);
305 std::copy(data_ptr, data_ptr + 4, reinterpret_cast<char*>(&raw));
306 if (do_byte_swap)
308 this->any_data.init_from_data_ptr(&raw);
309 // should in principle check return value, but it's always Succeeded::yes anyway
310 if (this->any_data.is_time())
311 return this->time_data.init_from_data_ptr(&raw);
312 else if (this->any_data.is_event())
313 return this->event_data.init_from_data_ptr(&raw);
314 else if (this->any_data.is_other())
315 return this->singles_data.init_from_data_ptr(&raw);
316 else
317 return Succeeded::yes;
318 }
319
320 virtual std::size_t
321 size_of_record_at_ptr(const char* const /*data_ptr*/, const std::size_t /*size*/, const bool /*do_byte_swap*/) const
322 {
323 return 4;
324 }
325
326private:
327 CListEventECAT8_32bit event_data;
328 CListTimeECAT8_32bit time_data;
330 CListSinglesECAT8_32bit singles_data;
331 boost::int32_t raw; // this raw field isn't strictly necessary, get rid of it?
332};
333
334} // namespace ecat
335END_NAMESPACE_STIR
336
337#endif
Definition of STIRIsNativeByteOrderBigEndian and STIRIsNativeByteOrderLittleEndian preprocessor symbo...
This file declares the stir::ByteOrder class.
Declarations of class stir::CListEventCylindricalScannerWithDiscreteDetectors.
Declarations of classes stir::CListRecord, and stir::CListEvent which are used for list mode data.
Declaration of class stir::DetectionPositionPair.
Declaration of class stir::ListAccumulatedSingles.
Declaration of class stir::ProjDataInfoCylindrical.
Declaration of class stir::Succeeded.
static void swap_order(NUMBER &value)
swap the byteorder of the argument
Definition ByteOrder.h:122
Class for storing and using a coincidence event from a list mode file for a cylindrical scanner.
Definition CListEventCylindricalScannerWithDiscreteDetectors.h:33
Class for records in a PET list mode file.
Definition CListRecord.h:68
A class for storing 2 coordinates-sets of a detection, together with a timing-position index (for TOF...
Definition DetectionPositionPair.h:41
Class for an accumulated singles record in a listmode file.
Definition ListAccumulatedSingles.h:33
A class for storing and using a timing record from a listmode file.
Definition ListTime.h:47
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
A class for decoding a raw "other" word (neither time nor coincidence) from the ECAT 8_32bit listmode...
Definition CListRecordECAT8_32bit.h:171
Class for decoding storing and using a raw coincidence event from a listmode file from the ECAT 966 s...
Definition CListRecordECAT8_32bit.h:49
Class for storing and using a coincidence event from a listmode file from Siemens scanners using the ...
Definition CListRecordECAT8_32bit.h:74
void get_detection_position(DetectionPositionPair<> &) const override
This routine returns the corresponding detector pair.
Definition CListRecordECAT8_32bit.cxx:48
void set_detection_position(const DetectionPositionPair<> &) override
This routine sets in a coincidence event from detector "indices".
Definition CListRecordECAT8_32bit.cxx:83
Succeeded set_prompt(const bool prompt=true) override
Changes the event from prompt to delayed or vice versa.
Definition CListRecordECAT8_32bit.h:96
Bit-field struct for the PETLINK singles word (type=1, deadtimeetc=2).
Definition CListRecordECAT8_32bit.h:148
A class for storing and using a singles bucket record from a listmode file from the ECAT 8_32bit scan...
Definition CListRecordECAT8_32bit.h:232
bool is_accumulated_singles() const
Returns true if this word is a singles record (type=1, subtype=0b10).
Definition CListRecordECAT8_32bit.h:242
float get_singles_count() const override
Number of singles in this record.
Definition CListRecordECAT8_32bit.h:248
unsigned int get_bucket_index() const override
Returns the singles bucket index.
Definition CListRecordECAT8_32bit.h:244
A class for decoding a raw events that is neither time or coincidence in a listmode file from the ECA...
Definition CListRecordECAT8_32bit.h:125
A class for storing and using a timing 'event' from a listmode file from the ECAT 8_32bit scanner.
Definition CListRecordECAT8_32bit.h:196
Declaration of the stir::round functions.