Developer documentation
Version 3.0.3-105-gd3941f44
scalar_file.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __dwi_tractography_scalar_file_h__
18#define __dwi_tractography_scalar_file_h__
19
20#include <map>
21
22#include "types.h"
23#include "file/config.h"
24#include "file/key_value.h"
25#include "file/ofstream.h"
29
30
31namespace MR
32{
33 namespace DWI
34 {
35 namespace Tractography
36 {
37
38
39
40
42
58 inline void check_properties_match (const Properties& p_tck, const Properties& p_tsf, const std::string& type, bool abort_on_fail = true)
59 {
60 check_timestamps (p_tck, p_tsf, type);
61 check_counts (p_tck, p_tsf, type, abort_on_fail);
62 }
63
64
65
66
67
68
69 template <typename T = float> class ScalarReader : public __ReaderBase__
71 public:
72 using value_type = T;
73
74 ScalarReader (const std::string& file, Properties& properties) {
75 open (file, "track scalars", properties);
76 }
77
78 bool operator() (TrackScalar<T>& tck_scalar)
79 {
80 tck_scalar.clear();
81
82 if (!in.is_open())
83 return false;
84 do {
86 if (std::isinf (val)) {
87 in.close();
88 return false;
89 }
90 if (in.eof()) {
91 in.close();
92 return false;
93 }
94
95 if (std::isnan (val)) {
96 tck_scalar.set_index (current_index++);
97 return true;
98 }
99 tck_scalar.push_back (val);
100 } while (in.good());
101
102 in.close();
103 return false;
104 }
105
106 protected:
107 using __ReaderBase__::in;
108 using __ReaderBase__::dtype;
109 using __ReaderBase__::current_index;
110
112 {
113 using namespace ByteOrder;
114 switch (dtype()) {
116 {
117 float val;
118 in.read ((char*) &val, sizeof (val));
119 return (value_type (LE(val)));
120 }
122 {
123 float val;
124 in.read ((char*) &val, sizeof (val));
125 return (value_type (BE(val)));
126 }
128 {
129 double val;
130 in.read ((char*) &val, sizeof (val));
131 return (value_type (LE(val)));
132 }
134 {
135 double val;
136 in.read ((char*) &val, sizeof (val));
137 return (value_type (BE(val)));
138 }
139 default:
140 assert (0);
141 break;
142 }
143 return (value_type (NaN));
144 }
145
146 ScalarReader (const ScalarReader&) = delete;
147
148 };
149
150
151
153
166 template <typename T = float>
167 class ScalarWriter : public __WriterBase__<T>
168 { NOMEMALIGN
169 public:
170 using value_type = T;
171 using __WriterBase__<T>::count;
172 using __WriterBase__<T>::count_offset;
173 using __WriterBase__<T>::total_count;
175 using __WriterBase__<T>::dtype;
177 using __WriterBase__<T>::update_counts;
178 using __WriterBase__<T>::verify_stream;
179 using __WriterBase__<T>::open_success;
180
181 ScalarWriter (const std::string& file, const Properties& properties) :
182 __WriterBase__<T> (file),
183 buffer_capacity (File::Config::get_int ("TrackWriterBufferSize", 16777216) / sizeof (value_type)),
185 buffer_size (0)
186 {
187 File::OFStream out;
188 try {
189 out.open (name, std::ios::out | std::ios::binary | std::ios::trunc);
190 } catch (Exception& e) {
191 throw Exception (e, "Unable to create output track scalar file");
192 }
193
194 // Do NOT set Properties timestamp here! (Must match corresponding .tck file)
195 const_cast<Properties&> (properties).set_version_info();
196 const_cast<Properties&> (properties).update_command_history();
197 create (out, properties, "track scalars");
198 open_success = true;
199 current_offset = out.tellp();
200 }
201
203 commit();
204 }
205
206
207 bool operator() (const TrackScalar<T>& tck_scalar)
208 {
209 if (buffer_size + tck_scalar.size() > buffer_capacity)
210 commit();
211
212 for (typename vector<value_type>::const_iterator i = tck_scalar.begin(); i != tck_scalar.end(); ++i) {
213 assert (std::isfinite (*i));
214 add_scalar (*i);
215 }
217 ++count;
218 ++total_count;
219 return true;
220 }
221
222
223 protected:
224
225 const size_t buffer_capacity;
226 std::unique_ptr<value_type[]> buffer;
229
230 void add_scalar (const value_type& s) {
232 }
233
234 value_type delimiter () const { return value_type (NAN); }
235
236 void format_scalar (const value_type& s, value_type& destination)
237 {
238 using namespace ByteOrder;
239 if (dtype.is_little_endian())
240 destination = LE(s);
241 else
242 destination = BE(s);
243 }
244
245 void commit ()
246 {
247 if (buffer_size == 0 || !open_success)
248 return;
249 File::OFStream out (name, std::ios::in | std::ios::out | std::ios::binary | std::ios::ate);
250 out.seekp (current_offset, out.beg);
251 out.write (reinterpret_cast<char*> (buffer.get()), sizeof(value_type)*buffer_size);
252 current_offset = int64_t (out.tellp());
253 verify_stream (out);
254 update_counts (out);
255 verify_stream (out);
256 buffer_size = 0;
257 }
258
259
260 ScalarWriter (const ScalarWriter&) = delete;
261
262 };
263
264
265 }
266 }
267}
268
269
270#endif
271
void set_index(const size_t i)
Definition: streamline.h:47
ScalarReader(const std::string &file, Properties &properties)
Definition: scalar_file.h:74
bool operator()(TrackScalar< T > &tck_scalar)
Definition: scalar_file.h:78
ScalarReader(const ScalarReader &)=delete
class to handle writing track scalars to file
Definition: scalar_file.h:168
ScalarWriter(const ScalarWriter &)=delete
bool operator()(const TrackScalar< T > &tck_scalar)
Definition: scalar_file.h:207
void format_scalar(const value_type &s, value_type &destination)
Definition: scalar_file.h:236
void add_scalar(const value_type &s)
Definition: scalar_file.h:230
ScalarWriter(const std::string &file, const Properties &properties)
Definition: scalar_file.h:181
std::unique_ptr< value_type[]> buffer
Definition: scalar_file.h:226
static constexpr uint8_t Float64LE
Definition: datatype.h:169
static constexpr uint8_t Float32BE
Definition: datatype.h:168
static constexpr uint8_t Float32LE
Definition: datatype.h:167
static constexpr uint8_t Float64BE
Definition: datatype.h:170
open output files for writing, checking for pre-existing file if necessary
Definition: ofstream.h:39
void open(const std::string &path, const std::ios_base::openmode mode=std::ios_base::out|std::ios_base::binary)
constexpr double e
Definition: math.h:39
#define NOMEMALIGN
Definition: memory.h:22
ValueType BE(ValueType v)
Definition: raw.h:94
ValueType LE(ValueType v)
Definition: raw.h:91
void check_counts(const Properties &, const Properties &, const std::string &, bool abort_on_fail)
void check_properties_match(const Properties &p_tck, const Properties &p_tsf, const std::string &type, bool abort_on_fail=true)
convenience function to verify that tck/tsf files match
Definition: scalar_file.h:58
void check_timestamps(const Properties &, const Properties &, const std::string &)
std::unique_ptr< ImageIO::Base > create(Header &H)
Definition: base.h:24
constexpr default_type NaN
Definition: types.h:230
const std::string name
Definition: thread.h:108