示例#1
0
def _WarpImage(dwimask, vol, xfm):

    if dwimask:
        unu('3op', 'ifelse', dwimask, vol, '0', '-o', vol)
    volwarped = vol.stem + '-warped.nrrd'
    WarpImageMultiTransform('3', vol, volwarped, '-R', vol,
                            xfm)
    return volwarped
示例#2
0
 def main(self):
     hdr = unu('head', self.nrrd)[:-1]
     new_origin = centered_origin(hdr)
     unu('save', '-e', 'gzip', '-f', 'nrrd', '-i', self.nrrd, '-o',
         self.out)
     replace_line_in_file(
         self.out, "space origin: ",
         "space origin: (%s, %s, %s)\n" % tuple(new_origin))
示例#3
0
    def main(self):
        with TemporaryDirectory() as tmpdir:
            tmpdir = local.path(tmpdir)
            bse           = tmpdir / "maskedbse.nrrd"
            t2masked      = tmpdir / "maskedt2.nrrd"
            t2inbse       = tmpdir / "t2inbse.nrrd"
            epiwarp       = tmpdir / "epiwarp.nii.gz"
            t2tobse_rigid = tmpdir / "t2tobse_rigid"

            logging.info('1. Extract and mask the DWI b0')
            bse_py('-m', self.dwimask ,'-i', self.dwi ,'-o', bse)

            logging.info("2. Mask the T2")
            unu("3op", "ifelse", self.t2mask, self.t2, "0", "-o", t2masked)

            logging.info(
                "3. Compute a rigid registration from the T2 to the DWI baseline")
            antsRegistrationSyN_sh("-d", "3"
                                   ,"-f", bse
                                   ,"-m", t2masked
                                   ,"-t", "r"
                                   ,"-o", tmpdir / "t2tobse_rigid")
            antsApplyTransforms("-d", "3"
                                ,"-i", t2masked
                                ,"-o", t2inbse
                                ,"-r", bse
                                ,"-t", tmpdir / "t2tobse_rigid0GenericAffine.mat")

            logging.info("4. Compute 1d nonlinear registration from the DWI to the T2 along the phase direction")
            moving = bse
            fixed  = t2inbse
            pre    = tmpdir / "epi"
            dwiepi = tmpdir / "dwiepi"+getext(self.out)
            antsRegistration("-d", "3"
                             ,"-m", "cc["+fixed+","+moving+",1,2]"
                             ,"-t", "SyN[0.25,3,0]"
                             ,"-c", "50x50x10"
                             ,"-f", "4x2x1"
                             , "-s", "2x1x0"
                             ,"--restrict-deformation", "0x1x0"
                             ,"-v", "1"
                             ,"-o", pre)

            local.path(pre+"0Warp.nii.gz").move(epiwarp)

            logging.info("5. Apply warp to the DWI")
            antsApplyTransformsDWI_sh(self.dwi, self.dwimask, epiwarp, dwiepi)

            if getext(dwiepi) == '.nhdr':
                unu("save","-e","gzip","-f","nrrd","-i",dwiepi,self.out)
            else:
                dwiepi.move(self.out)

            if self.debug:
                tmpdir.move("epidebug-"+getpid())
