Beispiel #1
0
    def __oddEvenNumberOfSlices(self, *args):
        """return a list of images that will count a odd number of slices in z direction

            If an even number of slices is found, the upper volume will be remove

        Args:
            *args: a list of images

        Returns:
             a list of images stripped

        """
        output = []
        for image in args:
            if image:
                try:
                    zDims = int(mriutil.getMriDimensions(image)[2])
                    if zDims % 2 == 1:
                        target = self.buildName(image, "subset")
                        mriutil.extractSubVolume(image, target, '+2',
                                                 "0:{}".format(zDims - 2),
                                                 self.getNTreadsMrtrix())
                        output.append(target)
                    else:
                        output.append(image)
                except ValueError:
                    output.append(image)
            else:
                output.append(False)
        return output
Beispiel #2
0
    def __oddEvenNumberOfSlices(self, *args):
        """return a list of images that will count a odd number of slices in z direction

            If an even number of slices is found, the upper volume will be remove

        Args:
            *args: a list of images

        Returns:
             a list of images stripped

        """
        output = []
        for image in args:
            if image:
                try:
                    zDims = int(mriutil.getMriDimensions(image)[2])
                    if zDims%2 == 1:
                        target = self.buildName(image, "subset")
                        mriutil.extractSubVolume(image, target, '+2',"0:{}".format(zDims-2), self.getNTreadsMrtrix())
                        output.append(target)
                    else:
                        output.append(image)
                except ValueError:
                    output.append(image)
            else:
                output.append(False)
        return output
Beispiel #3
0
    def __extractB0SubVolumeFromDWI(self, source):
        """Perform an extraction of a subset of the source image

        Args:
            source: The input DWI image

        Returns:
             The resulting file name

        """
        self.info("Launch sub volume extraction from mrtrix")

        target = os.path.join(self.workingDir, os.path.basename(source).replace(self.config.get("prefix",'dwi'),self.config.get("prefix",'b0')))
        extractAtAxis = self.get('extract_at_axis')
        if extractAtAxis not in ["1", "2", "3"]:
            self.error('extract_at_axis must be value of 1 or 2 or 3, found {}'.format(extractAtAxis))

        #make sure that we do not extract a volumes outside of the dimension
        self.info(mriutil.extractSubVolume(source,
                                target,
                                extractAtAxis,
                                self.get("extract_at_coordinate"),
                                self.getNTreadsMrtrix()))

        self.info("End extraction from mrtrix")
        return target
Beispiel #4
0
    def __extractB0SubVolumeFromDWI(self, source):
        """Perform an extraction of a subset of the source image

        Args:
            source: The input DWI image

        Returns:
             The resulting file name

        """
        self.info("Launch sub volume extraction from mrtrix")

        target = os.path.join(
            self.workingDir,
            os.path.basename(source).replace(self.config.get("prefix", 'dwi'),
                                             self.config.get("prefix", 'b0')))
        extractAtAxis = self.get('extract_at_axis')
        if extractAtAxis not in ["1", "2", "3"]:
            self.error(
                'extract_at_axis must be value of 1 or 2 or 3, found {}'.
                format(extractAtAxis))

        #make sure that we do not extract a volumes outside of the dimension
        self.info(
            mriutil.extractSubVolume(source, target, extractAtAxis,
                                     self.get("extract_at_coordinate"),
                                     self.getNTreadsMrtrix()))

        self.info("End extraction from mrtrix")
        return target
Beispiel #5
0
    def __extractWhiteMatterFrom5tt(self, source):
        """Extract the white matter part from the act

        Args:
            An 5tt image

        Returns:
            the resulting file filename

        """

        target = self.buildName(source, ["wm", "mask"])
        self.info(
            mriutil.extractSubVolume(source, target,
                                     self.get('act_extract_at_axis'),
                                     self.get("act_extract_at_coordinate"),
                                     self.getNTreadsMrtrix()))
        return target
