Skip to content

Commit

Permalink
Merge pull request #525 from oesteban/enh/524-upstream-nitransforms
Browse files Browse the repository at this point in the history
ENH: Upstream NiTransforms module from fMRIPrep
  • Loading branch information
oesteban authored May 21, 2020
2 parents 0250265 + cdaff49 commit 1e09f47
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ git+https://github.com/AleksandarPetrov/napoleon.git@0dc3f28a309ad602be5f44a9049
git+https://github.com/rwblair/sphinxcontrib-versioning.git@39b40b0b84bf872fc398feff05344051bbce0f63#egg=sphinxcontrib-versioning
nbsphinx
nipype>=1.3.1
nitransforms >= 20.0.0rc3,<20.2
packaging
pydot>=1.2.3
pydotplus
Expand Down
81 changes: 81 additions & 0 deletions niworkflows/interfaces/nitransforms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
"""Wrappers of NiTransforms."""

from pathlib import Path
from nipype.interfaces.base import (
TraitedSpec, BaseInterfaceInputSpec, File,
SimpleInterface, InputMultiObject,
traits, isdefined,
)
from nitransforms.manip import TransformChain
from nitransforms.linear import load as load_affine

XFM_FMT = {
".lta": "fs",
".txt": "itk",
".mat": "itk",
".tfm": "itk",
}


class _ConcatenateXFMsInputSpec(BaseInterfaceInputSpec):
in_xfms = InputMultiObject(File(exists=True), desc="input transform piles")
inverse = traits.Bool(False, usedefault=True, desc="generate inverse")
out_fmt = traits.Enum("itk", "fs", usedefault=True, desc="output format")
reference = File(exists=True, desc="reference file (only for writing LTA format, if not "
"concatenating another LTA).")
moving = File(exists=True, desc="moving file (only for writing LTA format, if not "
"concatenating another LTA).")


class _ConcatenateXFMsOutputSpec(TraitedSpec):
out_xfm = File(exists=True, desc="output, combined transform")
out_inv = File(desc="output, combined transform")


class ConcatenateXFMs(SimpleInterface):
"""Write a single, flattened transform file."""

input_spec = _ConcatenateXFMsInputSpec
output_spec = _ConcatenateXFMsOutputSpec

def _run_interface(self, runtime):
out_ext = "lta" if self.inputs.out_fmt == "fs" else "tfm"
reference = self.inputs.reference if isdefined(self.inputs.reference) else None
moving = self.inputs.moving if isdefined(self.inputs.moving) else None
out_file = Path(runtime.cwd) / f"out_fwd.{out_ext}"
self._results["out_xfm"] = str(out_file)
out_inv = None
if self.inputs.inverse:
out_inv = Path(runtime.cwd) / f"out_inv.{out_ext}"
self._results["out_inv"] = str(out_inv)

concatenate_xfms(self.inputs.in_xfms, out_file, out_inv,
reference=reference, moving=moving,
fmt=self.inputs.out_fmt)
return runtime


def concatenate_xfms(
in_files,
out_file,
out_inv=None,
reference=None,
moving=None,
fmt="itk"
):
"""Concatenate linear transforms."""
xfm = TransformChain(
[load_affine(f, fmt=XFM_FMT[Path(f).suffix]) for f in in_files]
).asaffine()
if reference is not None and not xfm.reference:
xfm.reference = reference

xfm.to_filename(out_file, moving=moving, fmt=fmt)

if out_inv is not None:
inv_xfm = ~xfm
if moving is not None:
inv_xfm.reference = moving
inv_xfm.to_filename(out_inv, moving=reference, fmt=fmt)
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ install_requires =
nibabel >= 3.0.1
nilearn >= 0.2.6, != 0.5.0, != 0.5.1
nipype >= 1.3.1
nitransforms >= 20.0.0rc3,<20.2
packaging
pandas
pybids >= 0.10.2
Expand Down

0 comments on commit 1e09f47

Please sign in to comment.