Exemple #1
0
    def isDirty(self):

        images = Images()

        dwi = self.getUpsamplingImage('dwi', 'upsample')

        if mriutil.getNbDirectionsFromDWI(dwi) <= 45 and not self.get(
                'forceHardi'):
            if 'deterministic' in self.get('algorithm'):
                images.append((
                    self.getImage('dwi', 'tensor_det', 'trk'),
                    "deterministic tensor connectome matrix from a streamlines"
                ))

            if 'probabilistic' in self.get('algorithm'):
                images.append((
                    self.getImage('dwi', 'tensor_prob', 'trk'),
                    "probabilistic tensor connectome matrix from a streamlines"
                ))

        else:
            images.append(
                (self.getImage('dwi', 'hardi_prob', 'trk'),
                 "tckgen hardi probabilistic streamlines tractography"))

            if self.get('sift'):
                images.append((self.getImage('dwi', 'tcksift',
                                             'trk'), 'tcksift'))

        return images
    def isDirty(self):

        images = Images()

        dwi = self.getUpsamplingImage('dwi', 'upsample')

        if mriutil.getNbDirectionsFromDWI(dwi) <= 45  and not self.get('forceHardi'):
            if 'deterministic' in self.get('algorithm'):
                images.append((
                    self.getImage('dwi', 'tensor_det', 'trk'),
                    "deterministic tensor connectome matrix from a streamlines"
                    ))

            if 'probabilistic' in self.get('algorithm'):
                images.append((
                    self.getImage('dwi', 'tensor_prob', 'trk'),
                    "probabilistic tensor connectome matrix from a streamlines"
                    ))

        else:
            images.append((
                    self.getImage('dwi', 'hardi_prob', 'trk'),
                    "tckgen hardi probabilistic streamlines tractography"
                    ))

            if self.get('sift'):
                images.append((
                    self.getImage('dwi', 'tcksift', 'trk'), 'tcksift'))

        return images
Exemple #3
0
 def __nii4dtoGif(self, inputfile, tgGif, gifSpeed=30):
     """
     Create a animated gif from a 4d NIfTI
     
     Compulsory arguments :
     inputfile 4D NIfTI image
     tgGif : outputfile gif name
     
     Optional arguments :
     gifSpeed    : delay between images (tens of ms), default=30
     """
     gifId = self.__idGenerator()
     
     # Number of volumes in the 4D image
     vSize = mriutil.getNbDirectionsFromDWI(inputfile)
     vols = [gifId + '{0:04}'.format(i) for i in range(vSize)]
     
     # Spliting 4D image
     cmd = 'fslsplit ' + inputfile + ' ' + gifId + ' -t'
     self.launchCommand(cmd)
     
     # Extracting pngs from all volumes
     for vol in vols:
         self.__slicer(vol, None, vol + '.png')
     
     # Creating .gif
     cmd = 'convert '
     for vol in vols:
         cmd += '-delay ' + str(gifSpeed) + ' ' + vol + '.png '
     cmd += tgGif
     self.launchCommand(cmd)
     
     # Cleaning temp files
     cmd = 'rm ' + gifId + '*'
     self.launchCommand(cmd)
Exemple #4
0
    def implement(self):

        dwi   = self.getImage(self.dependDir, 'dwi')
        b0PA  = self.getImage(self.dependDir, 'b0PA')
        b0AP  = self.getImage(self.dependDir, 'b0AP')
        bFile =  self.getImage(self.dependDir, 'grad',  None, 'b')
        bVals =  self.getImage(self.dependDir, 'grad',  None, 'bval')
        bVecs =  self.getImage(self.dependDir, 'grad',  None, 'bvec')

        #make sure the 3 images have the same voxel size and dimension scale
        self.__validateSizeAndDimension(dwi, b0PA, b0AP)

        #make sure that the z dimension contain an odd number of slices
        dwiZDims = int(mriutil.getMriDimensions(dwi)[2])

        if dwiZDims%2 == 1:
            dwi  = self.__extractZVolumes(dwi, "0:{}".format(dwiZDims-2))
            b0PA = self.__extractZVolumes(b0PA, "0:{}".format(dwiZDims-2))
            b0AP = self.__extractZVolumes(b0AP, "0:{}".format(dwiZDims-2))

        #concatenate B0 image together
        b0Image = self.__concatenateB0(b0PA, b0AP,
                            os.path.join(self.workingDir, self.get('b0s_filename')))

        #create an empty b02b0.cnf file
        #b02b0File = os.path.join(self.workingDir, self.get('b02b0_filename'))
        #open(b02b0File, 'a').close()

        #create the acquisition parameter file
        acqpTopup = self.__createAcquisitionParameterFile('topup')
        acqpEddy = self.__createAcquisitionParameterFile('eddy')

        #create an index file
        indexFile = self.__createIndexFile(mriutil.getNbDirectionsFromDWI(dwi))

        #Lauch topup on concatenate B0 image
        [topupBaseName, topupImage] = self.__topup(b0Image, acqpTopup, self.get('b02b0_filename'))

        outputFieldMask = self.__fslmaths_tmean(os.path.join(self.workingDir, topupImage))

        outputFieldMaskExtracted = self.__bet(outputFieldMask)

        outputEddyImage = self.__correction_eddy2(dwi,
                                    outputFieldMaskExtracted, topupBaseName, indexFile, acqpEddy, bVecs, bVals)

        self.info("Uncompressing eddy output image: {}".format(outputEddyImage))
        util.gunzip(outputEddyImage)

        #@TODO remove the glob and use getimage
        eddyParameterFiles = glob.glob("{}/*.eddy_parameters".format(self.workingDir))
        if len(eddyParameterFiles)>0:
            bCorrected = mriutil.applyGradientCorrection(bFile, eddyParameterFiles.pop(0), self.workingDir)
            #produce the bVal and bVec file accordingly
            mriutil.bEnc2BVec(bCorrected, self.workingDir)
            mriutil.bEnc2BVal(bCorrected, self.workingDir)
