2
2
import warnings
3
3
import numpy as np
4
4
from scipy .io import loadmat as _read_mat , savemat as _save_mat
5
+ from h5py import File as H5File
5
6
from nibabel import Nifti1Header , Nifti1Image
6
7
from nibabel .affines import from_matvec
7
8
from .base import (
@@ -112,6 +113,9 @@ def from_filename(cls, filename):
112
113
if str (filename ).endswith (".mat" ):
113
114
with open (str (filename ), "rb" ) as fileobj :
114
115
return cls .from_binary (fileobj )
116
+ elif str (filename ).endswith (".h5" ):
117
+ with H5File (str (filename )) as f :
118
+ return cls .from_h5obj (f )
115
119
116
120
with open (str (filename )) as fileobj :
117
121
return cls .from_string (fileobj .read ())
@@ -121,6 +125,10 @@ def from_fileobj(cls, fileobj, check=True):
121
125
"""Read the struct from a file object."""
122
126
if fileobj .name .endswith (".mat" ):
123
127
return cls .from_binary (fileobj )
128
+ elif fileobj .name .endswith (".h5" ):
129
+ with H5File (fileobj ) as f :
130
+ return cls .from_h5obj (f )
131
+
124
132
return cls .from_string (fileobj .read ())
125
133
126
134
@classmethod
@@ -145,6 +153,11 @@ def from_matlab_dict(cls, mdict, index=0):
145
153
sa ["offset" ] = mdict ["fixed" ].flatten ()
146
154
return tf
147
155
156
+ @classmethod
157
+ def from_h5obj (cls , fileobj , check = True ):
158
+ """Read the struct from a file object."""
159
+ raise NotImplementedError
160
+
148
161
@classmethod
149
162
def from_ras (cls , ras , index = 0 , moving = None , reference = None ):
150
163
"""Create an ITK affine from a nitransform's RAS+ matrix."""
@@ -225,6 +238,9 @@ def from_filename(cls, filename):
225
238
if str (filename ).endswith (".mat" ):
226
239
with open (str (filename ), "rb" ) as f :
227
240
return cls .from_binary (f )
241
+ elif str (filename ).endswith (".h5" ):
242
+ with H5File (str (filename )) as f :
243
+ return cls .from_h5obj (f )
228
244
229
245
with open (str (filename )) as f :
230
246
string = f .read ()
@@ -235,6 +251,10 @@ def from_fileobj(cls, fileobj, check=True):
235
251
"""Read the struct from a file object."""
236
252
if fileobj .name .endswith (".mat" ):
237
253
return cls .from_binary (fileobj )
254
+
255
+ elif fileobj .name .endswith (".h5" ):
256
+ with H5File (fileobj ) as f :
257
+ return cls .from_h5obj (f )
238
258
return cls .from_string (fileobj .read ())
239
259
240
260
@classmethod
@@ -272,6 +292,31 @@ def from_string(cls, string):
272
292
_self .xforms .append (cls ._inner_type .from_string ("#%s" % xfm ))
273
293
return _self
274
294
295
+ @classmethod
296
+ def from_h5obj (cls , fileobj , check = True ):
297
+ """Read the struct from a file object."""
298
+ h5group = fileobj ["TransformGroup" ]
299
+ typo_fallback = "Transform"
300
+ try :
301
+ h5group ["1" ][f"{ typo_fallback } Parameters" ]
302
+ except KeyError :
303
+ typo_fallback = "Tranform"
304
+
305
+ _self = cls ()
306
+ _self .xforms = []
307
+ for xfm in list (h5group .values ())[1 :]:
308
+ if xfm ["TransformType" ][0 ].startswith (b"AffineTransform" ):
309
+ _params = np .asanyarray (xfm [f"{ typo_fallback } Parameters" ])
310
+ _self .xforms .append (
311
+ ITKLinearTransform (
312
+ parameters = from_matvec (
313
+ _params [:- 3 ].reshape (3 , 3 ), _params [- 3 :]
314
+ ),
315
+ offset = np .asanyarray (xfm [f"{ typo_fallback } FixedParameters" ]),
316
+ )
317
+ )
318
+ return _self
319
+
275
320
276
321
class ITKDisplacementsField (DisplacementsField ):
277
322
"""A data structure representing displacements fields."""
@@ -304,8 +349,6 @@ class ITKCompositeH5:
304
349
@classmethod
305
350
def from_filename (cls , filename ):
306
351
"""Read the struct from a file given its path."""
307
- from h5py import File as H5File
308
-
309
352
if not str (filename ).endswith (".h5" ):
310
353
raise TransformFileError ("Extension is not .h5" )
311
354
0 commit comments