def reg_flirt(wsp, img, ref, initial_transform=None): """ Register low resolution ASL or calibration data to a high resolution structural image using Flirt rigid-body registration The brain extracted structural image is used as the reference image. If this is not supplied, BET will be run on the whole head structural image. :param reg_img: Data to register, e.g. PWI or calibration image. Normally would be brain extracted :param struc_brain_img: Brain-extracted structural image Optional keyword arguments: :param inweight: :param init: Initial transform matrix :param schedule: FLIRT transform schedule file (default: xyztrans.sch") :param dof: FLIRT degrees of freedom :return Tuple of registered image, transform matrix """ wsp.log.write(" - Registering image: %s using FLIRT\n" % img.name) # Step 1: 3D translation only flirt_opts = { "schedule": os.path.join(os.environ["FSLDIR"], "etc", "flirtsch", "xyztrans.sch"), "init": initial_transform, "inweight": wsp.inweight, "log": wsp.fsllog, } step1_trans = fsl.flirt(img, ref, omat=fsl.LOAD, **flirt_opts)["omat"] # Step 2: 6 DOF transformation with small search region flirt_opts.update({ "schedule": os.path.join(os.environ["FSLDIR"], "etc", "flirtsch", wsp.ifnone("flirtsch", "simple3D.sch")), "init": step1_trans, "dof": wsp.ifnone("dof", 6), }) flirt_result = fsl.flirt(img, ref, out=fsl.LOAD, omat=fsl.LOAD, **flirt_opts) return flirt_result["out"], flirt_result["omat"]
def test_flirt(): with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('flirt', )) as fsldir: flirt = op.join(fsldir, 'bin', 'flirt') result = fw.flirt('src', 'ref', usesqform=True, anglerep='euler') expected = (flirt + ' -in src -ref ref', ('-usesqform', '-anglerep euler')) assert checkResult(result.stdout[0], *expected)
def reg_struc2std(wsp, fnirt=False): """ Determine structural -> standard space registration Optional workspace attributes ----------------------------- - ``structural.struc`` : Structural image - ``fslanat`` : Path to existing FSLANAT data Updated workspace attributes ---------------------------- - ``reg.struc2std`` : Structural->MNI transformation matrix - either warp image or FLIRT matrix - ``reg.std2struc`` : MNI->structural transformation - either warp image or FLIRT matrix """ init(wsp) if wsp.reg.std2struc is not None: return if wsp.fslanat: warp = os.path.join(wsp.fslanat, "T1_to_MNI_nonlin_coeff.nii.gz") mat = os.path.join(wsp.fslanat, "T1_to_MNI_lin.mat") if os.path.isfile(warp): wsp.log.write(" - Using structural->std nonlinear transformation from FSL_ANAT\n") wsp.reg.struc2std = Image(warp, loadData=False) elif os.path.isfile(mat): wsp.log.write(" - Using structural->std linear transformation from FSL_ANAT\n") wsp.reg.struc2std = load_matrix(mat) if wsp.reg.struc2std is None: struc.init(wsp) wsp.log.write(" - Registering structural image to standard space using FLIRT\n") flirt_result = fsl.flirt(wsp.structural.brain, os.path.join(os.environ["FSLDIR"], "data/standard/MNI152_T1_2mm_brain"), omat=fsl.LOAD) wsp.reg.struc2std = flirt_result["omat"] if fnirt: wsp.log.write(" - Registering structural image to standard space using FNIRT\n") fnirt_result = fsl.fnirt(wsp.structural.brain, aff=wsp.reg.struc2std, config="T1_2_MNI152_2mm.cnf", cout=fsl.LOAD) wsp.reg.struc2std = fnirt_result["cout"] if isinstance(wsp.reg.struc2std, Image): # Calculate the inverse warp using INVWARP invwarp_result = fsl.invwarp(wsp.reg.struc2std, wsp.structural.struc, out=fsl.LOAD) wsp.reg.std2struc = invwarp_result["out"] else: wsp.reg.std2struc = np.linalg.inv(wsp.reg.struc2std)
def reg_3d(cls, reg_data, ref_data, options, queue): """ Static function for performing 3D registration """ from fsl import wrappers as fsl reg = qpdata_to_fslimage(reg_data) ref = qpdata_to_fslimage(ref_data) set_environ(options) output_space = options.pop("output-space", "ref") interp = _interp(options.pop("interp-order", 1)) twod = reg_data.grid.shape[2] == 1 logstream = six.StringIO() flirt_output = fsl.flirt(reg, ref, interp=interp, out=fsl.LOAD, omat=fsl.LOAD, twod=twod, log={ "cmd": logstream, "stdout": logstream, "stderr": logstream }, **options) transform = FlirtTransform(ref_data.grid, flirt_output["omat"], name="flirt_xfm") if output_space == "ref": qpdata = fslimage_to_qpdata(flirt_output["out"], reg_data.name) elif output_space == "reg": qpdata = fslimage_to_qpdata(flirt_output["out"], reg_data.name).resample(reg_data.grid, suffix="") qpdata.name = reg_data.name elif output_space == "trans": trans_affine = transform.voxel_to_world(reg_data.grid) trans_grid = DataGrid(reg_data.grid.shape, trans_affine) qpdata = NumpyData(reg_data.raw(), grid=trans_grid, name=reg_data.name) return qpdata, transform, logstream.getvalue()
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