Exemple #5
0
    def __isValidStructure(self):
        """Determine if the directory is a valid structure

        Returns:
            a Boolean that represent if validation is required for that directory

        """
        if not self.__validateImage(self.config.get('prefix', 'anat')):
            return False

        if not self.__validateImage(self.config.get('prefix', 'dwi')):
            return False

        dwi = util.getImage(self.config, self.workingDir, 'dwi')

        #@TODO fix data layout incomprehesion
        #make sure that diffusion image Z scale layout is oriented correctly
        #if not mriutil.isDataLayoutValid(dwiImage):
        #    self.error("Data layout for {} image is unexpected. "
        #                        "Only data layout = [ +0 +1 +2 +3 ] could be process".format(dwiImage))

        nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
        if nbDirections <= 45:
            msg = "Found only {} directions into {} image. Hardi model will not be accurate with diffusion weighted image " \
                  "that contain less than 45 directions\n\n".format(nbDirections, self.dwi)
            if self.config.getboolean('arguments', 'prompt'):
                util.displayYesNoMessage(msg)
            else:
                self.warning(msg)

        bEnc = util.getImage(self.config, self.workingDir, 'grad', None, 'b')
        bVal = util.getImage(self.config, self.workingDir, 'grad', None,
                             'bval')
        bVec = util.getImage(self.config, self.workingDir, 'grad', None,
                             'bvec')

        if (not bEnc) and (not bVal or not bVec):
            self.logger.warning("No valid .b encoding or pair of .bval, .bvec"
                                " file found in directory: {}".format(
                                    self.workingDir))
            return False
        #@TODO uncomment and fix not all zero bvec value in the first line
        """
        if bEnc and not self.__isValidEncoding(nbDirections, '.b'):
            self.logger.warning("Encoding file {} is invalid".format(bEnc))
            return False

        if bVal and not self.__isValidEncoding(nbDirections, '.bval'):
            self.logger.warning("Encoding file {} is invalid".format(bEnc))
            return False
        if bVec and not self.__isValidEncoding(nbDirections, '.bvec'):
            self.logger.warning("Encoding file {} is invalid".format(bVec))
            return False
        """
        return True
Exemple #6
0
    def __isValidStructure(self):
        """Determine if the directory is a valid structure

        Returns:
            a Boolean that represent if validation is required for that directory

        """
        if not self.__validateImage(self.config.get('prefix','anat')):
            return False

        if not self.__validateImage(self.config.get('prefix','dwi')):
            return False


        dwi = util.getImage(self.config, self.workingDir,'dwi')

        #@TODO fix data layout incomprehesion
        #make sure that diffusion image Z scale layout is oriented correctly
        #if not mriutil.isDataLayoutValid(dwiImage):
        #    self.error("Data layout for {} image is unexpected. "
        #                        "Only data layout = [ +0 +1 +2 +3 ] could be process".format(dwiImage))

        nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
        if nbDirections <= 45:
            msg = "Found only {} directions into {} image. Hardi model will not be accurate with diffusion weighted image " \
                  "that contain less than 45 directions\n\n".format(nbDirections, self.dwi)
            if self.config.getboolean('arguments', 'prompt'):
                util.displayYesNoMessage(msg)
            else:
                self.warning(msg)


        bEnc = util.getImage(self.config, self.workingDir,'grad', None, 'b')
        bVal = util.getImage(self.config, self.workingDir,'grad', None, 'bval')
        bVec = util.getImage(self.config, self.workingDir,'grad', None, 'bvec')

        if (not bEnc) and (not bVal or not bVec):
            self.logger.warning("No valid .b encoding or pair of .bval, .bvec"
                                " file found in directory: {}".format(self.workingDir))
            return False
        #@TODO uncomment and fix not all zero bvec value in the first line
        """
        if bEnc and not self.__isValidEncoding(nbDirections, '.b'):
            self.logger.warning("Encoding file {} is invalid".format(bEnc))
            return False

        if bVal and not self.__isValidEncoding(nbDirections, '.bval'):
            self.logger.warning("Encoding file {} is invalid".format(bEnc))
            return False
        if bVec and not self.__isValidEncoding(nbDirections, '.bvec'):
            self.logger.warning("Encoding file {} is invalid".format(bVec))
            return False
        """
        return True
Exemple #7
0
    def implement(self):
        shutil.copy(self.queries, self.workingDir)
        shutil.copy(self.tq_dict, self.workingDir)

        dwi = self.getUpsamplingImage('dwi', 'upsample')
        nbDirections = mriutil.getNbDirectionsFromDWI(dwi)  # Get number of directions

        self.tractographyTrk = self.__getTractography(nbDirections)  # Load tractography

        atlasResample = self.__getAtlas()  # Get atlas to refere to

        self.__tractQuerier(
                self.tractographyTrk, atlasResample,
                self.workingDir, self.queries)
