forked from UCL/STIR
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathProjDataInMemory.h
More file actions
324 lines (258 loc) · 10.1 KB
/
ProjDataInMemory.h
File metadata and controls
324 lines (258 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*
* Copyright (C) 2016, UCL
Copyright (C) 2002 - 2011-02-23, Hammersmith Imanet Ltd
Copyright (C) 2019-2020, 2023, UCL
This file is part of STIR.
SPDX-License-Identifier: Apache-2.0
See STIR/LICENSE.txt for details
*/
/*!
\file
\ingroup projdata
\brief Declaration of class stir::ProjDataInMemory
\author Nikos Efthimiou
\author Kris Thielemans
*/
#ifndef __stir_ProjDataInMemory_H__
#define __stir_ProjDataInMemory_H__
#include "stir/ProjData.h"
#include "stir/Array.h"
#include <string>
START_NAMESPACE_STIR
class Succeeded;
/*!
\ingroup projdata
\brief A class which reads/writes projection data from/to memory.
Mainly useful for temporary storage of projection data.
*/
class ProjDataInMemory : public ProjData
{
#ifdef STIR_COMPILING_SWIG_WRAPPER
// SWIG needs this typedef to be public
public:
#endif
typedef ProjDataInMemory self_type;
typedef ProjData base_type;
public:
//! constructor with only info, but no data
/*!
\param proj_data_info_ptr object specifying all sizes etc.
The ProjDataInfo object pointed to will not be modified.
\param initialise_with_0 specifies if the data should be set to 0.
If \c false, the data is undefined until you set it yourself.
*/
ProjDataInMemory(shared_ptr<const ExamInfo> const& exam_info_sptr,
shared_ptr<const ProjDataInfo> const& proj_data_info_ptr,
const bool initialise_with_0 = true);
//! constructor using externally allocated storage
/*!
The supplied buffer must have exactly `size_all()` elements for the
projection-data geometry.
*/
ProjDataInMemory(shared_ptr<const ExamInfo> const& exam_info_sptr,
shared_ptr<const ProjDataInfo> const& proj_data_info_ptr,
Array<1, float>&& buffer);
//! constructor that copies data from another ProjData
ProjDataInMemory(const ProjData& proj_data);
//! Copy constructor
ProjDataInMemory(const ProjDataInMemory& proj_data);
//! A static member to get the projection data in memory from a file
static shared_ptr<ProjDataInMemory> read_from_file(const std::string& filename);
Viewgram<float> get_viewgram(const int view_num,
const int segment_num,
const bool make_num_tangential_poss_odd = false,
const int timing_pos = 0) const override;
Succeeded set_viewgram(const Viewgram<float>& v) override;
Sinogram<float> get_sinogram(const int ax_pos_num,
const int segment_num,
const bool make_num_tangential_poss_odd = false,
const int timing_pos = 0) const override;
Succeeded set_sinogram(const Sinogram<float>& s) override;
//! Get all sinograms for the given segment
SegmentBySinogram<float> get_segment_by_sinogram(const int segment_num, const int timing_pos = 0) const override;
//! Get all viewgrams for the given segment
SegmentByView<float> get_segment_by_view(const int segment_num, const int timing_pos = 0) const override;
//! Set all sinograms for the given segment
Succeeded set_segment(const SegmentBySinogram<float>&) override;
//! Set all viewgrams for the given segment
Succeeded set_segment(const SegmentByView<float>&) override;
//! set all bins to the same value
/*! will call error() if setting failed */
void fill(const float value) override;
//! set all bins from another ProjData object
/*! will call error() if setting failed or if the 'source' proj_data is not compatible.
The current check requires at least the same segment numbers (but the source can have more),
all other geometric parameters have to be the same.
*/
void fill(const ProjData&) override;
//! destructor deallocates all memory the object owns
~ProjDataInMemory() override;
//! Returns a value of a bin
float get_bin_value(const Bin& bin) const;
void set_bin_value(const Bin& bin);
//! @name arithmetic operations
///@{
//! return sum of all elements
float sum() const override;
//! return maximum value of all elements
float find_max() const override;
//! return minimum value of all elements
float find_min() const override;
//! return L2-norm (sqrt of sum of squares)
double norm() const override;
//! return L2-norm squared (sum of squares)
double norm_squared() const override;
//! elem by elem addition
self_type operator+(const self_type& iv) const;
//! elem by elem subtraction
self_type operator-(const self_type& iv) const;
//! elem by elem multiplication
self_type operator*(const self_type& iv) const;
//! elem by elem division
self_type operator/(const self_type& iv) const;
//! addition with a 'float'
self_type operator+(const float a) const;
//! subtraction with a 'float'
self_type operator-(const float a) const;
//! multiplication with a 'float'
self_type operator*(const float a) const;
//! division with a 'float'
self_type operator/(const float a) const;
// corresponding assignment operators
//! adding elements of \c v to the current data
self_type& operator+=(const base_type& v) override;
//! subtracting elements of \c v from the current data
self_type& operator-=(const base_type& v) override;
//! multiplying elements of the current data with elements of \c v
self_type& operator*=(const base_type& v) override;
//! dividing all elements of the current data by elements of \c v
self_type& operator/=(const base_type& v) override;
//! adding an \c float to the elements of the current data
self_type& operator+=(const float v) override;
//! subtracting an \c float from the elements of the current data
self_type& operator-=(const float v) override;
//! multiplying the elements of the current data with an \c float
self_type& operator*=(const float v) override;
//! dividing the elements of the current data by an \c float
self_type& operator/=(const float v) override;
//! \deprecated a*x+b*y (use xapyb)
STIR_DEPRECATED void axpby(const float a, const ProjData& x, const float b, const ProjData& y) override;
//! set values of the array to x*a+y*b, where a and b are scalar, and x and y are ProjData.
/// This implementation requires that x and y are ProjDataInMemory
/// (else falls back on general method)
void xapyb(const ProjData& x, const float a, const ProjData& y, const float b) override;
//! set values of the array to x*a+y*b, where a, b, x and y are ProjData.
/// This implementation requires that a, b, x and y are ProjDataInMemory
/// (else falls back on general method)
void xapyb(const ProjData& x, const ProjData& a, const ProjData& y, const ProjData& b) override;
//! set values of the array to self*a+y*b where a and b are scalar, y is ProjData
/// This implementation requires that a, b and y are ProjDataInMemory
/// (else falls back on general method)
void sapyb(const float a, const ProjData& y, const float b) override;
//! set values of the array to self*a+y*b where a, b and y are ProjData
/// This implementation requires that a, b and y are ProjDataInMemory
/// (else falls back on general method)
void sapyb(const ProjData& a, const ProjData& y, const ProjData& b) override;
///@}
/** @name iterator typedefs
* iterator typedefs
*/
///@{
typedef Array<1, float>::iterator iterator;
typedef Array<1, float>::const_iterator const_iterator;
typedef Array<1, float>::full_iterator full_iterator;
typedef Array<1, float>::const_full_iterator const_full_iterator;
///@}
//! start value for iterating through all elements in the array, see iterator
iterator begin()
{
return buffer.begin();
}
//! start value for iterating through all elements in the (const) array, see iterator
const_iterator begin() const
{
return buffer.begin();
}
//! end value for iterating through all elements in the array, see iterator
iterator end()
{
return buffer.end();
}
//! end value for iterating through all elements in the (const) array, see iterator
const_iterator end() const
{
return buffer.end();
}
//! start value for iterating through all elements in the array, see iterator
iterator begin_all()
{
return buffer.begin_all();
}
//! start value for iterating through all elements in the (const) array, see iterator
const_iterator begin_all() const
{
return buffer.begin_all();
}
//! end value for iterating through all elements in the array, see iterator
iterator end_all()
{
return buffer.end_all();
}
//! end value for iterating through all elements in the (const) array, see iterator
const_iterator end_all() const
{
return buffer.end_all();
}
//! \name access to the data via a pointer
//@{
//! member function for access to the data via a float*
float* get_data_ptr()
{
return buffer.get_data_ptr();
}
//! member function for access to the data via a const float*
const float* get_const_data_ptr() const
{
return buffer.get_const_data_ptr();
}
//! signal end of access to float*
void release_data_ptr()
{
buffer.release_data_ptr();
}
//! signal end of access to const float*
void release_const_data_ptr() const
{
buffer.release_const_data_ptr();
}
//@}
private:
Array<1, float> buffer;
//! allocates buffer for storing the data. Has to be called by constructors
void create_buffer(const bool initialise_with_0 = false);
//! computes the offset and timing metadata after the geometry is known
void initialise_layout_metadata();
//! offset of the whole 3d sinogram in the stream
std::streamoff offset;
//! offset of a complete non-tof sinogram
std::streamoff offset_3d_data;
//! the order in which the segments occur in the stream
std::vector<int> segment_sequence;
//! the order in which the timing bins occur in the stream
std::vector<int> timing_poss_sequence;
//! Calculate the offset for a specific bin
/*! Throws if out-of-range or other error */
std::streamoff get_index(const Bin&) const;
};
inline double
norm(const ProjDataInMemory& p)
{
return p.norm();
}
inline double
norm_squared(const ProjDataInMemory& p)
{
return p.norm_squared();
}
END_NAMESPACE_STIR
#endif