Developer documentation
Version 3.0.3-105-gd3941f44
image.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 __file_dicom_image_h__
18#define __file_dicom_image_h__
19
20#include <memory>
21
22#include "datatype.h"
23#include "types.h"
24#include "file/dicom/element.h"
25
26namespace MR {
27 namespace File {
28 namespace Dicom {
29
30 class Series;
31 class Element;
32
33 class Frame { MEMALIGN(Frame)
34 public:
35 Frame () {
36 acq_dim[0] = acq_dim[1] = dim[0] = dim[1] = instance =
37 series_num = acq = sequence = echo_index = grad_number = UINT_MAX;
38 samples_per_pixel = 1;
39 position_vector[0] = position_vector[1] = position_vector[2] = NaN;
40 orientation_x[0] = orientation_x[1] = orientation_x[2] = NaN;
41 orientation_y[0] = orientation_y[1] = orientation_y[2] = NaN;
42 orientation_z[0] = orientation_z[1] = orientation_z[2] = NaN;
43 distance = NaN;
44 pixel_size[0] = pixel_size[1] = slice_thickness = slice_spacing = NaN;
45 scale_intercept = 0.0;
46 scale_slope = 1.0;
47 bvalue = G[0] = G[1] = G[2] = NaN;
48 data = bits_alloc = data_size = frame_offset = 0;
49 DW_scheme_wrt_image = false;
50 transfer_syntax_supported = true;
51 ignore_series_num = false;
52 pe_axis = 3;
53 pe_sign = 0;
54 philips_orientation = '\0';
55 pixel_bandwidth = bandwidth_per_pixel_phase_encode = echo_time = inversion_time = repetition_time = flip_angle = partial_fourier = time_after_start = NaN;
56 echo_train_length = 0;
57 bipolar_flag = readoutmode_flag = 0;
58 }
59
60 size_t acq_dim[2], dim[2], series_num, instance, acq, sequence, echo_index, grad_number, samples_per_pixel;
61 Eigen::Vector3d position_vector, orientation_x, orientation_y, orientation_z, G;
62 default_type distance, pixel_size[2], slice_thickness, slice_spacing, scale_slope, scale_intercept, bvalue;
63 size_t data, bits_alloc, data_size, frame_offset;
64 std::string filename, image_type;
65 bool DW_scheme_wrt_image, transfer_syntax_supported, ignore_series_num;
66 size_t pe_axis;
67 int pe_sign;
68 char philips_orientation;
69 Time acquisition_time;
70 default_type pixel_bandwidth, bandwidth_per_pixel_phase_encode, echo_time, inversion_time, repetition_time, flip_angle, partial_fourier, time_after_start;
71 size_t echo_train_length;
72 size_t bipolar_flag, readoutmode_flag;
73 vector<uint32_t> index;
74 vector<default_type> flip_angles;
75
76 bool operator< (const Frame& frame) const {
77 if (!ignore_series_num && series_num != frame.series_num)
78 return series_num < frame.series_num;
79 if (image_type != frame.image_type)
80 return image_type < frame.image_type;
81 if (acq != frame.acq)
82 return acq < frame.acq;
83 if (std::isfinite (distance) && std::isfinite (frame.distance) && distance != frame.distance)
84 return distance < frame.distance;
85 for (size_t n = index.size(); n--;)
86 if (index[n] != frame.index[n])
87 return index[n] < frame.index[n];
88 if (echo_index != frame.echo_index)
89 return echo_index < frame.echo_index;
90 if (std::isfinite (echo_time) && echo_time != frame.echo_time)
91 return echo_time < frame.echo_time;
92 if (grad_number != frame.grad_number)
93 return grad_number < frame.grad_number;
94 if (sequence != frame.sequence)
95 return sequence < frame.sequence;
96 if (instance != frame.instance)
97 return instance < frame.instance;
98 return false;
99 }
100
101
102 void calc_distance ()
103 {
104 if (!std::isfinite (orientation_z[0]))
105 orientation_z = orientation_x.cross (orientation_y);
106 else {
107 if (!orientation_x.allFinite() || !orientation_y.allFinite())
108 throw Exception ("slice orientation information missing from DICOM header!");
109 Eigen::Vector3d normal = orientation_x.cross (orientation_y);
110 if (normal.dot (orientation_z) < 0.0)
111 orientation_z = -normal;
112 else
113 orientation_z = normal;
114 }
115
116 if (!position_vector.allFinite())
117 throw Exception ("slice position information missing from DICOM header!");
118
119 orientation_z.normalize();
120 distance = orientation_z.dot (position_vector);
121 }
122
123 bool is_philips_iso () const {
124 if (philips_orientation == '\0')
125 return false;
126 return (philips_orientation == 'I' && bvalue > 0.0);
127 }
128
129 static vector<size_t> count (const vector<Frame*>& frames);
130 static default_type get_slice_separation (const vector<Frame*>& frames, size_t nslices);
131 static std::string get_DW_scheme (const vector<Frame*>& frames, const size_t nslices, const transform_type& image_transform);
132 static Eigen::MatrixXd get_PE_scheme (const vector<Frame*>& frames, const size_t nslices);
133
134 friend std::ostream& operator<< (std::ostream& stream, const Frame& item);
135 };
136
137
138
139
140
141
142
143
144
145
146
147 class Image : public Frame { MEMALIGN(Image)
148
149 public:
150 Image (Series* parent = nullptr) :
151 series (parent),
152 images_in_mosaic (0),
153 is_BE (false),
154 in_frames (false) { }
155
156 Series* series;
157 size_t images_in_mosaic;
158 std::string sequence_name, manufacturer;
159 bool is_BE, in_frames;
160 vector<float> mosaic_slices_timing;
161
162 vector<uint32_t> frame_dim;
164
165 void read ();
166 void parse_item (Element& item, const std::string& dirname = "");
167 void decode_csa (const uint8_t* start, const uint8_t* end);
168 KeyValues read_csa_ascii (const vector<std::string>& data);
169
170 bool operator< (const Image& ima) const {
171 return Frame::operator< (ima);
172 }
173
174 friend std::ostream& operator<< (std::ostream& stream, const Image& item);
175
176 };
177
178
179
180
181
182 }
183 }
184}
185
186
187#endif
188
189
friend std::ostream & operator<<(std::ostream &stream, const Frame &item)
friend std::ostream & operator<<(std::ostream &stream, const Image &item)
std::string dirname(const std::string &name)
Definition: path.h:67
Vertex normal(const Vertex &one, const Vertex &two, const Vertex &three)
Definition: utils.h:32
Definition: base.h:24
std::map< std::string, std::string > KeyValues
used in various places for storing key-value pairs
Definition: types.h:238
double default_type
the default type used throughout MRtrix
Definition: types.h:228
Eigen::Transform< default_type, 3, Eigen::AffineCompact > transform_type
the type for the affine transform of an image:
Definition: types.h:234
constexpr default_type NaN
Definition: types.h:230
Item item
size_t index