Exemple #8
0
    def implement(self):
        shutil.copy(self.queriesFile, self.workingDir)
        shutil.copy(self.tq_dictFile, self.workingDir)

        dwi = self.getUpsamplingImage('dwi', 'upsample')
        nbDirections = mriutil.getNbDirectionsFromDWI(
            dwi)  # Get number of directions

        self.tractographyTrk = self.__getTractography(
            nbDirections)  # Load tractography

        atlasResample = self.__getAtlas()  # Get atlas to refere to

        self.__tractQuerier(self.tractographyTrk, atlasResample,
                            self.workingDir, self.queriesFile)
    def implement(self):

        tt5 = self.getRegistrationImage("tt5", "register")
        seed_gmwmi = self.getMaskingImage("tt5", ["register", "5tt2gmwmi"])
        norm = self.getRegistrationImage("norm", "resample")

        mask253 = self.getMaskingImage('aparc_aseg', ['253', 'mask'])
        mask1024= self.getMaskingImage('aparc_aseg', ['1024', 'mask'])

        dwi = self.getUpsamplingImage('dwi', 'upsample')

        bFile = self.getUpsamplingImage('grad', None, 'b')
        mask = self.getRegistrationImage('mask', 'resample')


        self.__nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
        if self.__nbDirections <= 45:
            if 'deterministic' in self.get('algorithm'):
                tckDet = self.__tckgenTensor(dwi, self.buildName(dwi, 'tensor_det', 'tck'), mask, tt5, seed_gmwmi, bFile, 'Tensor_Det')
                tckDetRoi = self.__tckedit(tckDet, mask253, self.buildName(tckDet, 'roi','tck'))
                tckDetRoiTrk = mriutil.tck2trk(tckDetRoi, norm, self.buildName(tckDetRoi, None, 'trk'))
                tckDetTrk = mriutil.tck2trk(tckDet, norm, self.buildName(tckDet, None, 'trk'))
                self.__tckDetRoiTrk = tckDetRoiTrk

            if 'probabilistic' in self.get('algorithm'):
                tckProb = self.__tckgenTensor(dwi, self.buildName(dwi, 'tensor_prob', 'tck'), mask, tt5, seed_gmwmi, bFile, 'Tensor_Prob')
                tckProbRoi = self.__tckedit(tckProb, mask253, self.buildName(tckProb, 'roi','tck'))
                tckProbRoiTrk = mriutil.tck2trk(tckProbRoi, norm , self.buildName(tckProbRoi, None, 'trk'))
                tckProbTrk = mriutil.tck2trk(tckProb, norm , self.buildName(tckProb, None, 'trk'))
                self.__tckProbRoiTrk = tckProbRoiTrk

        else:
            if 'hardi' in self.get('algorithm'):
                csd =  self.getHardimrtrixImage('dwi','csd')
                hardiTck = self.__tckgenHardi(csd, self.buildName(csd, 'hardi_prob', 'tck'), tt5)
                hardiTckRoi = self.__tckedit(hardiTck, mask253, self.buildName(hardiTck, 'roi','tck'))
                tckgenRoiTrk = mriutil.tck2trk(hardiTckRoi, norm , self.buildName(hardiTckRoi, None, 'trk'))
                hardiTrk = mriutil.tck2trk(hardiTck, norm, self.buildName(hardiTck, 'None', 'trk'))
                self.__tckgenRoiTrk = tckgenRoiTrk

            if 'sift' in self.get('algorithm'):
                tcksift = self.__tcksift(hardiTck, csd)
                tcksiftRoi = self.__tckedit(tcksift, mask253, self.buildName(tcksift, 'roi', 'tck'))
                tcksiftRoiTrk = mriutil.tck2trk(tcksiftRoi, norm , self.buildName(tcksiftRoi, None, 'trk'))
                tcksiftTrk = mriutil.tck2trk(tcksift, norm, self.buildName(tcksift, 'None', 'trk'))
                self.__tcksiftRoiTrk = tcksiftRoiTrk
Exemple #10
0
    def meetRequirement(self):
        """Validate if all requirements have been met prior to launch the task
        Returns:
            True if all requirement are meet, False otherwise
        """

        images = Images()

        dwi = self.getUpsamplingImage('dwi', 'upsample')
        nbDirections = mriutil.getNbDirectionsFromDWI(dwi)  # Get number of directions

        if nbDirections <= 45 and not self.get('tractographymrtrix', 'forceHardi'):
            postfixTractography = 'tensor_prob'
        else:
            postfixTractography = 'hardi_prob'

        Images((self.getTractographymrtrixImage('dwi', postfixTractography, 'trk'),'Tractography file'),
                (self.__getAtlas(),'Atlas'))  # Check if tractographies are available

        return images
