Skip to content

ENH: Load ITK's .mat files with Affine's loaders #179

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 10, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion nitransforms/io/itk.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,14 @@ def from_string(cls, string):
parameters[:3, :3] = vals[:-3].reshape((3, 3))
parameters[:3, 3] = vals[-3:]
sa["parameters"] = parameters
return tf

# Try to double-dip and see if there are more transforms
try:
cls.from_string("\n".join(lines[4:8]))
except TransformFileError:
return tf
else:
raise TransformFileError("More than one linear transform found.")


class ITKLinearTransformArray(BaseLinearTransformList):
Expand Down
37 changes: 27 additions & 10 deletions nitransforms/linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,33 @@ def from_filename(cls, filename, fmt=None, reference=None, moving=None):
"""Create an affine from a transform file."""
fmtlist = [fmt] if fmt is not None else ("itk", "lta", "afni", "fsl")

is_array = cls != Affine

errors = []
for potential_fmt in fmtlist:
if (potential_fmt == "itk" and Path(filename).suffix == ".mat"):
is_array = False
cls = Affine

try:
struct = get_linear_factory(potential_fmt).from_filename(filename)
matrix = struct.to_ras(reference=reference, moving=moving)
if cls == Affine:
if np.shape(matrix)[0] != 1:
raise TypeError("Cannot load transform array '%s'" % filename)
matrix = matrix[0]
return cls(matrix, reference=reference)
except (TransformFileError, FileNotFoundError):
struct = get_linear_factory(
potential_fmt,
is_array=is_array
).from_filename(filename)
except (TransformFileError, FileNotFoundError) as err:
errors.append((potential_fmt, err))
continue

matrix = struct.to_ras(reference=reference, moving=moving)

# Process matrix
if not is_array and np.ndim(matrix) == 3:
if np.shape(matrix)[0] != 1:
raise TypeError("Cannot load transform array '%s'" % filename)
matrix = matrix[0]

return cls(matrix, reference=reference)

raise TransformFileError(
f"Could not open <{filename}> (formats tried: {', '.join(fmtlist)})."
)
Expand Down Expand Up @@ -499,6 +514,8 @@ def load(filename, fmt=None, reference=None, moving=None):
xfm = LinearTransformsMapping.from_filename(
filename, fmt=fmt, reference=reference, moving=moving
)
if len(xfm) == 1:
return xfm[0]

if isinstance(xfm, LinearTransformsMapping) and len(xfm) == 1:
xfm = xfm[0]

return xfm
2 changes: 1 addition & 1 deletion nitransforms/tests/test_linear.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_linear_typeerrors1(matrix):

def test_linear_typeerrors2(data_path):
"""Exercise errors in Affine creation."""
with pytest.raises(TypeError):
with pytest.raises(io.TransformFileError):
nitl.Affine.from_filename(data_path / "itktflist.tfm", fmt="itk")


Expand Down