Example #1
0
def test_applywarp():
    with asrt.disabled(), run.dryrun(), mockFSLDIR(
            bin=('applywarp', )) as fsldir:
        applywarp = op.join(fsldir, 'bin', 'applywarp')
        result = fw.applywarp('src',
                              'ref',
                              'out',
                              warp='warp',
                              abs=True,
                              super=True)
        expected = (applywarp + ' --in=src --ref=ref --out=out',
                    ('--warp=warp', '--abs', '--super'))
        assert checkResult(result.stdout[0], *expected)
Example #2
0
    def apply_transform(cls, reg_data, transform, options, queue):
        """
        Apply a previously calculated transformation to a data set
        """
        output_space = options.pop("output-space", "ref")
        if output_space not in ("ref", "reg"):
            raise QpException(
                "FNIRT does not support output in transformed space")

        from fsl import wrappers as fsl
        reg = qpdata_to_fslimage(reg_data)
        trans = qpdata_to_fslimage(transform)

        # Applywarp generates an output for each volume of reference image
        # for some reason. So use just the first volume of the transform
        # as the reference space
        ref = qpdata_to_fslimage(transform.volume(0, qpdata=True))

        log = six.StringIO()
        order = options.pop("interp-order", 1)
        interp = _interp(order)
        apply_output = fsl.applywarp(reg,
                                     ref,
                                     interp=interp,
                                     paddingsize=1,
                                     super=True,
                                     superlevel="a",
                                     out=fsl.LOAD,
                                     log={
                                         "cmd": log,
                                         "stdout": log,
                                         "stderr": log
                                     },
                                     warp=trans,
                                     rel=True)
        qpdata = fslimage_to_qpdata(apply_output["out"], name=reg_data.name)

        if output_space == "ref":
            # Default is to output in reference space
            pass
        else:
            qpdata = qpdata.resample(reg_data.grid, suffix="", order=order)
            log += "Resampling onto input grid\n"

        return qpdata, log.getvalue()
def _transform(img,
               warp,
               ref,
               premat=None,
               postmat=None,
               interp="trilinear",
               paddingsize=1,
               output_is_roi=False,
               output_roi_thresh=0.5):
    """
    Transform an image

    :param img: fsl.data.Image containing image to transform
    :param warp: Transformation matrix or warp image
    :param ref:  fsl.data.Image containing reference image
    :param premat: Optional Pre-warp affine transformation matrix
    :param premat: Optional Post-warp affine transformation matrix
    :param interp: Interpolation method
    :param paddingsize: Padding size in pixels
    :param output_is_roi: Output should be binarized as an ROI
    :param output_roi_threshold: Thresholding value for binarizing output ROI

    :return:  fsl.data.Image containing transformed image
    """
    kwargs = {
        "warp": warp,
        "premat": premat,
        "postmat": postmat,
        "rel": True,
        "super": True,
        "superlevel": "a",
        "interp": interp,
        "paddingsize": paddingsize,
    }
    ret = fsl.applywarp(img, ref, out=fsl.LOAD, **kwargs)["out"]

    if output_is_roi:
        # Binarise mask images
        ret = Image((ret.data > output_roi_threshold).astype(np.int),
                    header=ret.header)
    return ret
Example #4
0
def transform(wsp, img, trans, ref, use_flirt=False, interp="trilinear", paddingsize=1, premat=None, mask=False, mask_thresh=0.5):
    """
    Transform an image

    :param wsp: Workspace, used for logging only
    :param img: Image to transform
    :param trans: Transformation matrix or warp image
    :param ref: Reference image
    :param use_flirt: Use flirt to apply the transformation which must be a matrix
    :param interp: Interpolation method
    :param paddingsize: Padding size in pixels
    :param premat: If trans is a warp, this can be set to a pre-warp affine transformation matrix

    :return: Transformed Image object
    """
    if trans is None:
        raise ValueError("Transformation matrix not available - has registration been performed?")

    have_warp = isinstance(trans, Image)
    if use_flirt and have_warp:
        raise ValueError("Cannot transform using Flirt when we have a warp")
    elif use_flirt:
        if interp == "nn":
            interp = "nearestneighbour"
        ret = fsl.applyxfm(img, ref, trans, out=fsl.LOAD, interp=interp, paddingsize=paddingsize, log=wsp.fsllog)["out"]
    else:
        if have_warp:
            kwargs = {"warp" : trans, "premat" : premat, "rel" : True}
        elif premat:
            raise ValueError("Can't set a pre-transformation matrix unless using a warp")
        else:
            kwargs = {"premat" : trans}
        ret = fsl.applywarp(img, ref, out=fsl.LOAD, interp=interp, paddingsize=paddingsize, super=True, superlevel="a", log=wsp.fsllog, **kwargs)["out"]
    if mask:
        # Binarise mask images
        ret = Image((ret.data > mask_thresh).astype(np.int), header=ret.header)
    return ret