Exemple #11
0
    def meetRequirement(self):
        """Validate if all requirements have been met prior to launch the task
        Returns:
            True if all requirement are meet, False otherwise
        """

        images = Images()

        dwi = self.getUpsamplingImage('dwi', 'upsample')
        nbDirections = mriutil.getNbDirectionsFromDWI(
            dwi)  # Get number of directions

        if nbDirections <= 45 and not self.get('tractographymrtrix',
                                               'forceHardi'):
            postfixTractography = 'tensor_prob'
        else:
            postfixTractography = 'hardi_prob'

        Images((self.getTractographymrtrixImage('dwi', postfixTractography,
                                                'trk'), 'Tractography file'),
               (self.__getAtlas(),
                'Atlas'))  # Check if tractographies are available

        return images
    def implement(self):

        tt5 = self.getRegistrationImage("tt5", "register")
        seed_gmwmi = self.getMaskingImage("tt5", ["register", "5tt2gmwmi"])
        norm = self.getRegistrationImage("norm", "resample")

        mask253 = self.getMaskingImage('aparc_aseg', ['253', 'mask'])
        # mask1024= self.getMaskingImage('aparc_aseg', ['1024', 'mask'])

        dwi = self.getUpsamplingImage('dwi', 'upsample')

        bFile = self.getUpsamplingImage('grad', None, 'b')
        mask = self.getRegistrationImage('mask', 'resample')

        # If step is None set Step = voxelSize/2

        if self.get('step') == 'None':
            voxelSize = [float(x) for x in self.get('methodology', 't1_voxelsize')[1:-1].split(',')]
            self.set('step', str(float(voxelSize[0]) * 0.5))
            self.set('angle', str(90 * float(self.get('step')) / float(voxelSize[0])))

        self.__nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
        if self.__nbDirections <= 45 and not self.get('forceHardi'):

            self.set('methodReconstruction', 'tenseur')

            if 'deterministic' in self.get('algorithm'):
                tckDet = self.__tckgenTensor(
                        dwi, self.buildName(dwi, 'tensor_det', 'tck'),
                        mask, tt5, seed_gmwmi, bFile, 'Tensor_Det')
                tckDetTrk = mriutil.tck2trk(
                        tckDet, norm, self.buildName(tckDet, None, 'trk'))
                tckDetRoi = self.__tckedit(
                        tckDet, mask253, self.buildName(tckDet, 'roi', 'tck'))
                tckDetRoiTrk = mriutil.tck2trk(
                        tckDetRoi, norm, self.buildName(tckDetRoi, None, 'trk'))
                self.__tckDetRoiTrk = tckDetRoiTrk

                self.set('algorithm', 'Determinist')  # Set Method tractography Det

            elif 'probabilistic' in self.get('algorithm'):
                tckProb = self.__tckgenTensor(
                        dwi, self.buildName(dwi, 'tensor_prob', 'tck'),
                        mask, tt5, seed_gmwmi, bFile, 'Tensor_Prob')
                tckProbTrk = mriutil.tck2trk(
                        tckProb, norm , self.buildName(tckProb, None, 'trk'))
                tckProbRoi = self.__tckedit(
                        tckProb, mask253, self.buildName(tckProb, 'roi', 'tck'))
                tckProbRoiTrk = mriutil.tck2trk(
                        tckProbRoi, norm , self.buildName(tckProbRoi, None, 'trk'))
                self.__tckProbRoiTrk = tckProbRoiTrk

                self.set('algorithm', 'Probabilist')  # Set Method tractography Prob

        else:
            csd =  self.getHardimrtrixImage('dwi', 'csd')
            hardiTck = self.__tckgenHardi(
                    csd, self.buildName(csd, 'hardi_prob', 'tck'), tt5)
            hardiTrk = mriutil.tck2trk(
                    hardiTck, norm, self.buildName(hardiTck, None, 'trk'))
            hardiTckRoi = self.__tckedit(
                    hardiTck, mask253, self.buildName(hardiTck, 'roi', 'tck'))
            tckgenRoiTrk = mriutil.tck2trk(
                    hardiTckRoi, norm , self.buildName(hardiTckRoi, None, 'trk'))
            self.__tckgenRoiTrk = tckgenRoiTrk

            self.set('methodReconstruction', 'hardi')
            self.set('algorithm', 'Probabilist')

            if self.get('sift'):
                tcksift = self.__tcksift(hardiTck, csd)
                tcksiftTrk = mriutil.tck2trk(
                    tcksift, norm, self.buildName(tcksift, None, 'trk'))
                tcksiftRoi = self.__tckedit(
                    tcksift, mask253, self.buildName(tcksift, 'roi', 'tck'))
                tcksiftRoiTrk = mriutil.tck2trk(
                    tcksiftRoi, norm , self.buildName(tcksiftRoi, None, 'trk'))
                self.__tcksiftRoiTrk = tcksiftRoiTrk
