32
32
('dims' , '>i4' , (4 ,)), # 4; width, height, depth, nframes
33
33
('type' , '>i4' ), # 20; data type
34
34
('dof' , '>i4' ), # 24; degrees of freedom
35
- ('ras_good' , '>i2' ), # 28; *_ras fields valid
36
- ('voxelsize' , '>f4' , (3 ,)), # 30; zooms (X, Y, Z)
37
- ('x_ras' , '>f4' , (3 , 1 )), # 42; X direction cosine column
38
- ('y_ras' , '>f4' , (3 , 1 )), # 54; Y direction cosine column
39
- ('z_ras' , '>f4' , (3 , 1 )), # 66; Z direction cosine column
40
- ('c_ras' , '>f4' , (3 , 1 )), # 78; mm from (0, 0, 0) RAS to vol center
35
+ ('goodRASFlag' , '>i2' ), # 28; Mdc, Pxyz_c fields valid
36
+ ('delta' , '>f4' , (3 ,)), # 30; zooms (X, Y, Z)
37
+ ('Mdc' , '>f4' , (3 , 3 )), # 42; TRANSPOSE of direction cosine matrix
38
+ ('Pxyz_c' , '>f4' , (3 ,)), # 78; mm from (0, 0, 0) RAS to vol center
41
39
]
42
40
# Optional footer. Also has more stuff after this, optionally
43
41
footer_dtd = [
@@ -120,7 +118,7 @@ def __init__(self,
120
118
super (MGHHeader , self ).__init__ (binaryblock = binaryblock ,
121
119
endianness = endianness ,
122
120
check = False )
123
- if not self ._structarr ['ras_good ' ]:
121
+ if not self ._structarr ['goodRASFlag ' ]:
124
122
self ._set_affine_default ()
125
123
if check :
126
124
self .check_fix ()
@@ -165,13 +163,12 @@ def get_affine(self):
165
163
166
164
MGH format doesn't store the transform directly. Instead it's gleaned
167
165
from the zooms ( delta ), direction cosines ( Mdc ), RAS centers (
168
- c_ras ) and the dimensions.
166
+ Pxyz_c ) and the dimensions.
169
167
'''
170
- affine = np .eye (4 )
171
168
hdr = self ._structarr
172
- MdcD = np . hstack (( hdr ['x_ras' ], hdr [ 'y_ras' ], hdr [ 'z_ras' ])) * hdr ['voxelsize ' ]
169
+ MdcD = hdr ['Mdc' ]. T * hdr ['delta ' ]
173
170
vol_center = MdcD .dot (hdr ['dims' ][:3 ]) / 2
174
- return from_matvec (MdcD , hdr ['c_ras' ]. T - vol_center )
171
+ return from_matvec (MdcD , hdr ['Pxyz_c' ] - vol_center )
175
172
176
173
# For compatibility with nifti (multiple affines)
177
174
get_best_affine = get_affine
@@ -185,7 +182,7 @@ def get_vox2ras_tkr(self):
185
182
''' Get the vox2ras-tkr transform. See "Torig" here:
186
183
https://surfer.nmr.mgh.harvard.edu/fswiki/CoordinateSystems
187
184
'''
188
- ds = self ._structarr ['voxelsize ' ]
185
+ ds = self ._structarr ['delta ' ]
189
186
ns = self ._structarr ['dims' ][:3 ] * ds / 2.0
190
187
v2rtkr = np .array ([[- ds [0 ], 0 , 0 , ns [0 ]],
191
188
[0 , 0 , ds [2 ], - ns [2 ]],
@@ -235,7 +232,7 @@ def get_zooms(self):
235
232
For four-dimensional files, a fourth zoom is included, equal to the
236
233
repetition time (TR) in ms.
237
234
238
- To access only the spatial zooms, use `hdr['voxelsize ']`.
235
+ To access only the spatial zooms, use `hdr['delta ']`.
239
236
240
237
Returns
241
238
-------
@@ -244,7 +241,7 @@ def get_zooms(self):
244
241
'''
245
242
# Do not return time zoom (TR) if 3D image
246
243
tzoom = (self ['tr' ],)[:self ._ndims () > 3 ]
247
- return tuple (self ._structarr ['voxelsize ' ]) + tzoom
244
+ return tuple (self ._structarr ['delta ' ]) + tzoom
248
245
249
246
def set_zooms (self , zooms ):
250
247
''' Set zooms into header fields
@@ -266,7 +263,7 @@ def set_zooms(self, zooms):
266
263
raise HeaderDataError ('Expecting %d zoom values' % ndims )
267
264
if np .any (zooms <= 0 ):
268
265
raise HeaderDataError ('zooms must be positive' )
269
- hdr ['voxelsize ' ] = zooms [:3 ]
266
+ hdr ['delta ' ] = zooms [:3 ]
270
267
if len (zooms ) == 4 :
271
268
hdr ['tr' ] = zooms [3 ]
272
269
@@ -292,7 +289,7 @@ def set_data_shape(self, shape):
292
289
if len (shape ) > 4 :
293
290
raise ValueError ("Shape may be at most 4 dimensional" )
294
291
self ._structarr ['dims' ] = shape + (1 ,) * (4 - len (shape ))
295
- self ._structarr ['voxelsize ' ] = 1
292
+ self ._structarr ['delta ' ] = 1
296
293
297
294
def get_data_bytespervox (self ):
298
295
''' Get the number of bytes per voxel of the data
@@ -357,22 +354,18 @@ def default_structarr(klass, endianness=None):
357
354
structarr ['version' ] = 1
358
355
structarr ['dims' ] = 1
359
356
structarr ['type' ] = 3
360
- structarr ['ras_good' ] = 1
361
- structarr ['voxelsize' ] = 1
362
- structarr ['x_ras' ][0 ] = - 1
363
- structarr ['y_ras' ][2 ] = 1
364
- structarr ['z_ras' ][1 ] = - 1
357
+ structarr ['goodRASFlag' ] = 1
358
+ structarr ['delta' ] = 1
359
+ structarr ['Mdc' ] = [[- 1 , 0 , 0 ], [0 , 0 , 1 ], [0 , - 1 , 0 ]]
365
360
return structarr
366
361
367
362
def _set_affine_default (self ):
368
- ''' If ras_good flag is 0, set the default affine
363
+ ''' If goodRASFlag is 0, set the default affine
369
364
'''
370
- self ._structarr ['ras_good' ] = 1
371
- self ._structarr ['voxelsize' ] = 1
372
- self ._structarr ['x_ras' ] = [[- 1 ], [0 ], [0 ]]
373
- self ._structarr ['y_ras' ] = [[0 ], [0 ], [1 ]]
374
- self ._structarr ['z_ras' ] = [[0 ], [- 1 ], [0 ]]
375
- self ._structarr ['c_ras' ] = 0
365
+ self ._structarr ['goodRASFlag' ] = 1
366
+ self ._structarr ['delta' ] = 1
367
+ self ._structarr ['Mdc' ] = [[- 1 , 0 , 0 ], [0 , 0 , 1 ], [0 , - 1 , 0 ]]
368
+ self ._structarr ['Pxyz_c' ] = 0
376
369
377
370
def writehdr_to (self , fileobj ):
378
371
''' Write header to fileobj
@@ -416,35 +409,20 @@ def writeftr_to(self, fileobj):
416
409
417
410
class _HeaderData :
418
411
""" Provide interface to deprecated MGHHeader fields"""
419
- renamed = {'goodRASFlag' : 'ras_good' ,
420
- 'delta' : 'voxelsize' }
421
412
def __init__ (self , structarr ):
422
413
self ._structarr = structarr
423
414
424
415
def __getitem__ (self , item ):
425
416
sa = self ._structarr
426
- if item == 'Mdc' :
427
- return np .hstack ((sa ['x_ras' ], sa ['y_ras' ], sa ['z_ras' ])).T
428
- elif item == 'Pxyz_c' :
429
- return sa ['c_ras' ][:, 0 ]
430
- elif item == 'mrparams' :
417
+ if item == 'mrparams' :
431
418
return np .hstack ((sa ['tr' ], sa ['flip_angle' ], sa ['te' ], sa ['ti' ]))
432
- elif item in self .renamed :
433
- item = self .renamed [item ]
434
419
return sa [item ]
435
420
436
421
def __setitem__ (self , item , val ):
437
422
sa = self ._structarr
438
- if item == 'Mdc' :
439
- sa ['x_ras' ][:, 0 ], sa ['y_ras' ][:, 0 ], sa ['z_ras' ][:, 0 ] = val
440
- elif item == 'Pxyz_c' :
441
- sa ['c_ras' ][:, 0 ] = val
442
- elif item == 'mrparams' :
443
- return sa ['tr' ], sa ['flip_angle' ], sa ['te' ], sa ['ti' ] = val
444
- else :
445
- if item in self .renamed .values ():
446
- item = {v : k for k , v in self .renamed .items ()}[item ]
447
- sa [item ] = val
423
+ if item == 'mrparams' :
424
+ sa ['tr' ], sa ['flip_angle' ], sa ['te' ], sa ['ti' ] = val
425
+ sa [item ] = val
448
426
449
427
@property
450
428
@deprecate_with_version ('_header_data is deprecated.\n '
@@ -457,12 +435,12 @@ def _header_data(self):
457
435
return self ._HeaderData (self ._structarr )
458
436
459
437
def __getitem__ (self , item ):
460
- if item in ( 'goodRASFlag' , 'delta' , 'Mdc' , 'Pxyz_c' , ' mrparams') :
438
+ if item == ' mrparams' :
461
439
return self ._header_data [item ]
462
440
return super (MGHHeader , self ).__getitem__ (item )
463
441
464
442
def __setitem__ (self , item , value ):
465
- if item in ( 'goodRASFlag' , 'delta' , 'Mdc' , 'Pxyz_c' , ' mrparams') :
443
+ if item == ' mrparams' :
466
444
self ._header_data [item ] = value
467
445
super (MGHHeader , self ).__setitem__ (item , value )
468
446
@@ -627,17 +605,17 @@ def _write_data(self, mghfile, data, header):
627
605
def _affine2header (self ):
628
606
""" Unconditionally set affine into the header """
629
607
hdr = self ._header
630
- shape = np .array (self ._dataobj .shape [:3 ]). reshape ( - 1 , 1 )
608
+ shape = np .array (self ._dataobj .shape [:3 ])
631
609
632
610
# for more information, go through save_mgh.m in FreeSurfer dist
633
611
voxelsize = voxel_sizes (self ._affine )
634
612
Mdc = self ._affine [:3 , :3 ] / voxelsize
635
- c_ras = self ._affine .dot (np .vstack ((shape / 2.0 , [1 ])))[:3 ]
613
+ c_ras = self ._affine .dot (np .hstack ((shape / 2.0 , [1 ])))[:3 ]
636
614
637
615
# Assign after we've had a chance to raise exceptions
638
- hdr ['voxelsize ' ] = voxelsize
639
- hdr ['x_ras' ][:, 0 ], hdr [ 'y_ras' ][:, 0 ], hdr [ 'z_ras' ][:, 0 ] = Mdc .T
640
- hdr ['c_ras ' ] = c_ras
616
+ hdr ['delta ' ] = voxelsize
617
+ hdr ['Mdc' ] = Mdc .T
618
+ hdr ['Pxyz_c ' ] = c_ras
641
619
642
620
643
621
load = MGHImage .load
0 commit comments