Esempio n. 1
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
Esempio n. 2
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
Esempio n. 3
0
    def __isValidEncoding(self, nbDirection, type):
        """Determine if an image with a prefix exists into the subject directory

        Args:
            nbDirection: number of direction into DWI image
            type: type of encoding file. Valid values are: .b, .bval, .bvec

        Returns:
            a Boolean that represent if the encoding file is valid

        """
        encoding = util.getImage(self.config, self.workingDir, 'grad', None, type)
        if not encoding:
            self.logger.warning("No {} encoding file found in directory: {}"
                                .format(type, self.workingDir))
            return False

        f = open(encoding,'r')
        lines = f.readlines()
        f.close()

        if type=='.bval':
            for line in lines:
                nbElements = len(line.split())
                if nbElements != nbDirection:
                    self.logger.warning("Expecting {} elements in {} file, counting {}"
                                        .format(nbDirection, encoding, nbElements))
                    return False

        elif type=='.bvec':
            if len(lines) != 3:
                self.logger.warning("Expecting 3 vectors in {} file, counting {}".format(encoding, len(lines)))
                return False
            for line in lines:
                if len(line.split()) != nbDirection:
                    self.logger.warning("Expecting {} values in {} file, counting {}"
                                        .format(nbDirection, encoding, len(line.split())))
                    return False

        elif type=='.b':
            if len(lines) != nbDirection:
                self.logger.warning("Expecting {} lines in {} file, counting {}".format(nbDirection, type, len(lines)))
                return False

            for index, line in enumerate(lines):
                if index == 0:
                    for token in line.split():
                        if token not in "0" :
                            self.logger.warning("Expecting only zero values in the first line of file {}, found value {}"
                                                .format(encoding, token))
                            return False
                if len(line.split()) != 4:
                    self.logger.warning("Expecting 4 elements at line {} of file {}, counting {}"
                                        .format(index+1, encoding, len(line.split())))
                    return False
        else:
            self.logger.warning("Unknown encoding file type")
            return False
        return True
Esempio n. 4
0
    def isAToadSubject(self):
        """Determine if the directory contain all the necessary images to be consider a toad subject.

        Must have at least.
            1 high resolution anatomical image (nii or nii.gz)
            1 diffusion weighted image (nii or nii.gz)
            A corresponding B (.b) encoding or a pair of bvecs (.bvecs), bvals (.bvals) encoding file

        Returns:
            False if one of those file are missing, True otherwise

        """
        result = True

        if os.path.exists(self.backupDir):
                self.info("{} directory exists, assuming validation have already done before".format(self.backupDir))
                result = True
        else:
            if not (util.getImage(self.config, self.workingDir, 'anat') or
                        util.getImage(self.config, self.workingDir, 'anat', None, 'nii')):
                self.warning("No high resolution image found into {} directory".format(self.workingDir))
                result = False

            if not (util.getImage(self.config, self.workingDir, 'dwi') or
                    util.getImage(self.config, self.workingDir, 'dwi', None, 'nii')):
                self.warning("No diffusion weight image found into {} directory".format(self.workingDir))
                result = False

            if (not util.getImage(self.config, self.workingDir,'grad', None, 'b')) and \
                    (not util.getImage(self.config, self.workingDir,'grad', None, 'bvals') or not
                    util.getImage(self.config, self.workingDir,'grad', None, 'bvecs')):
                self.warning("No valid .b encoding or (.bvals, .bvecs) files found in directory: {}".format(self.workingDir))
                result = False

        return result
Esempio n. 5
0
    def getImage(self, dir, prefix, postfix=None, ext="nii"):
        """A simple utility function that return an mri image given certain criteria

        this is a wrapper over mriutil getImage function

        Args:
            dir:     the directory where looking for the image
            prefix:  an expression that the filename should start with
            postfix: an expression that the filename should end with (excluding the extension)
            ext:     name of the extension of the filename

        Returns:
            the absolute filename if found, False otherwise

        """
        return util.getImage(self.config, dir, prefix, postfix, ext)