Exemple #13
0
    def implement(self):

        dwi = self.getDenoisingImage('dwi', 'denoise')
        if not dwi:
            dwi = self.getPreparationImage('dwi')

        b0AP = self.getPreparationImage('b0_ap')
        b0PA = self.getPreparationImage('b0_pa')
        bEnc = self.getPreparationImage('grad', None, 'b')
        bVals = self.getPreparationImage('grad', None, 'bvals')
        bVecs = self.getPreparationImage('grad', None, 'bvecs')
        norm = self.getParcellationImage('norm')
        parcellationMask = self.getParcellationImage('mask')

        # Fieldmap only
        mag = self.getPreparationImage("mag")
        phase = self.getPreparationImage("phase")
        freesurferAnat = self.getParcellationImage('anat', 'freesurfer')

        self.info("extract b0 image from the dwi")
        b0 = os.path.join(
            self.workingDir,
            os.path.basename(dwi).replace(self.get("prefix", 'dwi'),
                                          self.get("prefix", 'b0')))
        self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals))

        self.info(
            "look if all images have the same voxel size and dimension scale")
        self.__validateSizeAndDimension(dwi, b0, b0AP, b0PA)

        # Generate a missing b0 image if we could. --> 0 = P>>A, 1 = A>>P
        if self.get("phase_enc_dir") == "0" and b0AP and b0PA is False:
            b0PA = b0

        if self.get("phase_enc_dir") == "1" and b0PA and b0AP is False:
            b0AP = b0

        [dwi, b0, b0AP,
         b0PA] = self.__oddEvenNumberOfSlices(dwi, b0, b0AP, b0PA)

        self.set('method', None)

        if b0AP is False or b0PA is False:
            topupBaseName = None
            b0Image = b0
            self.set('method', 'fieldmap')
        else:
            # Concatenate B0 image together
            if self.get("phase_enc_dir") == "0":
                concatenateB0Image = self.__concatenateB0(
                    b0PA, b0AP, self.buildName("b0pa_b0ap", None, "nii.gz"))

            elif self.get("phase_enc_dir") == "1":
                concatenateB0Image = self.__concatenateB0(
                    b0AP, b0PA, self.buildName("b0ap_b0pa", None, "nii.gz"))
            # Create the acquisition parameter file
            acqpTopup = self.__createAcquisitionParameterFile('topup')

            # Run topup on concatenate B0 image
            [topupBaseName,
             topupImage] = self.__topup(concatenateB0Image, acqpTopup,
                                        self.get('b02b0_filename'))
            b0Image = self.__fslmathsTmean(
                os.path.join(self.workingDir, topupImage))
            self.set('method', 'topup')

        self.info("create a suitable mask for the dwi")
        extraArgs = " -dof 6 "  # same subject

        if self.get("methodology", "intrasession"):
            extraArgs += " -usesqform "

        mask = mriutil.computeDwiMaskFromFreesurfer(
            b0Image, norm, parcellationMask,
            self.buildName(parcellationMask, 'temporary'), extraArgs)

        # Create the acquisition parameter file for eddy
        acqpEddy = self.__createAcquisitionParameterFile('eddy')

        # Create an index file
        indexFile = self.__createIndexFile(mriutil.getNbDirectionsFromDWI(dwi))

        outputImage = self.__correctionEddy(dwi, mask, topupBaseName,
                                            indexFile, acqpEddy, bVecs, bVals)

        eddyParameterFiles = self.getImage('dwi', None, 'eddy_parameters')

        if eddyParameterFiles:
            self.info(
                "Apply eddy movement correction to gradient encodings directions"
            )
            bEnc = mriutil.applyGradientCorrection(
                bEnc, eddyParameterFiles,
                self.buildName(outputImage, None, 'b'))
            self.info(
                mriutil.mrtrixToFslEncoding(
                    outputImage, bEnc,
                    self.buildName(outputImage, None, 'bvecs'),
                    self.buildName(outputImage, None, 'bvals')))
        # Proceed with fieldmap if provided
        if mag and phase and not self.__topupCorrection:
            # OutputImage is now used for fieldmap correction
            outputImage = self.__computeFieldmap(outputImage, bVals, mag,
                                                 phase, norm, parcellationMask,
                                                 freesurferAnat)
            self.set('method', 'fieldmap')

        # Produce a valid b0 and mask for QA
        b0Corrected = self.buildName(b0, 'corrected')
        self.info(
            mriutil.extractFirstB0FromDwi(outputImage, b0Corrected, bVals))
        maskCorrected = mriutil.computeDwiMaskFromFreesurfer(
            b0Corrected, norm, parcellationMask,
            self.buildName(parcellationMask, 'corrected'), extraArgs)

        self.rename(outputImage, self.buildName(outputImage, 'corrected'))
