STIR 6.4.0
CListRecordECAT966.h
Go to the documentation of this file.
1//
2//
3/*
4 Copyright (C) 2003- 2011, Hammersmith Imanet Ltd
5 This file is part of STIR.
6
7 SPDX-License-Identifier: Apache-2.0
8
9 See STIR/LICENSE.txt for details
10*/
19
20#ifndef __stir_listmode_CListRecordECAT966_H__
21#define __stir_listmode_CListRecordECAT966_H__
22
28#include "stir/IO/stir_ecat_common.h" // for namespace macros
29#include "stir/Succeeded.h"
30#include "stir/ByteOrder.h"
32#include "stir/round.h"
33#include "boost/static_assert.hpp"
34#include "boost/cstdint.hpp"
36
37START_NAMESPACE_STIR
38
39START_NAMESPACE_ECAT
40START_NAMESPACE_ECAT7
41
43
55{
56public:
59 void get_sinogram_and_ring_coordinates(int& view, int& tangential_pos_num, unsigned int& ring_a, unsigned int& ring_b) const;
60
62 void set_sinogram_and_ring_coordinates(const int view_num, const int tangential_pos_num, const int ring_a, const int ring_b);
63
64 /* ring encoding. use as follows:
65 #define CRYSTALRINGSPERDETECTOR 8
66 ringA = ( block_A_ring * CRYSTALRINGSPERDETECTOR ) + block_A_detector ;
67 in practice, for the 966 block_A_ring ranges from 0 to 5.
68
69 This organisation corresponds to physical detector blocks (which
70 have 8 crystal rings). Names are not very good probably...
71 */
72 /* 'delayed' bit:
73 1 if event is Delayed (it fell in delayed time window) */
74 /* bin field is shifted in a funny way, use the following code to find
75 bin_number:
76 if ( bin > NumProjBinsBy2 ) bin -= NumProjBins ;
77 */
78
79#if STIRIsNativeByteOrderBigEndian
80 unsigned type : 1; /* 0-coincidence event, 1-time tick */
81 unsigned block_B_ring : 3;
82 unsigned block_A_ring : 3;
83 unsigned block_B_detector : 3;
84 unsigned block_A_detector : 3;
85 unsigned delayed : 1;
86 unsigned bin : 9;
87 unsigned view : 9;
88#else
89 // Do byteswapping first before using this bit field.
90 unsigned view : 9;
91 unsigned bin : 9;
92 unsigned delayed : 1;
93 unsigned block_A_detector : 3;
94 unsigned block_B_detector : 3;
95 unsigned block_A_ring : 3;
96 unsigned block_B_ring : 3;
97 unsigned type : 1; /* 0-coincidence event, 1-time tick */
98
99#endif
100}; /*-coincidence event*/
101
103class CListEventECAT966 : public CListEventCylindricalScannerWithViewTangRingRingEncoding<CListEventECAT966>
104{
105private:
106public:
107 typedef CListEventDataECAT966 DataType;
108 DataType get_data() const { return this->data; }
109
110public:
111 CListEventECAT966()
112 : CListEventCylindricalScannerWithViewTangRingRingEncoding<CListEventECAT966>(
113 shared_ptr<Scanner>(new Scanner(Scanner::E966)))
114 {}
115
116 Succeeded init_from_data_ptr(const void* const ptr)
117 {
118 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
119 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
120 return Succeeded::yes;
121 }
122 inline bool is_prompt() const { return this->data.delayed == 0; }
123 inline Succeeded set_prompt(const bool prompt = true)
124 {
125 if (prompt)
126 this->data.delayed = 0;
127 else
128 this->data.delayed = 1;
129 return Succeeded::yes;
130 }
131
132private:
133 BOOST_STATIC_ASSERT(sizeof(CListEventDataECAT966) == 4);
134 union
135 {
137 boost::int32_t raw;
138 };
139};
140
142
147{
148public:
149#if STIRIsNativeByteOrderBigEndian
150 unsigned type : 1; /* 0-coincidence event, 1-time tick */
151 unsigned gating : 4; /* some info about the gating signals */
152 unsigned time : 27; /* since scan start */
153#else
154 // Do byteswapping first before using this bit field.
155 unsigned time : 27; /* since scan start */
156 unsigned gating : 4; /* some info about the gating signals */
157 unsigned type : 1; /* 0-coincidence event, 1-time tick */
158#endif
159};
160
162
165{
166public:
167 Succeeded init_from_data_ptr(const void* const ptr)
168 {
169 const char* const data_ptr = reinterpret_cast<const char* const>(ptr);
170 std::copy(data_ptr, data_ptr + sizeof(this->raw), reinterpret_cast<char*>(&this->raw));
171 return Succeeded::yes;
172 }
173 bool is_time() const { return this->data.type == 1U; }
174 inline unsigned long get_time_in_millisecs() const { return static_cast<unsigned long>(this->data.time); }
175 inline Succeeded set_time_in_millisecs(const unsigned long time_in_millisecs)
176 {
177 this->data.time = ((1U << 28) - 1) & static_cast<unsigned>(time_in_millisecs);
178 // TODO return more useful value
179 return Succeeded::yes;
180 }
181 inline unsigned int get_gating() const { return this->data.gating; }
182 inline Succeeded set_gating(unsigned int g)
183 {
184 this->data.gating = g & 0xf;
185 return this->data.gating == g ? Succeeded::yes : Succeeded::no;
186 }
187
188private:
189 BOOST_STATIC_ASSERT(sizeof(CListTimeDataECAT966) == 4);
190 union
191 {
193 boost::int32_t raw;
194 };
195};
196
198
200class CListRecordECAT966 : public CListRecordWithGatingInput
201{
202
203 // public:
204
205 bool is_time() const { return this->time_data.is_time(); }
206 bool is_gating_input() const { return this->is_time(); }
207 bool is_event() const { return !this->is_time(); }
208 virtual CListEventECAT966& event() { return this->event_data; }
209 virtual const CListEventECAT966& event() const { return this->event_data; }
210 virtual CListTimeECAT966& time() { return this->time_data; }
211 virtual const CListTimeECAT966& time() const { return this->time_data; }
212 virtual CListTimeECAT966& gating_input() { return this->time_data; }
213 virtual const CListTimeECAT966& gating_input() const { return this->time_data; }
214
215 bool operator==(const CListRecord& e2) const
216 {
217 return dynamic_cast<CListRecordECAT966 const*>(&e2) != 0 && raw == dynamic_cast<CListRecordECAT966 const&>(e2).raw;
218 }
219
220public:
221 virtual Succeeded init_from_data_ptr(const char* const data_ptr,
222 const std::size_t
223#ifndef NDEBUG
224 size // only use within assert
225#endif
226 ,
227 const bool do_byte_swap)
228 {
229 assert(size >= 4);
230 std::copy(data_ptr, data_ptr + 4, reinterpret_cast<char*>(&raw)); // TODO necessary for operator==
231 if (do_byte_swap)
233 this->time_data.init_from_data_ptr(&raw);
234 // should in principle check return value, but it's always Succeeded::yes anyway
235 if (!this->is_time())
236 return this->event_data.init_from_data_ptr(&raw);
237 else
238 return Succeeded::yes;
239 }
240
241 virtual std::size_t
242 size_of_record_at_ptr(const char* const /*data_ptr*/, const std::size_t /*size*/, const bool /*do_byte_swap*/) const
243 {
244 return 4;
245 }
246
247private:
248 CListEventECAT966 event_data;
249 CListTimeECAT966 time_data;
250 boost::int32_t raw;
251};
252
253END_NAMESPACE_ECAT7
254END_NAMESPACE_ECAT
255END_NAMESPACE_STIR
256
257#endif
Definition of STIRIsNativeByteOrderBigEndian and STIRIsNativeByteOrderLittleEndian preprocessor symbo...
This file declares the stir::ByteOrder class.
Definition of class stir::CListEventCylindricalScannerWithViewTangRingRingEncoding.
Declarations of classes stir::CListRecord, and stir::CListEvent which are used for list mode data.
Declaration of class stir::DetectionPositionPair.
Declarations of class stir::ListGatingInput, which is used for list mode data.
Declarations of class stir::ListTime which is used for list mode data.
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 records in a PET list mode file.
Definition CListRecord.h:67
A class recording external input to the scanner (normally used for gating)
Definition ListGatingInput.h:39
A class for storing and using a timing record from a listmode file.
Definition ListTime.h:47
A class for storing some info on the scanner.
Definition Scanner.h:108
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
Class for decoding storing and using a raw coincidence event from a listmode file from the ECAT 966 s...
Definition CListRecordECAT966.h:55
void get_sinogram_and_ring_coordinates(int &view, int &tangential_pos_num, unsigned int &ring_a, unsigned int &ring_b) const
Definition CListRecordECAT966.cxx:39
void set_sinogram_and_ring_coordinates(const int view_num, const int tangential_pos_num, const int ring_a, const int ring_b)
Definition CListRecordECAT966.cxx:58
Class for storing and using a coincidence event from a listmode file from the ECAT 966 scanner.
Definition CListRecordECAT966.h:104
Succeeded set_prompt(const bool prompt=true)
Changes the event from prompt to delayed or vice versa.
Definition CListRecordECAT966.h:123
A class for a general element of a listmode file.
Definition CListRecordECAT966.h:201
A class for decoding a raw timing 'event' from a listmode file from the ECAT 966 scanner.
Definition CListRecordECAT966.h:147
A class for storing and using a timing 'event' from a listmode file from the ECAT 966 scanner.
Definition CListRecordECAT966.h:165
unsigned int get_gating() const
get gating-related info
Definition CListRecordECAT966.h:181
Declaration of the stir::round functions.
Declaration of routines which convert ECAT things into our building blocks and vice versa.