Пример #1
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())
Пример #2
0
    def main(self):
        fshome = local.path(os.getenv('FREESURFER_HOME'))
        if not fshome:
            logging.error('Set FREESURFER_HOME first.')
            sys.exit(1)

        with TemporaryDirectory() as tmpdir:
            tmpdir = local.path(tmpdir)
            b0masked = tmpdir / "b0masked.nrrd"
            b0masked1mm = tmpdir / "b0masked1mm.nrrd"
            brain = tmpdir / "brain.nii.gz"
            wmparc = tmpdir / "wmparc.nii.gz"
            brainmgz = self.parent.fsdir / 'mri/brain.mgz'
            wmparcmgz = self.parent.fsdir / 'mri/wmparc.mgz'
            wmparcindwi1mm = tmpdir / 'wmparcInDwi1mm.nii.gz'

            logging.info(
                "Make brain.nii.gz and wmparc.nii.gz from their mgz versions")
            vol2vol = local[fshome / 'bin/mri_vol2vol']
            label2vol = local[fshome / 'bin/mri_label2vol']
            with local.env(SUBJECTS_DIR=''):
                vol2vol('--mov', brainmgz, '--targ', brainmgz, '--regheader',
                        '--o', brain)
                label2vol('--seg', wmparcmgz, '--temp', brainmgz,
                          '--regheader', wmparcmgz, '--o', wmparc)

            logging.info('Extract B0 from DWI and mask')
            bse_py('-i', self.parent.dwi, '-m', self.parent.dwimask, '-o',
                   b0masked)
            logging.info('Made masked B0')

            logging.info('Upsample masked baseline to 1x1x1')
            ResampleImageBySpacing('3', b0masked, b0masked1mm, '1', '1', '1')
            logging.info('Made 1x1x1 baseline')

            logging.info('Register wmparc to B0')
            pre = tmpdir / 'fsbrain_to_b0'
            affine = pre + '0GenericAffine.mat'
            warp = pre + '1Warp.nii.gz'
            antsRegistrationSyNMI_sh['-m', brain, '-f', b0masked1mm, '-o', pre,
                                     '-n', 32] & FG
            antsApplyTransforms('-d', '3', '-i', wmparc, '-t', warp, affine,
                                '-r', b0masked1mm, '-o', wmparcindwi1mm,
                                '--interpolation', 'NearestNeighbor')
            logging.info('Made ' + wmparcindwi1mm)

            logging.info('Make output directory')
            self.parent.out.mkdir()
            b0masked.copy(self.parent.out)
            b0masked1mm.copy(self.parent.out)
            wmparcindwi1mm.copy(self.parent.out)
Пример #3
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())))
Пример #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"
            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())))
Пример #5
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)

            # fileinput() caused trouble reading data file in python 3, so switching to nrrd
            # if the hdr has 'nan' in space origin, the following will take care of that
            img = nrrd.read(self.dwi)
            dwi = img[0]
            hdr = img[1]

            hdr_out = hdr.copy()
            hdr_out['space origin'] = hdr_out['space origin'][0:3]

            nrrd.write('dwijoined.nhdr',
                       dwi,
                       header=hdr_out,
                       compression_level=1)

            # we want to use this hdr to write a new .nhdr file with corresponding data file
            # so delete old data file from the hdr
            if 'data file' in hdr_out.keys():
                del hdr_out['data file']
            elif 'datafile' in hdr_out.keys():
                del hdr_out['datafile']

            if 'content' in hdr_out.keys():
                del hdr_out['content']

            logging.info('Dice the DWI')

            # Since fslmerge works along the 3rd axis only, dicing also has to be along that axis
            # So, use `unu permute` to reorient the volumes to be stacked along 3rd axis only
            # Include this issue in the tutorial
            (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')

            # use the following multi-processed loop
            pool = Pool(int(self.nproc))
            res = pool.map_async(_Register_vol, vols)
            volsRegistered = res.get()
            pool.close()
            pool.join()

            # or use the following for loop
            # 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()

            # nibabel loading can be avoided by setting 'data file' = EddyCorrect-DWI.nii.gz
            # and 'byteskip' = -1
            # Tashrif updated Pynrrd package to properly handle that
            new_dwi = nib.load('EddyCorrect-DWI.nii.gz').get_data()

            logging.info('Extract the rotations and realign the gradients')

            space = hdr_out['space'].lower()
            if (space == 'left'):
                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]])
            mf = np.matrix(hdr['measurement frame'])

            # 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 (i, t) in enumerate(transforms):

                gDir = [
                    float(num) for num in hdr_out['DWMRI_gradient_' +
                                                  '{:04}'.format(i)].split(' ')
                    if num
                ]

                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
                # compute 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)

                hdr_out['DWMRI_gradient_' + '{:04}'.format(i)] = ('   ').join(
                    str(x) for x in newdir.tolist()[0])

            tar('cvzf', outxfms, transforms)

            nrrd.write(self.out, new_dwi, header=hdr_out, compression_level=1)

            if self.debug:
                tmpdir.copy(
                    join(dirname(self.out), "eddy-debug-" + str(getpid())))
Пример #6
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()))