示例#4
0
    def main(self):
        if not self.force and self.out.exists():
            logging.error("'{}' already exists, use '--force' to force overwrite.".format(self.out))
            sys.exit(1)
        with TemporaryDirectory() as tmpdir:
            tmpdir = local.path(tmpdir)
            bse = tmpdir / "maskedbse.nrrd"
            t2masked = tmpdir / "maskedt2.nrrd"
            t2inbse = tmpdir / "t2inbse.nrrd"
            epiwarp = tmpdir / "epiwarp.nii.gz"
            t2tobse_rigid = tmpdir / "t2tobse_rigid"

            logging.info('1. Extract and mask the DWI b0')
            bse_py('-m', self.dwimask, '-i', self.dwi, '-o', bse)

            logging.info("2. Mask the T2")
            unu("3op", "ifelse", self.t2mask, self.t2, "0", "-o", t2masked)

            logging.info(
                "3. Compute a rigid registration from the T2 to the DWI baseline")
            antsRegistrationSyN_sh("-d", "3", "-f", bse, "-m", t2masked, "-t",
                                   "r", "-o", tmpdir / "t2tobse_rigid")
            antsApplyTransforms("-d", "3", "-i", t2masked, "-o", t2inbse, "-r",
                                bse, "-t",
                                tmpdir / "t2tobse_rigid0GenericAffine.mat")

            logging.info(
                "4. Compute 1d nonlinear registration from the DWI to the T2 along the phase direction")
            moving = bse
            fixed = t2inbse
            pre = tmpdir / "epi"
            dwiepi = tmpdir / ("dwiepi" + ''.join(self.out.suffixes))
            antsRegistration("-d", "3", "-m",
                             "cc[" + str(fixed) + "," + str(moving) + ",1,2]", "-t",
                             "SyN[0.25,3,0]", "-c", "50x50x10", "-f", "4x2x1",
                             "-s", "2x1x0", "--restrict-deformation", "0x1x0",
                             "-v", "1", "-o", pre)

            local.path(str(pre) + "0Warp.nii.gz").move(epiwarp)

            logging.info("5. Apply warp to the DWI")
            antsApplyTransformsDWI_py('-i', self.dwi, '-m', self.dwimask, '-t', epiwarp, '-o', dwiepi)

            if '.nhdr' in dwiepi.suffixes:
                unu("save", "-e", "gzip", "-f", "nrrd", "-i", dwiepi, self.out)
            else:
                dwiepi.move(self.out)

            if self.debug:
                tmpdir.copy(self.out.dirname / ("epidebug-" + str(getpid())))
示例#5
0
def test_DWIConvert():
    with TemporaryDirectory() as tmpdir:
        fsl = tmpdir / 'dwi.nii.gz'
        nrrd = tmpdir / 'dwi.nrrd'
        nrrdFromFSl = tmpdir / 'dwi-from-fsl.nrrd'
        run(dwidicoms, fsl)
        run(dwidicoms, nrrd)
        run(fsl, nrrdfromFsl)
        output = unu('diff', nrrd, nrrdFromFSl)
        assert not 'differ' in output
示例#6
0
def nrrd_get_b0_index(dwi):
    dwi = local.path(dwi)
    hdr = unu("head", dwi)[:-1]
    def norm(vector):
        return sum([v**2 for v in vector])
    bval = get_bval(hdr)
    bvals = [norm(gdir) * bval for gdir in get_grad_dirs(hdr)]
    idx, min_bval = min(enumerate(bvals), key=operator.itemgetter(1))
    logger.info("Found B0 of " + str(min_bval) + " at index " + str(idx))
    return idx