Exemple #14
0
    def __isAValidStructure(self):
        """Determine if the directory is a valid structure

        Returns:
            a Boolean that represent if the subject integrity test pass for that directory

        """

        #Anatomical, Dwi and gradient encoding direction are mandatory input
        anat = util.getImage(self.config, self.workingDir, 'anat')
        if not anat:
            if util.getImage(self.config, self.workingDir, 'anat', None, 'nii'):
                self.warning("Found some uncompressed nifti images into {} directory. "
                           "Please gzip those images and resubmit the pipeline again".format(self.workingDir))
                return False
            self.warning("No high resolution image found into {} directory".format(self.workingDir))
            return False

        dwi = util.getImage(self.config, self.workingDir, 'dwi')
        if not dwi:
            if util.getImage(self.config, self.workingDir, 'dwi', None, 'nii'):
                self.warning("Found some uncompressed  nifti image into {} directory. "
                           "Please gzip those images and resubmit the pipeline again".format(self.workingDir))
                return False
            self.warning("No diffusion weight image found into {} directory".format(self.workingDir))
            return False

        bEnc = util.getImage(self.config, self.workingDir,'grad', None, 'b')
        bVals = util.getImage(self.config, self.workingDir,'grad', None, 'bvals')
        bVecs = util.getImage(self.config, self.workingDir,'grad', None, 'bvecs')

        if (not bEnc) and (not bVals or not bVecs):
            self.warning("No valid .b encoding or (.bvals, .bvecs) files found in directory: {}".format(self.workingDir))
            return False

        else:

            nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
            if nbDirections <= 45:
                msg = "Found only {} directions into {} image. Hardi model will not be accurate with diffusion weighted image " \
                      "that contain less than 45 directions\n\n".format(nbDirections, dwi)
                self.warning(msg)
                #return False

            if bEnc and not self.__isValidEncoding(nbDirections, '.b'):
                self.warning("Encoding file {} is invalid".format(bEnc))
                return False

            if bVals and not self.__isValidEncoding(nbDirections, '.bvals'):
                self.warning("Encoding file {} is invalid".format(bEnc))
                return False

            if bVecs and not self.__isValidEncoding(nbDirections, '.bvecs'):
                self.warning("Encoding file {} is invalid".format(bVecs))
                return False

        #Validate optionnal images
        images = {
                  'anat': (anat, 'high resolution'),
                  'dwi': (dwi,'diffusion weighted'),
                  'mag': (util.getImage(self.config, self.workingDir, 'mag'), 'MR magnitude '),
                  'phase': (util.getImage(self.config, self.workingDir, 'phase'), 'MR phase '),
                  'b0_ap': (util.getImage(self.config, self.workingDir, 'b0_ap'), "posterior to anterior b0 "),
                  'b0_pa': (util.getImage(self.config, self.workingDir, 'b0_pa'), "anterior to posterior b0")}


        if self.config.get('arguments', 'debug') == 'True':
            self.debug("Images found into {} directory: {}".format(self.workingDir, images))


        if self.config.getboolean('arguments', 'prompt'):

            for key, (value, description) in images.iteritems():
                if value:
                    if not mriutil.isDataStridesOrientationExpected(value, self.config.get('preparation', 'stride_orientation'))\
                            and self.config.getboolean("preparation", "force_realign_strides"):
                        msg = "Data strides layout for {} is unexpected and force_realign_strides is set to True.\n \
                               If you continue, all unexpected images will be realign accordingly.\n\
                               Only a copy of the original images will be alter.".format(value)
                        if not util.displayYesNoMessage(msg):
                            self.warning("Remove this subject from the list?")
                            return False
                        else:
                            break

            #if one and only one b0 image is given, make sure that the b0 image is not on same direction than the dwi.
            if (not (images['b0_ap'][0] and images['b0_pa'][0])) and (images['b0_ap'][0] or images['b0_pa'][0])  \
                and (self.config.get("correction", "ignore") == "False"):
                if ((self.config.get("correction", "phase_enc_dir") == "0") and images['b0_pa'][0]) \
                    or ((self.config.get("correction", "phase_enc_dir") == "1")  and images['b0_ap'][0]):
                        msg = "Found only one B0 image into the subject directory and that B0 is in " \
                              "the same phase encoding direction than the DWI.\n" \
                              "We recommend to remove the B0 image so at least a motion correction will be perform"
                        if not util.displayYesNoMessage(msg):
                            self.warning("Remove this subject from the list?")
                            return False

            if images['mag'][0] and images['phase'][0] and (images['b0_ap'][0] or images['b0_pa'][0]):
                msg = "Found both Fieldmap and B0 images into the subject directory\n" \
                      "We recommend to disabled fieldmap correction?"
                if not util.displayYesNoMessage(msg):
                    self.warning("Remove this subject from the list?")
                    return False

        return True
