Skip to content
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

FIX: Refactor of LTA implementation #145

Merged
merged 9 commits into from
Feb 16, 2022
5 changes: 0 additions & 5 deletions nitransforms/io/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""Read and write transforms."""
from . import afni, fsl, itk, lta
from .lta import LinearTransform, LinearTransformArray, VolumeGeometry


__all__ = [
"afni",
"fsl",
"itk",
"lta",
"LinearTransform",
"LinearTransformArray",
"VolumeGeometry",
]
108 changes: 45 additions & 63 deletions nitransforms/io/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,24 @@ def __init__(self, binaryblock=None, endianness=None, check=True):
if binaryblock is not None and _dtype == self.dtype:
self._structarr = binaryblock.copy()
return
super(StringBasedStruct, self).__init__(binaryblock, endianness, check)
super().__init__(binaryblock, endianness, check)

def __array__(self):
"""Return the internal structure array."""
return self._structarr

def to_string(self):
"""Convert to a string directly writeable to file."""
raise NotImplementedError

class LinearParameters(StringBasedStruct):
"""
A string-based structure for linear transforms.

Examples
--------
>>> lp = LinearParameters()
>>> np.all(lp.structarr['parameters'] == np.eye(4))
True

>>> p = np.diag([2., 2., 2., 1.])
>>> lp = LinearParameters(p)
>>> np.all(lp.structarr['parameters'] == p)
True
@classmethod
def from_string(cls, string):
"""Read the struct from string."""
raise NotImplementedError

"""

template_dtype = np.dtype([("parameters", "f8", (4, 4))])
dtype = template_dtype

def __init__(self, parameters=None):
"""Initialize with default parameters."""
super().__init__()
self.structarr["parameters"] = np.eye(4)
if parameters is not None:
self.structarr["parameters"] = parameters
class LinearTransformStruct(StringBasedStruct):
"""File data structure from linear transforms."""

def to_filename(self, filename):
"""Store this transform to a file with the appropriate format."""
Expand All @@ -78,12 +63,44 @@ def from_fileobj(cls, fileobj, check=True):
return cls.from_string(fileobj.read())

@classmethod
def from_string(cls, string):
"""Read the struct from string."""
def from_ras(cls, ras, moving=None, reference=None):
"""Create an affine from a nitransform's RAS+ matrix."""
raise NotImplementedError


class BaseLinearTransformList(StringBasedStruct):
class LinearParameters(LinearTransformStruct):
"""
A string-based structure for linear transforms.

Examples
--------
>>> lp = LinearParameters()
>>> np.all(lp.structarr['parameters'] == np.eye(4))
True

>>> p = np.diag([2., 2., 2., 1.])
>>> lp = LinearParameters(p)
>>> np.all(lp.structarr['parameters'] == p)
True

"""

template_dtype = np.dtype([("parameters", "f8", (4, 4))])
dtype = template_dtype

def __init__(self, parameters=None):
"""
Initialize with default parameters.


"""
super().__init__()
self.structarr["parameters"] = np.eye(4)
if parameters is not None:
self.structarr["parameters"] = parameters


class BaseLinearTransformList(LinearTransformStruct):
"""A string-based structure for series of linear transforms."""

template_dtype = np.dtype([("nxforms", "i4")])
Expand Down Expand Up @@ -113,41 +130,6 @@ def __getitem__(self, idx):
return len(self._xforms)
raise KeyError(idx)

def to_filename(self, filename):
"""Store this transform to a file with the appropriate format."""
with open(str(filename), "w") as f:
f.write(self.to_string())

def to_ras(self, moving=None, reference=None):
"""Return a nitransforms' internal RAS matrix."""
raise NotImplementedError

def to_string(self):
"""Convert to a string directly writeable to file."""
raise NotImplementedError

@classmethod
def from_filename(cls, filename):
"""Read the struct from a file given its path."""
with open(str(filename)) as f:
string = f.read()
return cls.from_string(string)

@classmethod
def from_fileobj(cls, fileobj, check=True):
"""Read the struct from a file object."""
return cls.from_string(fileobj.read())

@classmethod
def from_ras(cls, ras, moving=None, reference=None):
"""Create an ITK affine from a nitransform's RAS+ matrix."""
raise NotImplementedError

@classmethod
def from_string(cls, string):
"""Read the struct from string."""
raise NotImplementedError


class DisplacementsField:
"""A data structure representing displacements fields."""
Expand Down
1 change: 0 additions & 1 deletion nitransforms/io/fsl.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ def from_string(cls, string):
if not lines or len(lines) < 4:
raise TransformFileError

print(lines)
sa["parameters"] = np.genfromtxt(
["\n".join(lines)], dtype=cls.dtype["parameters"]
)
Expand Down
Loading