示例#7
0
    def main(self):
        hdr = unu("head", self.dwi)[:-1]
        idx = get_b0_index(hdr)

        slicecmd = unu["slice", "-a", "3", "-p", str(idx), "-i", self.dwi]
        gzipcmd = unu["save", "-e", "gzip", "-f", "nrrd", "-o", self.out]
        if self.dwimask:
            maskcmd = unu["3op", "ifelse", "-w", "1", self.dwimask, "-", "0"]
            (slicecmd | maskcmd | gzipcmd) & FG
        else:
            (slicecmd | gzipcmd) & FG
    def main(self):
        with TemporaryDirectory() as tmpdir, local.cwd(tmpdir):
            tmpdir = local.path(tmpdir)
            dicePrefix = 'dwi'

            logging.info("Dice DWI")
            (unu['convert', '-t', 'int16', '-i', self.dwi] | \
                unu['dice','-a','3','-o',dicePrefix]) & FG

            logging.info("Apply warp to each DWI volume")
            vols = sorted(tmpdir // (dicePrefix + '*'))
            volsWarped = []
            for vol in vols:
                if self.dwimask:
                    unu('3op', 'ifelse', self.dwimask, vol, '0', '-o', vol)
                volwarped = vol.stem + '-warped.nrrd'
                WarpImageMultiTransform('3', vol, volwarped, '-R', vol,
                                        self.xfm)
                unu('convert', '-t', 'int16', '-i', volwarped, '-o', volwarped)
                volsWarped.append(volwarped)

            logging.info("Join warped volumes together")
            (unu['join', '-a', '3', '-i', volsWarped] | \
                unu['save', '-e', 'gzip', '-f', 'nrrd'] | \
                unu['data','-'] > 'tmpdwi.raw.gz') & FG

            logging.info(
                "Create new nrrd header pointing to the newly generated data file"
            )
            unu('save', '-e', 'gzip', '-f', 'nrrd', '-i', self.dwi, '-o',
                'dwi.nhdr')
            with open("dwi.nhdr", "r") as hdr:
                lines = hdr.readlines()
            with open("dwi.nhdr", "w") as hdr:
                for line in lines:
                    hdr.write(
                        re.sub(r'^data file:.*$', 'data file: tmpdwi.raw.gz',
                               line))

            logging.info('Make ' + str(self.out))
            unu('save', '-e', 'gzip', '-f', 'nrrd', '-i', 'dwi.nhdr', '-o',
                self.out)
            logging.info('Made ' + str(self.out))

            if self.debug:
                from os import getpid
                pid = str(getpid())
                d = local.path(self.out.dirname /
                               ('antsApplyTransformsDWi-' + pid))
                tmpdir.copy(d)
示例#9
0
    def main(self):
        with TemporaryDirectory() as tmpdir, local.cwd(tmpdir):
            tmpdir = local.path(tmpdir)
            dicePrefix = 'dwi'

            logging.info("Dice DWI")
            unu['dice','-a','3','-i',self.dwi,'-o',dicePrefix] & FG

            logging.info("Apply warp to each DWI volume")
            vols = sorted(tmpdir // (dicePrefix + '*'))

            # use the following multi-processed loop
            pool= Pool(int(self.nproc))
            res= []
            for vol in vols:
                res.append(pool.apply_async(_WarpImage, (self.dwimask, vol, self.xfm)))

            volsWarped= [r.get() for r in res]
            pool.close()
            pool.join()


            # or use the following for loop
            # volsWarped = []
            # for vol in vols:
            #     if self.dwimask:
            #         unu('3op','ifelse',self.dwimask,vol,'0','-o',vol)
            #     volwarped = vol.stem + '-warped.nrrd'
            #     WarpImageMultiTransform('3', vol, volwarped, '-R', vol,
            #                             self.xfm)
            #     volsWarped.append(volwarped)
            #
            # logging.info("Join warped volumes together")


            (unu['join', '-a', '3', '-i', volsWarped] | \
                unu['save', '-e', 'gzip', '-f', 'nrrd', '-o', 'dwi.nhdr']) & FG

            # get data type
            with open("dwi.nhdr", "r") as hdr:
                lines = hdr.readlines()
                for line in lines:
                    if 'type' in line:
                        typeline=line

            logging.info(
                "Create new nrrd header pointing to the newly generated data file")

            unu('save', '-e', 'gzip', '-f', 'nrrd', '-i', self.dwi, '-o', 'tmpdwi.nhdr')

            # get other header fields
            with open("tmpdwi.nhdr", "r") as hdr:
                lines = hdr.readlines()

            with open("dwi.nhdr", "w") as hdr:
                for line in lines:
                    if 'data file' in line:
                        hdr.write('data file: dwi.raw.gz\n')
                    elif 'type' in line:
                        hdr.write(typeline)
                    else:
                        hdr.write(line)

            logging.info('Make ' + str(self.out))
            unu('save', '-e', 'gzip', '-f', 'nrrd', '-i', 'dwi.nhdr', '-o',
                self.out)
            logging.info('Made ' + str(self.out))

            if self.debug:
                from os import getpid
                pid = str(getpid())
                d = local.path(self.out.dirname /
                               ('antsApplyTransformsDWi-' + pid))
                tmpdir.copy(d)
示例#10
0
    def main(self):
        if not self.force and self.out.exists():
            logging.error(
                "'{}' already exists, use '--force' to force overwrite.".
                format(self.out))
            sys.exit(1)
        with TemporaryDirectory() as tmpdir:
            tmpdir = local.path(tmpdir)
            bse = tmpdir / "maskedbse.nrrd"
            t2masked = tmpdir / "maskedt2.nrrd"
            t2inbse = tmpdir / "t2inbse.nrrd"
            epiwarp = tmpdir / "epiwarp.nii.gz"

            t2tobse_rigid = tmpdir / "t2tobse_rigid"
            affine = tmpdir / "t2tobse_rigid0GenericAffine.mat"

            logging.info('1. Extract and mask the DWI b0')
            bse_py('-m', self.dwimask, '-i', self.dwi, '-o', bse)

            logging.info("2. Mask the T2")
            unu("3op", "ifelse", self.t2mask, self.t2, "0", "-o", t2masked)

            logging.info(
                "3. Compute a rigid registration from the T2 to the DWI baseline"
            )
            antsRegistrationSyN_sh("-d", "3", "-f", bse, "-m", t2masked, "-t",
                                   "r", "-o", tmpdir / "t2tobse_rigid")

            antsApplyTransforms("-d", "3", "-i", t2masked, "-o", t2inbse, "-r",
                                bse, "-t", affine)

            logging.info(
                "4. Compute 1d nonlinear registration from the DWI to the T2 along the phase direction"
            )
            moving = bse
            fixed = t2inbse
            pre = tmpdir / "epi"
            dwiepi = tmpdir / ("dwiepi" + ''.join(self.out.suffixes))
            antsRegistration("-d", "3", "-m",
                             "cc[" + str(fixed) + "," + str(moving) + ",1,2]",
                             "-t", "SyN[0.25,3,0]", "-c", "50x50x10", "-f",
                             "4x2x1", "-s", "2x1x0", "--restrict-deformation",
                             "0x1x0", "-v", "1", "-o", pre)

            local.path(str(pre) + "0Warp.nii.gz").move(epiwarp)

            logging.info("5. Apply warp to the DWI")
            antsApplyTransformsDWI_py['-i', self.dwi, '-m', self.dwimask, '-t',
                                      epiwarp, '-o', dwiepi, '-n',
                                      str(self.nproc)] & FG

            logging.info('6. Apply warp to the DWI mask')
            epimask = self.out.dirname / self.out.basename.split(
                '.')[0] + '-mask.nrrd'
            antsApplyTransforms('-d', '3', '-i', self.dwimask, '-o', epimask,
                                '-n', 'NearestNeighbor', '-r', bse, '-t',
                                epiwarp)
            unu('convert', '-t', 'uchar', '-i', epimask, '-o', epimask)

            if '.nhdr' in dwiepi.suffixes:
                unu("save", "-e", "gzip", "-f", "nrrd", "-i", dwiepi, "-o",
                    self.out)
            else:
                dwiepi.move(self.out)

            # FIXME: the following conversion is only for UKFTractography, should be removed in future
            if self.typeCast:
                unu('convert', '-t', 'int16', '-i', self.out, '-o', self.out)

            if self.debug:
                tmpdir.copy(self.out.dirname / ("epidebug-" + str(getpid())))
示例#11
0
    def main(self):
        self.out = local.path(self.out)
        if self.out.exists():
            if self.overwrite:
                self.out.delete()
            else:
                logging.error(
                    "{} exists, use '--force' to overwrite it".format(
                        self.out))
                sys.exit(1)
        outxfms = self.out.dirname / self.out.stem + '-xfms.tgz'
        with TemporaryDirectory() as tmpdir, local.cwd(tmpdir):
            tmpdir = local.path(tmpdir)

            unu('save', '-f', 'nrrd', '-e', 'gzip', '-i', self.dwi, '-o',
                'dwijoined.nhdr')

            logging.info('Dice the DWI')
            (unu['convert', '-t', 'int16', '-i', 'dwijoined.nhdr']
             | unu['dice', '-a', '3', '-o', 'Diffusion-G'])()
            vols = tmpdir.glob('Diffusion-G*.nrrd')
            vols.sort()

            logging.info('Extract the B0')
            bse_py('-i', 'dwijoined.nhdr', '-o', 'b0.nrrd')
            ConvertBetweenFileFormats('b0.nrrd', 'b0.nii.gz', 'short')

            logging.info('Register each volume to the B0')
            volsRegistered = []
            for vol in vols:
                volnii = vol.with_suffix('.nii.gz')
                ConvertBetweenFileFormats(vol, volnii, 'short')
                logging.info('Run FSL flirt affine registration')
                flirt('-interp', 'sinc', '-sincwidth', '7', '-sincwindow',
                      'blackman', '-in', volnii, '-ref', 'b0.nii.gz',
                      '-nosearch', '-o', volnii, '-omat',
                      volnii.with_suffix('.txt', depth=2), '-paddingsize', '1')
                volsRegistered.append(volnii)
            fslmerge('-t', 'EddyCorrect-DWI', volsRegistered)
            transforms = tmpdir.glob('Diffusion-G*.txt')
            transforms.sort()

            logging.info('Extract the rotations and realign the gradients')
            gDir = []
            header = ''
            gNum = []
            gframe = []
            with open('dwijoined.nhdr') as f:
                for line in f:
                    if line.find('DWMRI_gradient_') != -1:
                        gNum.append(line[15:19])
                        gDir.append(map(float, line[21:-1].split()))
                    elif line.find('data file:') != -1:
                        header = header + 'data file: EddyCorrect-DWI.nii.gz\n'
                    elif line.find('encoding:') != -1:
                        header = header + line + 'byteskip: -1\n'
                    elif line.find('measurement frame:') != -1:
                        header = header + line
                        mf = np.matrix([
                            map(float,
                                line.split()[2][1:-1].split(',')),
                            map(float,
                                line.split()[3][1:-1].split(',')),
                            map(float,
                                line.split()[4][1:-1].split(','))
                        ])
                    elif line.find('space:') != -1:
                        header = header + line
                        # Here I assume either lps or ras so only need to check the first letter
                        space = line.split()[1][0]
                        if (space == 'l') | (space == 'L'):
                            spctoras = np.matrix([[-1, 0, 0], [0, -1, 0],
                                                  [0, 0, 1]])
                        else:
                            spctoras = np.matrix([[1, 0, 0], [0, 1, 0],
                                                  [0, 0, 1]])
                    else:
                        header = header + line

            with open('EddyCorrect-DWI.nhdr', 'w') as f:
                f.write(header)
                i = 0
                # Transforms are in RAS so need to do inv(MF)*inv(SPC2RAS)*ROTATION*SPC2RAS*MF*GRADIENT
                mfras = mf.I * spctoras.I
                rasmf = spctoras * mf
                for t in transforms:
                    logging.info('Apply ' + t)
                    tra = np.loadtxt(t)
                    #removes the translation
                    aff = np.matrix(tra[0:3, 0:3])
                    # computes the finite strain of aff to get the rotation
                    rot = aff * aff.T
                    # Computer the square root of rot
                    [el, ev] = np.linalg.eig(rot)
                    eL = np.identity(3) * np.sqrt(el)
                    sq = ev * eL * ev.I
                    # finally the rotation is defined as
                    rot = sq.I * aff
                    newdir = np.dot(mfras * rot * rasmf, gDir[i])
                    f.write('DWMRI_gradient_' + gNum[i] + ':= ' +
                            str(newdir[0, 0]) + ' ' + str(newdir[0, 1]) + ' ' +
                            str(newdir[0, 2]) + '\n')
                    i = i + 1

            tar('cvzf', outxfms, transforms)
            unu('save', '-f', 'nrrd', '-e', 'gzip', '-i',
                'EddyCorrect-DWI.nhdr', '-o', self.out)

            if self.debug:
                tmpdir.move("eddy-debug-" + str(getpid()))