Exemple #15
0
    def implement(self):

        dwi = self.getDenoisingImage('dwi', 'denoise')
        if not dwi:
            dwi = self.getPreparationImage('dwi')

        b0AP = self.getPreparationImage('b0_ap')
        b0PA = self.getPreparationImage('b0_pa')
        bEnc = self.getPreparationImage('grad', None, 'b')
        bVals = self.getPreparationImage('grad', None, 'bvals')
        bVecs = self.getPreparationImage('grad', None, 'bvecs')
        norm = self.getParcellationImage('norm')
        parcellationMask = self.getParcellationImage('mask')

        # Fieldmap only
        mag = self.getPreparationImage("mag")
        phase = self.getPreparationImage("phase")
        freesurferAnat = self.getParcellationImage('anat', 'freesurfer')

        self.info("extract b0 image from the dwi")
        b0 = os.path.join(self.workingDir,
                          os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0')))
        self.info(mriutil.extractFirstB0FromDwi(dwi, b0, bVals))

        self.info("look if all images have the same voxel size and dimension scale")
        self.__validateSizeAndDimension(dwi, b0, b0AP, b0PA)

        # Generate a missing b0 image if we could. --> 0 = P>>A, 1 = A>>P
        if self.get("phase_enc_dir") == "0" and b0AP and b0PA is False:
            b0PA = b0

        if self.get("phase_enc_dir") == "1" and b0PA and b0AP is False:
            b0AP = b0

        [dwi, b0, b0AP, b0PA] = self.__oddEvenNumberOfSlices(dwi, b0, b0AP, b0PA)

        self.set('method', None)


        if b0AP is False or b0PA is False:
            topupBaseName = None
            b0Image = b0
            self.set('method', 'fieldmap')
        else:
            # Concatenate B0 image together
            if self.get("phase_enc_dir") == "0":
                concatenateB0Image = self.__concatenateB0(b0PA, b0AP, self.buildName("b0pa_b0ap", None, "nii.gz"))

            elif self.get("phase_enc_dir") == "1":
                concatenateB0Image = self.__concatenateB0(b0AP, b0PA, self.buildName("b0ap_b0pa", None, "nii.gz"))
            # Create the acquisition parameter file
            acqpTopup = self.__createAcquisitionParameterFile('topup')

            # Run topup on concatenate B0 image
            [topupBaseName, topupImage] = self.__topup(concatenateB0Image, acqpTopup, self.get('b02b0_filename'))
            b0Image = self.__fslmathsTmean(os.path.join(self.workingDir, topupImage))
            self.set('method', 'topup')

        self.info("create a suitable mask for the dwi")
        extraArgs = " -dof 6 "  # same subject

        if self.get("methodology", "intrasession"):
            extraArgs += " -usesqform "

        mask = mriutil.computeDwiMaskFromFreesurfer(b0Image,
                                                    norm,
                                                    parcellationMask,
                                                    self.buildName(parcellationMask, 'temporary'),
                                                    extraArgs)

        # Create the acquisition parameter file for eddy
        acqpEddy = self.__createAcquisitionParameterFile('eddy')

        # Create an index file
        indexFile = self.__createIndexFile(mriutil.getNbDirectionsFromDWI(dwi))

        outputImage = self.__correctionEddy(dwi, mask, topupBaseName, indexFile, acqpEddy, bVecs, bVals)

        eddyParameterFiles = self.getImage('dwi', None, 'eddy_parameters')

        if eddyParameterFiles:
            self.info("Apply eddy movement correction to gradient encodings directions")
            bEnc = mriutil.applyGradientCorrection(bEnc, eddyParameterFiles, self.buildName(outputImage, None, 'b'))
            self.info(mriutil.mrtrixToFslEncoding(outputImage,
                                                  bEnc,
                                                  self.buildName(outputImage, None, 'bvecs'),
                                                  self.buildName(outputImage, None, 'bvals')))
        # Proceed with fieldmap if provided
        if mag and phase and not self.__topupCorrection:
            # OutputImage is now used for fieldmap correction
            outputImage = self.__computeFieldmap(outputImage, bVals, mag, phase, norm, parcellationMask, freesurferAnat)
            self.set('method', 'fieldmap')

        # Produce a valid b0 and mask for QA
        b0Corrected = self.buildName(b0, 'corrected')
        self.info(mriutil.extractFirstB0FromDwi(outputImage, b0Corrected, bVals))
        maskCorrected = mriutil.computeDwiMaskFromFreesurfer(b0Corrected,
                                                             norm,
                                                             parcellationMask,
                                                             self.buildName(parcellationMask, 'corrected'),
                                                             extraArgs)

        self.rename(outputImage, self.buildName(outputImage, 'corrected'))
Exemple #16
0
    def implement(self):

        tt5 = self.getRegistrationImage("tt5", "register")
        seed_gmwmi = self.getMaskingImage("tt5", ["register", "5tt2gmwmi"])
        norm = self.getRegistrationImage("norm", "resample")

        mask253 = self.getMaskingImage('aparc_aseg', ['253', 'mask'])
        # mask1024= self.getMaskingImage('aparc_aseg', ['1024', 'mask'])

        dwi = self.getUpsamplingImage('dwi', 'upsample')

        bFile = self.getUpsamplingImage('grad', None, 'b')
        mask = self.getRegistrationImage('mask', 'resample')

        # If step is None set Step = voxelSize/2

        if self.get('step') == 'None':
            voxelSize = [
                float(x) for x in self.get('methodology', 't1_voxelsize')
                [1:-1].split(',')
            ]
            self.set('step', str(float(voxelSize[0]) * 0.5))
            self.set('angle',
                     str(90 * float(self.get('step')) / float(voxelSize[0])))

        self.__nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
        if self.__nbDirections <= 45 and not self.get('forceHardi'):

            self.set('methodReconstruction', 'tenseur')

            if 'deterministic' in self.get('algorithm'):
                tckDet = self.__tckgenTensor(
                    dwi, self.buildName(dwi, 'tensor_det', 'tck'), mask, tt5,
                    seed_gmwmi, bFile, 'Tensor_Det')
                tckDetTrk = mriutil.tck2trk(
                    tckDet, norm, self.buildName(tckDet, None, 'trk'))
                tckDetRoi = self.__tckedit(
                    tckDet, mask253, self.buildName(tckDet, 'roi', 'tck'))
                tckDetRoiTrk = mriutil.tck2trk(
                    tckDetRoi, norm, self.buildName(tckDetRoi, None, 'trk'))
                self.__tckDetRoiTrk = tckDetRoiTrk

                self.set('algorithm',
                         'Determinist')  # Set Method tractography Det

            elif 'probabilistic' in self.get('algorithm'):
                tckProb = self.__tckgenTensor(
                    dwi, self.buildName(dwi, 'tensor_prob', 'tck'), mask, tt5,
                    seed_gmwmi, bFile, 'Tensor_Prob')
                tckProbTrk = mriutil.tck2trk(
                    tckProb, norm, self.buildName(tckProb, None, 'trk'))
                tckProbRoi = self.__tckedit(
                    tckProb, mask253, self.buildName(tckProb, 'roi', 'tck'))
                tckProbRoiTrk = mriutil.tck2trk(
                    tckProbRoi, norm, self.buildName(tckProbRoi, None, 'trk'))
                self.__tckProbRoiTrk = tckProbRoiTrk

                self.set('algorithm',
                         'Probabilist')  # Set Method tractography Prob

        else:
            csd = self.getHardimrtrixImage('dwi', 'csd')
            hardiTck = self.__tckgenHardi(
                csd, self.buildName(csd, 'hardi_prob', 'tck'), tt5)
            hardiTrk = mriutil.tck2trk(hardiTck, norm,
                                       self.buildName(hardiTck, None, 'trk'))
            hardiTckRoi = self.__tckedit(
                hardiTck, mask253, self.buildName(hardiTck, 'roi', 'tck'))
            tckgenRoiTrk = mriutil.tck2trk(
                hardiTckRoi, norm, self.buildName(hardiTckRoi, None, 'trk'))
            self.__tckgenRoiTrk = tckgenRoiTrk

            self.set('methodReconstruction', 'hardi')
            self.set('algorithm', 'Probabilist')

            if self.get('sift'):
                tcksift = self.__tcksift(hardiTck, csd)
                tcksiftTrk = mriutil.tck2trk(
                    tcksift, norm, self.buildName(tcksift, None, 'trk'))
                tcksiftRoi = self.__tckedit(
                    tcksift, mask253, self.buildName(tcksift, 'roi', 'tck'))
                tcksiftRoiTrk = mriutil.tck2trk(
                    tcksiftRoi, norm, self.buildName(tcksiftRoi, None, 'trk'))
                self.__tcksiftRoiTrk = tcksiftRoiTrk
Exemple #17
0
    def __isAValidStructure(self):
        """Determine if the directory is a valid structure

        Returns:
            a Boolean that represent if the subject integrity test pass for that directory

        """

        #Anatomical, Dwi and gradient encoding direction are mandatory input
        anat = util.getImage(self.config, self.workingDir, 'anat')
        if not anat:
            if util.getImage(self.config, self.workingDir, 'anat', None,
                             'nii'):
                self.warning(
                    "Found some uncompressed nifti images into {} directory. "
                    "Please gzip those images and resubmit the pipeline again".
                    format(self.workingDir))
                return False
            self.warning(
                "No high resolution image found into {} directory".format(
                    self.workingDir))
            return False

        dwi = util.getImage(self.config, self.workingDir, 'dwi')
        if not dwi:
            if util.getImage(self.config, self.workingDir, 'dwi', None, 'nii'):
                self.warning(
                    "Found some uncompressed  nifti image into {} directory. "
                    "Please gzip those images and resubmit the pipeline again".
                    format(self.workingDir))
                return False
            self.warning(
                "No diffusion weight image found into {} directory".format(
                    self.workingDir))
            return False

        bEnc = util.getImage(self.config, self.workingDir, 'grad', None, 'b')
        bVals = util.getImage(self.config, self.workingDir, 'grad', None,
                              'bvals')
        bVecs = util.getImage(self.config, self.workingDir, 'grad', None,
                              'bvecs')

        if (not bEnc) and (not bVals or not bVecs):
            self.warning(
                "No valid .b encoding or (.bvals, .bvecs) files found in directory: {}"
                .format(self.workingDir))
            return False

        else:

            nbDirections = mriutil.getNbDirectionsFromDWI(dwi)
            if nbDirections <= 45:
                msg = "Found only {} directions into {} image. Hardi model will not be accurate with diffusion weighted image " \
                      "that contain less than 45 directions\n\n".format(nbDirections, dwi)
                self.warning(msg)
                #return False

            if bEnc and not self.__isValidEncoding(nbDirections, '.b'):
                self.warning("Encoding file {} is invalid".format(bEnc))
                return False

            if bVals and not self.__isValidEncoding(nbDirections, '.bvals'):
                self.warning("Encoding file {} is invalid".format(bEnc))
                return False

            if bVecs and not self.__isValidEncoding(nbDirections, '.bvecs'):
                self.warning("Encoding file {} is invalid".format(bVecs))
                return False

        #Validate optionnal images
        images = {
            'anat': (anat, 'high resolution'),
            'dwi': (dwi, 'diffusion weighted'),
            'mag': (util.getImage(self.config, self.workingDir,
                                  'mag'), 'MR magnitude '),
            'phase': (util.getImage(self.config, self.workingDir,
                                    'phase'), 'MR phase '),
            'b0_ap': (util.getImage(self.config, self.workingDir,
                                    'b0_ap'), "posterior to anterior b0 "),
            'b0_pa': (util.getImage(self.config, self.workingDir,
                                    'b0_pa'), "anterior to posterior b0")
        }

        if self.config.get('arguments', 'debug') == 'True':
            self.debug("Images found into {} directory: {}".format(
                self.workingDir, images))

        if self.config.getboolean('arguments', 'prompt'):

            for key, (value, description) in images.iteritems():
                if value:
                    if not mriutil.isDataStridesOrientationExpected(value, self.config.get('preparation', 'stride_orientation'))\
                            and self.config.getboolean("preparation", "force_realign_strides"):
                        msg = "Data strides layout for {} is unexpected and force_realign_strides is set to True.\n \
                               If you continue, all unexpected images will be realign accordingly.\n\
                               Only a copy of the original images will be alter.".format(
                            value)
                        if not util.displayYesNoMessage(msg):
                            self.warning("Remove this subject from the list?")
                            return False
                        else:
                            break

            #if one and only one b0 image is given, make sure that the b0 image is not on same direction than the dwi.
            if (not (images['b0_ap'][0] and images['b0_pa'][0])) and (images['b0_ap'][0] or images['b0_pa'][0])  \
                and (self.config.get("correction", "ignore") == "False"):
                if ((self.config.get("correction", "phase_enc_dir") == "0") and images['b0_pa'][0]) \
                    or ((self.config.get("correction", "phase_enc_dir") == "1")  and images['b0_ap'][0]):
                    msg = "Found only one B0 image into the subject directory and that B0 is in " \
                          "the same phase encoding direction than the DWI.\n" \
                          "We recommend to remove the B0 image so at least a motion correction will be perform"
                    if not util.displayYesNoMessage(msg):
                        self.warning("Remove this subject from the list?")
                        return False

            if images['mag'][0] and images['phase'][0] and (
                    images['b0_ap'][0] or images['b0_pa'][0]):
                msg = "Found both Fieldmap and B0 images into the subject directory\n" \
                      "We recommend to disabled fieldmap correction?"
                if not util.displayYesNoMessage(msg):
                    self.warning("Remove this subject from the list?")
                    return False

        return True