STIR 6.4.0
InputStreamWithRecordsFromHDF5.inl
Go to the documentation of this file.
1
12/*
13 Copyright (C) 2003-2011, Hammersmith Imanet Ltd
14 Copyright (C) 2012-2013, Kris Thielemans
15 Copyright (C) 2018 University of Hull
16 Copyright (C) 2018 University of Leeds
17 Copyright (C) 2020-2021 University College London
18 This file is part of STIR.
19
20 SPDX-License-Identifier: Apache-2.0
21
22 See STIR/LICENSE.txt for details
23*/
24
25#include "stir/utilities.h"
26#include "stir/Succeeded.h"
27#include "stir/is_null_ptr.h"
28#include "stir/shared_ptr.h"
29
30#include <fstream>
31#include <string.h>
32START_NAMESPACE_STIR
33
34namespace GE
35{
36namespace RDF_HDF5
37{
38
39// template <class RecordT>
40// InputStreamWithRecordsFromHDF5<RecordT>::
41// InputStreamWithRecordsFromHDF5(const shared_ptr<H5::DataSet>& dataset_sptr_v,
42// const std::size_t size_of_record_signature,
43// const std::size_t max_size_of_record)
44// : dataset_sptr(dataset_sptr_v),
45// size_of_record_signature(size_of_record_signature),
46// max_size_of_record(max_size_of_record)
47//{
48// assert(size_of_record_signature<=max_size_of_record);
49// if (is_null_ptr(dataset_sptr))
50// return;
51// starting_stream_position = 0;
52// current_offset = 0;
53// //if (!dataset_sptr->good())
54// // error("InputStreamWithRecordsFromHDF5: error in tellg()\n");
55// }
56
57template <class RecordT>
59 const std::size_t size_of_record_signature,
60 const std::size_t max_size_of_record)
61 : m_filename(filename),
62 size_of_record_signature(size_of_record_signature),
63 max_size_of_record(max_size_of_record)
64{
65 assert(size_of_record_signature <= max_size_of_record);
66
67 this->max_buffer_size = 10000000;
68 this->buffer.reset(new char[this->max_buffer_size]);
69
70 set_up();
71}
72
73template <class RecordT>
75InputStreamWithRecordsFromHDF5<RecordT>::set_up()
76{
77 input_sptr.reset(new GEHDF5Wrapper(m_filename));
78 data_sptr.reset(new char[this->max_size_of_record]);
79 starting_stream_position = 0;
80 current_offset = 0;
81
82 input_sptr->initialise_listmode_data();
83 m_list_size = input_sptr->get_dataset_size() - this->size_of_record_signature;
84
85 this->buffer_size = 0;
86 return Succeeded::yes;
87}
88
89template <class RecordT>
90void
91InputStreamWithRecordsFromHDF5<RecordT>::fill_buffer(const std::streampos offset) const
92{
93 this->buffer_size = static_cast<std::size_t>(std::min(static_cast<uint64_t>(this->max_buffer_size), m_list_size - offset));
94 input_sptr->read_list_data(buffer.get(), offset, hsize_t(this->buffer_size));
95 this->start_of_buffer_offset = offset;
96}
98template <class RecordT>
99void
100InputStreamWithRecordsFromHDF5<RecordT>::read_data(char* output, const std::streampos offset, const hsize_t size) const
101{
102 if (this->buffer_size == 0 || offset < this->start_of_buffer_offset
103 || offset >= (this->start_of_buffer_offset + static_cast<std::streampos>(this->buffer_size)))
104 this->fill_buffer(offset);
105
106 // copy data from buffer to output
107 const std::size_t offset_in_buffer = offset - this->start_of_buffer_offset;
108 const hsize_t size_in_buffer = std::min(size, static_cast<hsize_t>(this->buffer_size - offset_in_buffer));
109
110 memcpy(output, this->buffer.get() + offset_in_buffer, static_cast<std::size_t>(size_in_buffer));
111
112 // check if there is anything else to read after the end of the buffer
113 if (size_in_buffer < size)
114 read_data(output + size_in_buffer, offset + static_cast<std::streampos>(size_in_buffer), size - size_in_buffer);
115}
116
117template <class RecordT>
119InputStreamWithRecordsFromHDF5<RecordT>::get_next_record(RecordT& record)
121 try
122 {
123 if (current_offset >= static_cast<std::streampos>(m_list_size))
124 return Succeeded::no;
125 char* data_ptr = data_sptr.get();
126 this->read_data(data_ptr, current_offset, hsize_t(this->size_of_record_signature));
127 const std::size_t size_of_record = record.size_of_record_at_ptr(data_ptr, this->size_of_record_signature, false);
128
129 assert(size_of_record <= this->max_size_of_record);
130 // read more bytes if necessary
131 auto remainder = size_of_record - this->size_of_record_signature;
132 if (remainder > 0)
133 this->read_data(data_ptr + this->size_of_record_signature,
134 current_offset + static_cast<std::streampos>(this->size_of_record_signature),
135 hsize_t(remainder));
136 current_offset += size_of_record;
137 return record.init_from_data_ptr(data_ptr, size_of_record, false);
138 }
139 catch (...)
140 {
141 return Succeeded::no;
142 }
143}
144
145template <class RecordT>
148{
149 if (is_null_ptr(input_sptr))
150 return Succeeded::no;
151
152 current_offset = 0;
153 return Succeeded::yes;
154}
155
156template <class RecordT>
157typename InputStreamWithRecordsFromHDF5<RecordT>::SavedPosition
159{
160 assert(!is_null_ptr(input_sptr));
161 // TODO should somehow check if tellg() worked and return an error if it didn't
162
163 saved_get_positions.push_back(current_offset);
164 return saved_get_positions.size() - 1;
165}
166
167template <class RecordT>
170 const typename InputStreamWithRecordsFromHDF5<RecordT>::SavedPosition& pos)
171{
172 if (is_null_ptr(input_sptr))
173 return Succeeded::no;
174
175 assert(pos < saved_get_positions.size());
176 current_offset = saved_get_positions[pos];
177
178 return Succeeded::yes;
179}
180
181template <class RecordT>
182std::vector<std::streampos>
184{
185 return saved_get_positions;
186}
187
188template <class RecordT>
189void
191{
192 saved_get_positions = poss;
193}
194
195} // namespace RDF_HDF5
196} // namespace GE
197END_NAMESPACE_STIR
Declaration of class stir::Succeeded.
A class that extracts and reads the necessary data from GE HDF5 input files.
Definition GEHDF5Wrapper.h:51
std::vector< std::streampos > get_saved_get_positions() const
Function that enables the user to store the saved get_positions.
Definition InputStreamWithRecordsFromHDF5.inl:183
Succeeded set_get_position(const SavedPosition &)
set current "get" position to previously saved value
Definition InputStreamWithRecordsFromHDF5.inl:169
InputStreamWithRecordsFromHDF5(const std::string &filename, const std::size_t size_of_record_signature, const std::size_t max_size_of_record)
Constructor taking a stream.
Definition InputStreamWithRecordsFromHDF5.inl:58
Succeeded reset()
go back to starting position
Definition InputStreamWithRecordsFromHDF5.inl:147
void set_saved_get_positions(const std::vector< std::streampos > &)
Function that sets the saved get_positions.
Definition InputStreamWithRecordsFromHDF5.inl:190
SavedPosition save_get_position()
save current "get" position in an internal array
Definition InputStreamWithRecordsFromHDF5.inl:158
a class containing an enumeration type that can be used by functions to signal successful operation o...
Definition Succeeded.h:44
Succeeded read_data(IStreamT &s, ArrayType< num_dimensions, elemT > &data, const ByteOrder byte_order=ByteOrder::native)
Read the data of an Array from file.
Definition read_data.inl:63
Definition of stir::is_null_ptr functions.
Import of std::shared_ptr, std::dynamic_pointer_cast and std::static_pointer_cast into the stir names...
This file declares various utility functions.