Beispiel #6
0
    def __extractWhiteMatterFrom5tt(self, source):
        """Extract the white matter part from the act

        Args:
            An 5tt image

        Returns:
            the resulting file filename

        """

        target = self.buildName(source, ["wm", "mask"])
        self.info(mriutil.extractSubVolume(source,
                                target,
                                self.get('act_extract_at_axis'),
                                self.get("act_extract_at_coordinate"),
                                self.getNTreadsMrtrix()))
        return target
Beispiel #7
0
    def __extractB0APSubVolumeFromDWI(self, source):
        self.info("Launch sub volume extraction from mrtrix")

        #rename the file B0
        target = os.path.join(
            self.workingDir,
            os.path.basename(source).replace(self.config.get("prefix", 'dwi'),
                                             self.config.get("prefix",
                                                             'b0AP')))
        extractAtAxis = self.get('b0AP_extract_at_axis')
        if extractAtAxis not in ["1", "2", "3"]:
            self.error(
                'extract_at_axis must be value of 1 or 2 or 3, found {}'.
                format(extractAtAxis))

        #make sure that we do not extract a volumes outside of the dimension
        self.info(
            mriutil.extractSubVolume(source, target, extractAtAxis,
                                     self.get("b0AP_extract_at_coordinate"),
                                     self.getNTreadsMrtrix()))

        self.info("End extraction from mrtrix")
        return target
Beispiel #8
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')))

        # Extract first n b0s from DWI
        self.info(mriutil.extractFirstB0sFromDWI(dwi, b0, bVals, self.getNTreadsMrtrix()))

        # Get number of b0s extracted from DWI
	tDims = int(mriutil.getMriDimensions(b0)[3])

        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
            # Extract same number of volumes b0PA
	    try:
	        b0APDim = int(mriutil.getMriDimensions(b0AP)[3])
        	target = os.path.join(self.workingDir,
               	         os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0_ap')))
            	self.info(mriutil.extractSubVolume(b0AP, target, '+3', "{}:{}".format(b0APDim-tDims, b0APDim-1 ), self.getNTreadsMrtrix()))
            	b0AP = target
	    except:
		b0APDim = 1

        if self.get("phase_enc_dir") == "1" and b0PA and b0AP is False:
            b0AP = b0
            # Extract same number of volumes b0PA
            try:
		b0PADim = int(mriutil.getMriDimensions(b0PA)[3])
		target = os.path.join(self.workingDir,
                          os.path.basename(dwi).replace(self.get("prefix", 'dwi'), self.get("prefix", 'b0_pa')))
	        self.info(mriutil.extractSubVolume(b0PA, target, '+3', "{}:{}".format(b0PADim-tDims, b0PADim-1), self.getNTreadsMrtrix()))
		b0PA = target
	    except:
		b0PADim = 1

        topupConfigFile = self.__checkOddEvenNumberOfSlices(dwi)

        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"))
                self.dimB0s = [mriutil.getNbDirectionsFromDWI(b0PA), mriutil.getNbDirectionsFromDWI(b0AP)]
            elif self.get("phase_enc_dir") == "1":
                concatenateB0Image = self.__concatenateB0(b0AP, b0PA, self.buildName("b0ap_b0pa", None, "nii.gz"))
                self.dimB0s = [mriutil.getNbDirectionsFromDWI(b0AP), mriutil.getNbDirectionsFromDWI(b0PA)]

            if int(mriutil.getMriDimensions(dwi)[2]) % 2 == 1: # Number of slice in z axis
                if 'force' not in self.get('crop'): # Use odd number
                    [dwi, b0, b0AP, b0PA, concatenateB0Image] = self.__cropNumberOfSlices(dwi, b0, b0AP, b0PA, concatenateB0Image)

            # Select config File for topup
            topupConfigFile = self.__checkOddEvenNumberOfSlices(dwi)

            # Create the acquisition parameter file
            acqpTopup = self.__createAcquisitionParameterFile('topup')

            # Run topup on concatenate B0 image
            [topupBaseName, topupImage] = self.__topup(concatenateB0Image, acqpTopup, topupConfigFile)
            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, _notUsed_a, _notUsed_b = 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, bEnc)

        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'))