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
use std::{fs::File, io::BufReader, path::Path};
use anyhow::{Context, Result};
use byteorder::WriteBytesExt;
#[cfg(feature = "nifti_images")]
use nifti::NiftiHeader;
use crate::{
affine::get_affine_and_translation,
cheader::{CHeader, Endianness},
Affine, Affine4, Translation,
};
#[derive(Clone)]
pub struct Header {
c_header: CHeader,
pub affine4_to_rasmm: Affine4,
pub affine_to_rasmm: Affine,
pub translation: Translation,
pub nb_streamlines: usize,
pub scalars_name: Vec<String>,
pub properties_name: Vec<String>,
}
impl Header {
#[cfg(feature = "nifti_images")]
pub fn from_nifti(h: &NiftiHeader) -> Header {
let c_header = CHeader::from_nifti(h.dim, h.pixdim, h.srow_x, h.srow_y, h.srow_z);
let affine4 = c_header.get_affine_to_rasmm();
let (affine, translation) = get_affine_and_translation(&affine4);
Header {
c_header,
affine4_to_rasmm: affine4,
affine_to_rasmm: affine,
translation,
nb_streamlines: 0,
scalars_name: vec![],
properties_name: vec![],
}
}
pub fn from_trk<P: AsRef<Path>>(path: P) -> Result<Header> {
let f = File::open(path.as_ref())
.with_context(|| format!("Failed to load {:?}", path.as_ref()))?;
let mut reader = BufReader::new(f);
let (header, _) = Self::read(&mut reader)?;
Ok(header)
}
pub fn raw_header(&self) -> CHeader {
self.c_header.clone()
}
pub fn read(reader: &mut BufReader<File>) -> Result<(Header, Endianness)> {
let (c_header, endianness) = CHeader::read(reader)?;
let affine4 = c_header.get_affine_to_rasmm();
let (affine, translation) = get_affine_and_translation(&affine4);
let nb_streamlines = c_header.n_count as usize;
let scalars_name = c_header.get_scalars_name();
let properties_name = c_header.get_properties_name();
let header = Header {
c_header,
affine4_to_rasmm: affine4,
affine_to_rasmm: affine,
translation,
nb_streamlines,
scalars_name,
properties_name,
};
Ok((header, endianness))
}
pub fn clear_scalars_and_properties(&mut self) {
self.clear_scalars();
self.clear_properties();
}
pub fn clear_scalars(&mut self) {
self.scalars_name.clear();
self.c_header.clear_scalars();
}
pub fn clear_properties(&mut self) {
self.properties_name.clear();
self.c_header.clear_properties();
}
pub fn copy_scalars_and_properties(&mut self, rhs: &Self) {
self.copy_scalars(rhs);
self.copy_properties(rhs);
}
pub fn copy_scalars(&mut self, rhs: &Self) {
self.clear_scalars();
for scalar in &rhs.scalars_name {
self.add_scalar(scalar).unwrap(); }
}
pub fn copy_properties(&mut self, rhs: &Self) {
self.clear_properties();
for property in &rhs.properties_name {
self.add_property(property).unwrap(); }
}
pub fn add_scalar(&mut self, name: &str) -> Result<()> {
self.c_header.add_scalar(name)?;
self.scalars_name.push(name.to_string());
Ok(())
}
pub fn add_property(&mut self, name: &str) -> Result<()> {
self.c_header.add_property(name)?;
self.properties_name.push(name.to_string());
Ok(())
}
pub fn write<W: WriteBytesExt>(&self, writer: &mut W) -> Result<()> {
Ok(self.c_header.write(writer)?)
}
}
impl Default for Header {
fn default() -> Header {
Header {
c_header: CHeader::default(),
affine4_to_rasmm: Affine4::identity(),
affine_to_rasmm: Affine::identity(),
translation: Translation::zeros(),
nb_streamlines: 0,
scalars_name: vec![],
properties_name: vec![],
}
}
}
impl PartialEq for Header {
fn eq(&self, other: &Header) -> bool {
self.affine_to_rasmm == other.affine_to_rasmm
&& self.translation == other.translation
&& self.nb_streamlines == other.nb_streamlines
&& self.scalars_name == other.scalars_name
&& self.properties_name == other.properties_name
}
}