2828mutable struct NIfTI1Header
2929 sizeof_hdr:: Int32
3030
31- data_type:: NTuple{10,UInt8}
32- db_name:: NTuple{18,UInt8}
31+ data_type:: NTuple{10, UInt8}
32+ db_name:: NTuple{18, UInt8}
3333 extents:: Int32
3434 session_error:: Int16
3535 regular:: Int8
3636
37- dim_info:: Int8
37+ dim_info:: UInt8
3838 dim:: NTuple{8,Int16}
3939 intent_p1:: Float32
4040 intent_p2:: Float32
@@ -48,8 +48,8 @@ mutable struct NIfTI1Header
4848 scl_slope:: Float32
4949 scl_inter:: Float32
5050 slice_end:: Int16
51- slice_code:: Int8
52- xyzt_units:: Int8
51+ slice_code:: UInt8
52+ xyzt_units:: UInt8
5353 cal_max:: Float32
5454 cal_min:: Float32
5555 slice_duration:: Float32
@@ -58,8 +58,8 @@ mutable struct NIfTI1Header
5858 glmax:: Int32
5959 glmin:: Int32
6060
61- descrip:: NTuple{80,UInt8}
62- aux_file:: NTuple{24,UInt8}
61+ descrip:: NTuple{80, UInt8}
62+ aux_file:: NTuple{24, UInt8}
6363
6464 qform_code:: Int16
6565 sform_code:: Int16
@@ -70,13 +70,13 @@ mutable struct NIfTI1Header
7070 qoffset_y:: Float32
7171 qoffset_z:: Float32
7272
73- srow_x:: NTuple{4,Float32}
74- srow_y:: NTuple{4,Float32}
75- srow_z:: NTuple{4,Float32}
73+ srow_x:: NTuple{4, Float32}
74+ srow_y:: NTuple{4, Float32}
75+ srow_z:: NTuple{4, Float32}
7676
77- intent_name:: NTuple{16,UInt8}
77+ intent_name:: NTuple{16, UInt8}
7878
79- magic:: NTuple{4,UInt8}
79+ magic:: NTuple{4, UInt8}
8080end
8181define_packed (NIfTI1Header)
8282
@@ -95,53 +95,125 @@ function byteswap(hdr::NIfTI1Header)
9595end
9696
9797"""
98- freqdim(img )::Int
98+ NIfTI.slice_start(x )::Int
9999
100- Returns the frequency dimension associated with with `img`. `img` is an image or a collection of
101- image related metadata.
100+ Which slice corresponds to the first slice acquired during MRI acquisition (i.e. not padded slices).
102101"""
103- freqdim (x:: NIfTI1Header ) = Int (getfield (x, :dim_info ) & 0x03 )
104- freqdim (x) = freqdim (header (x))
102+ slice_start (x:: NIfTI1Header ) = Int (getfield (x, :slice_start )) + 1
103+ slice_start (x) = slice_start (header (x))
105104
106105"""
107- phasedim(img )::Int
106+ NIfTI.slice_end(x )::Int
108107
109- Returns the phase dimension associated with `img`. `img` is an image or a collection of
110- image related metadata.
108+ Which slice corresponds to the last slice acquired during MRI acquisition (i.e. not padded slices).
111109"""
112- phasedim (x:: NIfTI1Header ) = Int (( getfield (x, :dim_info ) >> 2 ) & 0x03 )
113- phasedim (x) = phasedim (header (x))
110+ slice_end (x:: NIfTI1Header ) = Int (getfield (x, :slice_end )) + 1
111+ slice_end (x) = slice_end (header (x))
114112
115113"""
116- slicedim(img)::Int
114+ NIfTI.slice_duration(x)
117115
118- Returns the slice dimension associated with `img`. `img` is an image or a collection of
119- image related metadata.
116+ Time to acquire one slice.
120117"""
121- slicedim (x:: NIfTI1Header ) = Int (( getfield (x, :dim_info ) >> 4 ) & 0x03 )
122- slicedim (x) = slicedim (header (x))
118+ slice_duration (x:: NIfTI1Header ) = getfield (x, :slice_duration )
119+ slice_duration (x) = slice_duration (header (x))
123120
124121"""
125- slice_start(x)::Int
122+ NIfTI.sdims(img)
126123
127- Which slice corresponds to the first slice acquired during MRI acquisition (i.e. not padded slices) .
124+ Return the number of spatial dimensions in the image .
128125"""
129- slice_start (x:: NIfTI1Header ) = Int (getfield (x, :slice_start )) + 1
130- slice_start (x) = slice_start (header (x))
126+ sdims (x:: NIfTI1Header ) = min (Int (getfield (getfield (x, :dim ), 1 )), 3 )
127+ sdims (x) = sdims (header (x))
128+
129+ # Conversion factors to mm/ms
130+ # http://nifti.nimh.nih.gov/nifti-1/documentation/nifti1fields/nifti1fields_pages/xyzt_units.html
131+ # 1 => NIfTI_UNITS_METER
132+ # 2 => NIfTI_UNITS_MM
133+ # 3 => NIfTI_UNITS_MICRON
134+ function to_spatial_multiplier (xyzt_units:: UInt8 )
135+ i = xyzt_units & 0x03
136+ if i === 0x01
137+ return 1000.0f0
138+ elseif i === 0x02
139+ return 1.0f0
140+ else
141+ return 0.001f0
142+ end
143+ end
131144
132145"""
133- slice_end(x)::Int
146+ NIfTI.voxel_size(header::NIfTI1Header)
134147
135- Which slice corresponds to the last slice acquired during MRI acquisition (i.e. not padded slices) .
148+ Get the voxel size **in mm** from a `NIfTI1Header` .
136149"""
137- slice_end (x:: NIfTI1Header ) = Int (getfield (x, :slice_end )) + 1
138- slice_end (x) = slice_end (header (x))
150+ function voxel_size (x:: NIfTI1Header )
151+ sd = sdims (x)
152+ if sd === 0
153+ return ()
154+ else
155+ sconvert = to_spatial_multiplier (getfield (x, :xyzt_units ))
156+ if sd === 3
157+ pd = getfield (x, :pixdim )
158+ return (
159+ getfield (pd, 2 ) * sconvert,
160+ getfield (pd, 3 ) * sconvert,
161+ getfield (pd, 4 ) * sconvert
162+ )
163+ elseif sd === 2
164+ pd = getfield (x, :pixdim )
165+ return (getfield (pd, 2 ) * sconvert, getfield (pd, 3 ) * sconvert,)
166+ else # sd === 1
167+ pd = getfield (x, :pixdim )
168+ return (getfield (pd, 2 ) * sconvert,)
169+ end
170+ end
171+ end
172+
173+ function to_dim_info (dim_info:: Tuple{Integer,Integer,Integer} )
174+ if dim_info[1 ] > 3 || dim_info[1 ] < 0
175+ error (" Invalid frequency dimension $(dim_info[1 ]) " )
176+ elseif dim_info[2 ] > 3 || dim_info[2 ] < 0
177+ error (" Invalid phase dimension $(dim_info[2 ]) " )
178+ elseif dim_info[3 ] > 3 || dim_info[3 ] < 0
179+ error (" Invalid slice dimension $(dim_info[3 ]) " )
180+ end
181+
182+ return UInt8 (dim_info[1 ] | (dim_info[2 ] << 2 ) | (dim_info[3 ] << 4 ))
183+ end
184+
185+ # Returns or sets dim_info as a tuple whose values are the frequency, phase, and slice dimensions
186+ function dim_info (hdr:: NIfTI1Header )
187+ return (hdr. dim_info & 0x03 , (hdr. dim_info >> 0x02 ) & 0x03 , (hdr. dim_info >> 0x04 ) & 0x03 )
188+ end
189+ function dim_info (header:: NIfTI1Header , dim_info:: Tuple{T, T, T} ) where {T<: Integer }
190+ header. dim_info = to_dim_info (dim_info)
191+ end
139192
140193"""
141- slice_duration(x)
194+ NIfTI.freqdim(img)::Int
142195
143- Time to acquire one slice.
196+ Returns the frequency dimension associated with with `img`. `img` is an image or a collection of
197+ image related metadata.
144198"""
145- slice_duration (x:: NIfTI1Header ) = getfield (x, :slice_duration )
146- slice_duration (x) = slice_duration (header (x))
199+ freqdim (x:: NIfTI1Header ) = Int (getfield (x, :dim_info ) & 0x03 )
200+ freqdim (x) = freqdim (header (x))
201+
202+ """
203+ NIfTI.phasedim(img)::Int
204+
205+ Returns the phase dimension associated with `img`. `img` is an image or a collection of
206+ image related metadata.
207+ """
208+ phasedim (x:: NIfTI1Header ) = Int ((getfield (x, :dim_info ) >> 0x02 ) & 0x03 )
209+ phasedim (x) = phasedim (header (x))
210+
211+ """
212+ NIfTI.slicedim(img)::Int
213+
214+ Returns the slice dimension associated with `img`. `img` is an image or a collection of
215+ image related metadata.
216+ """
217+ slicedim (x:: NIfTI1Header ) = Int ((getfield (x, :dim_info ) >> 0x04 ) & 0x03 )
218+ slicedim (x) = slicedim (header (x))
147219
0 commit comments