Developer documentation
Version 3.0.3-105-gd3941f44
buffer_scratch_dump.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_mapping_buffer_scratch_dump_h__
18#define __dwi_tractography_mapping_buffer_scratch_dump_h__
19
20
21#include <map>
22
23#include "image.h"
24#include "types.h"
25
26#include "file/ofstream.h"
27
28
29
30namespace MR {
31 namespace DWI {
32 namespace Tractography {
33 namespace Mapping {
34
35
36 template <typename value_type>
37 class BufferScratchDump : public Image<value_type>
38 { MEMALIGN(BufferScratchDump)
39
40 public:
41 template <class Template>
42 BufferScratchDump (const Template& info) :
43 Image::BufferScratch<value_type> (info) { }
44
45 template <class Template>
46 BufferScratchDump (const Template& info, const std::string& label) :
47 Image::BufferScratch<value_type> (info, label) { }
48
49 void dump_to_file (const std::string&, const Image::Header&) const;
50
51 private:
52 // Helper function to get the underlying data pointer
53 inline const char* get_data_ptr() const { return reinterpret_cast<const char*> (Image::BufferScratch<value_type>::address(0)); }
54
55 };
56
57 template <>
58 inline const char* BufferScratchDump<bool>::get_data_ptr() const
59 {
60 return reinterpret_cast<const char*> (Image::BufferScratch<bool>::address());
61 }
62
63
64
65 template <typename value_type>
66 void BufferScratchDump<value_type>::dump_to_file (const std::string& path, const Header& H) const
67 {
68
69 if (!Path::has_suffix (path, ".mih") && !Path::has_suffix (path, ".mif"))
70 throw Exception ("Can only perform direct dump to file for .mih / .mif files");
71
72 const bool single_file = Path::has_suffix (path, ".mif");
73
74 std::string dat_path;
75 if (!single_file)
76 dat_path = Path::basename (path.substr (0, path.size()-4) + ".dat");
77 const int64_t dat_size = Image::footprint (*this);
78
79 File::OFStream out_header (path, std::ios::out | std::ios::binary);
80
81 out_header << "mrtrix image\n";
82 out_header << "dim: " << H.dim (0);
83 for (size_t n = 1; n < H.ndim(); ++n)
84 out_header << "," << H.dim (n);
85
86 out_header << "\nvox: " << H.vox (0);
87 for (size_t n = 1; n < H.ndim(); ++n)
88 out_header << "," << H.vox (n);
89
92
93 out_header << "\nlayout: " << (stride[0] >0 ? "+" : "-") << abs (stride[0])-1;
94 for (size_t n = 1; n < H.ndim(); ++n)
95 out_header << "," << (stride[n] >0 ? "+" : "-") << abs (stride[n])-1;
96
97 out_header << "\ndatatype: " << H.datatype().specifier();
98
99 for (const auto& i : H.keyval())
100 out_header << "\n" << i.first << ": " << i.second;
101
102 for (vector<std::string>::const_iterator i = H.comments().begin(); i != H.comments().end(); i++)
103 out_header << "\ncomments: " << *i;
104
105
106 if (H.transform().is_set()) {
107 out_header << "\ntransform: " << H.transform() (0,0) << "," << H.transform() (0,1) << "," << H.transform() (0,2) << "," << H.transform() (0,3);
108 out_header << "\ntransform: " << H.transform() (1,0) << "," << H.transform() (1,1) << "," << H.transform() (1,2) << "," << H.transform() (1,3);
109 out_header << "\ntransform: " << H.transform() (2,0) << "," << H.transform() (2,1) << "," << H.transform() (2,2) << "," << H.transform() (2,3);
110 }
111
112 if (H.intensity_offset() != 0.0 || H.intensity_scale() != 1.0)
113 out_header << "\nscaling: " << H.intensity_offset() << "," << H.intensity_scale();
114
115 if (H.DW_scheme().is_set()) {
116 for (size_t i = 0; i < H.DW_scheme().rows(); i++)
117 out_header << "\ndw_scheme: " << H.DW_scheme() (i,0) << "," << H.DW_scheme() (i,1) << "," << H.DW_scheme() (i,2) << "," << H.DW_scheme() (i,3);
118 }
119
120 out_header << "\nfile: ";
121 int64_t offset = 0;
122 if (single_file) {
123 offset = out_header.tellp() + int64_t(18);
124 offset += ((4 - (offset % 4)) % 4);
125 out_header << ". " << offset << "\nEND\n";
126 } else {
127 out_header << dat_path << "\n";
128 }
129 out_header.close();
130
131 File::OFStream out_dat;
132 if (single_file) {
133 File::resize (path, offset);
134 out_dat.open (path, std::ios_base::out | std::ios_base::binary | std::ios_base::app);
135 } else {
136 out_dat.open (dat_path, std::ios_base::out | std::ios_base::binary | std::ios_base::trunc);
137 }
138
139 const char* data_ptr = get_data_ptr();
140 out_dat.write (data_ptr, dat_size);
141 out_dat.close();
142
143 // If dat_size exceeds some threshold, ostream artificially increases the file size beyond that required at close()
144 if (single_file)
145 File::resize (path, offset + dat_size);
146 else
147 File::resize (dat_path, dat_size);
148
149 }
150
151
152
153
154 }
155 }
156 }
157}
158
159#endif
160
161
162
open output files for writing, checking for pre-existing file if necessary
Definition: ofstream.h:39
functions and classes related to image data input/output
Definition: image.h:41
index_type offset
Definition: loop.h:33
void resize(const std::string &filename, int64_t size)
Definition: utils.h:187
std::string basename(const std::string &name)
Definition: path.h:60
bool has_suffix(const std::string &name, const std::string &suffix)
Definition: path.h:130
vector< ssize_t > List
Definition: stride.h:63
void symbolise(HeaderType &header)
convert strides from actual to symbolic strides
Definition: stride.h:281
List get(const HeaderType &header)
return the strides of header as a vector<ssize_t>
Definition: stride.h:125
Definition: base.h:24
constexpr std::enable_if< std::is_arithmetic< X >::value &&std::is_unsigned< X >::value, X >::type abs(X x)
Definition: types.h:297
Eigen::MatrixXd H