Esempio n. 6
0
    def isAToadSubject(self):
        """Determine if the directory contain all the necessary images to be consider a toad subject.

        Must have at least.
            1 high resolution anatomical image (nii or nii.gz)
            1 diffusion weighted image (nii or nii.gz)
            A corresponding B (.b) encoding or a pair of bvecs (.bvecs), bvals (.bvals) encoding file

        Returns:
            False if one of those file are missing, True otherwise

        """
        result = True

        if os.path.exists(self.backupDir):
            self.info(
                "{} directory exists, assuming validation have already done before"
                .format(self.backupDir))
            result = True
        else:

            if not (util.getImage(self.config, self.workingDir, 'anat')
                    or util.getImage(self.config, self.workingDir, 'anat',
                                     None, 'nii')):
                self.warning(
                    "No high resolution image found into {} directory".format(
                        self.workingDir))
                result = False

            if not (util.getImage(self.config, self.workingDir, 'dwi')
                    or util.getImage(self.config, self.workingDir, 'dwi', None,
                                     'nii')):
                self.warning(
                    "No diffusion weight image found into {} directory".format(
                        self.workingDir))
                result = False

            if (not util.getImage(self.config, self.workingDir, 'grad', None, 'b')) and \
                    (not util.getImage(self.config, self.workingDir, 'grad', None, 'bvals') or not
                    util.getImage(self.config, self.workingDir, 'grad', None, 'bvecs')):
                self.warning(
                    "No valid .b encoding or (.bvals, .bvecs) files found in directory: {}"
                    .format(self.workingDir))
                result = False

        return result
Esempio n. 7
0
 def wrapper(*args):
     arguments = [self.config, directory] + list(args)
     return util.getImage(*arguments)
Esempio n. 8
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
Esempio n. 9
0
    def __isValidEncoding(self, nbDirection, type):
        """Determine if an image with a prefix exists into the subject directory

        Args:
            nbDirection: number of direction into DWI image
            type: type of encoding file. Valid values are: .b, .bval, .bvec

        Returns:
            a Boolean that represent if the encoding file is valid

        """
        encoding = util.getImage(self.config, self.workingDir, 'grad', None,
                                 type)
        if not encoding:
            self.logger.warning(
                "No {} encoding file found in directory: {}".format(
                    type, self.workingDir))
            return False

        f = open(encoding, 'r')
        lines = f.readlines()
        f.close()

        if type == '.bval':
            for line in lines:
                nbElements = len(line.split())
                if nbElements != nbDirection:
                    self.logger.warning(
                        "Expecting {} elements in {} file, counting {}".format(
                            nbDirection, encoding, nbElements))
                    return False

        elif type == '.bvec':
            if len(lines) != 3:
                self.logger.warning(
                    "Expecting 3 vectors in {} file, counting {}".format(
                        encoding, len(lines)))
                return False
            for line in lines:
                if len(line.split()) != nbDirection:
                    self.logger.warning(
                        "Expecting {} values in {} file, counting {}".format(
                            nbDirection, encoding, len(line.split())))
                    return False

        elif type == '.b':
            if len(lines) != nbDirection:
                self.logger.warning(
                    "Expecting {} lines in {} file, counting {}".format(
                        nbDirection, type, len(lines)))
                return False

            for index, line in enumerate(lines):
                if index == 0:
                    for token in line.split():
                        if token not in "0":
                            self.logger.warning(
                                "Expecting only zero values in the first line of file {}, found value {}"
                                .format(encoding, token))
                            return False
                if len(line.split()) != 4:
                    self.logger.warning(
                        "Expecting 4 elements at line {} of file {}, counting {}"
                        .format(index + 1, encoding, len(line.split())))
                    return False
        else:
            self.logger.warning("Unknown encoding file type")
            return False
        return True
Esempio n. 10
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
Esempio n. 11
0
 def wrapper(*args):
     arguments = [self.config, directory] + list(args)
     return util.getImage(*arguments)