Example #5
0
def epi_reg(wsp, epi_img, use_fmap=False, **kwargs):
    """
    Do EPI registration
    """
    struc.segment(wsp)
    wmseg = wsp.structural.wm_seg
    bbr_sch = os.path.join(os.environ["FSLDIR"], "etc/flirtsch/bbr.sch")

    if wsp.asl2struc is None:
        # Do pre-alignment in the same was as epi_reg
        wsp.asl2struc = fsl.flirt(epi_img,
                                  ref=wsp.structural.brain,
                                  omat=fsl.LOAD,
                                  dof=6,
                                  log=wsp.fsllog)["omat"]

    if not use_fmap:
        wsp.log.write(" - Running BBR\n")
        trans = fsl.flirt(epi_img,
                          ref=wsp.structural.struc,
                          dof=6,
                          cost="bbr",
                          wmseg=wmseg,
                          init=wsp.asl2struc,
                          omat=fsl.LOAD,
                          out=fsl.LOAD,
                          schedule=bbr_sch,
                          log=wsp.fsllog)["omat"]
        out_img = fsl.applywarp(epi_img,
                                ref=wsp.structural.struc,
                                out=fsl.LOAD,
                                premat=trans,
                                interp="spline",
                                log=wsp.fsllog)["out"]
        return {"out.nii.gz": out_img, "out": trans}
    else:
        dirmap = {
            "x": (1, "x"),
            "y": (2, "y"),
            "z": (3, "z"),
            "-x": (-1, "x-"),
            "-y": (-2, "y-"),
            "-z": (-3, "z-"),
            "x-": (-1, "x-"),
            "y-": (-2, "y-"),
            "z-": (-3, "z-"),
        }
        pedir, fdir = dirmap.get(wsp.pedir, (None, None))
        if pedir is None:
            raise ValueError("Invalid phase encode direction specified: %s" %
                             wsp.pedir)

        if wsp.nofmapreg:
            wsp.fmap2struc = np.identity(4)
            wsp.fmapmag_struc = wsp.fmapmag
        else:
            # Register fmap to structural image
            wsp.log.write(" - Registering fieldmap to structural\n")
            wsp.fmap2struc = fsl.flirt(wsp.fmapmagbrain,
                                       ref=wsp.structural.brain,
                                       dof=6,
                                       omat=fsl.LOAD)["omat"]
            flirt_result = fsl.flirt(wsp.fmapmag,
                                     ref=wsp.structural.struc,
                                     dof=6,
                                     init=wsp.fmap2struc,
                                     omat=fsl.LOAD,
                                     out=fsl.LOAD,
                                     nosearch=True)
            wsp.fmap2struc = flirt_result["omat"]
            wsp.fmapmag_struc = flirt_result["out"]

        # Unmask the fieldmap (necessary to avoid edge effects)
        wsp.fmap_mask = fsl.fslmaths(wsp.fmapmagbrain).abs().bin().run()
        wsp.fmap_mask = fsl.fslmaths(wsp.fmap).abs().bin().mul(
            wsp.fmap_mask).run()

        # The direction here should take into account the initial affine (it needs to be the direction in the EPI)
        wsp.fmap_unmasked = fsl.fugue(loadfmap=wsp.fmap,
                                      mask=wsp.fmap_mask,
                                      unmaskfmap=True,
                                      savefmap=fsl.LOAD,
                                      unwarpdir=fdir)["out"]

        # The following is a NEW HACK to fix extrapolation when fieldmap is too small
        wsp.fmap_struc_pad0 = fsl.applywarp(wsp.fmap_unmasked,
                                            ref=wsp.structural.struc,
                                            premat=wsp.fmap2struc,
                                            out=fsl.LOAD)["out"]
        wsp.fmap_struc_innermask = fsl.fslmaths(
            wsp.fmap_struc_pad0).abs().bin().run()
        wsp.fmap_struc_dilated = fsl.fugue(loadfmap=wsp.fmap_struc_pad0,
                                           mask=wsp.fmap_struc_innermask,
                                           unmaskfmap=True,
                                           unwarpdir=fdir,
                                           savefmap=fsl.LOAD)["savefmap"]
        wsp.fmap_struc = wsp.fmap_struc_dilated

        # Run bbr with fieldmap
        wsp.log.write("Running BBR with fieldmap\n")
        if not wsp.epi_reg_use_weighting:
            refweight = None

        wsp.reg.epi2struc = fsl.flirt(epi_img,
                                      ref=wsp.structural.struc,
                                      dof=6,
                                      cost="bbr",
                                      wmseg=wmseg,
                                      init=wsp.reg.asl2struc,
                                      omat=fsl.LOAD,
                                      schedule=bbr_sch,
                                      echospacing=wsp.echospacing,
                                      pedir=pedir,
                                      fieldmap=wsp.fmap_struc,
                                      refweight=refweight)["omat"]

        # Make equivalent warp fields
        wsp.log.write(
            "Making warp fields and applying registration to EPI series\n")
        wsp.reg.struc2epi = np.linalg.inv(wsp.reg.epi2struc)
        fsl.concatxfm(wsp.reg.struc2epi, wsp.fmap2struc, outmat=fsl.LOAD)
        fsl.applywarp(wsp.fmap, ref=epi_img, premat=wsp.fmap2epi, out=fsl.LOAD)
        wsp.fmap2epi_mask = fsl.fslmaths(wsp.fmap2epi).abs().bin().run()
        # ${vout}_fieldmaprads2epi -abs -bin ${vout}_fieldmaprads2epi_mask
        ret = fsl.fugue(loadfmap=wsp.fmap2epi,
                        mask=wsp.fmap2epi_mask,
                        saveshift=fsl.LOAD,
                        unmaskshift=True,
                        dwell=wsp.dwell,
                        unwarpdir=fdir)
        print(ret)
        wsp.fmap2epi_shift = ret["fieldmaprads2epi_shift"]
        ret = fsl.convertwarp(wsp.structural.struc,
                              s=wsp.fmap2epi_shift,
                              postmat=wsp.epi2struc,
                              out=fsl.LOAD,
                              shiftdir=fdir,
                              relout=True)
        print(ret)
        warp = ret["out"]
        ret = fsl.applywarp(epi_img,
                            ref=wsp.structural.struc,
                            out=fsl.LOAD,
                            warp1=warp,
                            interp="spline",
                            rel=True)
        print(ret)
        return ret["out"], warp