예제 #1
0
def maskDirectoryStructure(FH, masking=True):
    if masking:
        FH.tmpDir = fh.createSubDir(FH.subjDir, "masking")
        FH.logDir = fh.createLogDir(FH.tmpDir)
    else:
        FH.tmpDir = fh.createSubDir(FH.subjDir, "tmp")
        FH.logDir = fh.createLogDir(FH.subjDir)
예제 #2
0
def maskDirectoryStructure(FH, masking=True):
    if masking:
        FH.tmpDir = fh.createSubDir(FH.subjDir, "masking")
        FH.logDir = fh.createLogDir(FH.tmpDir)
    else:
        FH.tmpDir = fh.createSubDir(FH.subjDir, "tmp")
        FH.logDir = fh.createLogDir(FH.subjDir)
예제 #3
0
def setupInitModel(inputModel, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space
    """
    errorMsg = "Failed to properly set up initModel."

    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, "init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(
                inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                errorMsg = "Required mask for the --init-model does not exist: " + str(
                    mask)
                raise
            standardFH = rfh.RegistrationPipeFH(imageFile,
                                                mask=mask,
                                                basedir=initModelDir)
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    errorMsg = "_native.mnc file included but associated mask not found"
                    raise
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName,
                                                      mask=mask,
                                                      basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        nativeToStdXfm = None
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print errorMsg
        print "Exiting..."
        sys.exit()
예제 #4
0
def setupDirectories(outputDir, pipeName, module):
    #Setup pipeline name
    if not pipeName:
        pipeName = str(date.today()) + "_pipeline"
    
    #initilize directories class:
    dirs = StandardMBMDirectories() 
    
    #create subdirectories based on which module is being run. _processed always created 
    dirs.processedDir = fh.createSubDir(outputDir, pipeName + "_processed")
    
    if (module == "ALL") or (module=="LSQ6"):
        dirs.lsq6Dir = fh.createSubDir(outputDir, pipeName + "_lsq6")
    if (module == "ALL") or (module=="LSQ12"):
        dirs.lsq12Dir = fh.createSubDir(outputDir, pipeName + "_lsq12")
    if (module == "ALL") or (module=="NLIN"):
        dirs.nlinDir = fh.createSubDir(outputDir, pipeName + "_nlin")
    
    return dirs
예제 #5
0
def setupDirectories(outputDir, pipeName, module):
    #Setup pipeline name
    if not pipeName:
        pipeName = str(date.today()) + "_pipeline"

    #initilize directories class:
    dirs = StandardMBMDirectories()

    #create subdirectories based on which module is being run. _processed always created
    dirs.processedDir = fh.createSubDir(outputDir, pipeName + "_processed")

    if (module == "ALL") or (module == "LSQ6"):
        dirs.lsq6Dir = fh.createSubDir(outputDir, pipeName + "_lsq6")
    if (module == "ALL") or (module == "LSQ12"):
        dirs.lsq12Dir = fh.createSubDir(outputDir, pipeName + "_lsq12")
    if (module == "ALL") or (module == "NLIN"):
        dirs.nlinDir = fh.createSubDir(outputDir, pipeName + "_nlin")

    return dirs
예제 #6
0
def setupTwoLevelDirectories(csvFile, outputDir, pipeName, module):
    """Creates outputDir/pipelineName_firstlevel for twolevel_registration
       Within first level directory, creates _lsq6/12/nlin/processed for each subject,
       based on the name of the first file in the csv
    """

    if not pipeName:
        pipeName = str(date.today()) + "_pipeline"
    firstLevelDir = fh.createSubDir(outputDir, pipeName + "_firstlevel")
    fileList = open(csvFile, 'rb')
    subjectList = csv.reader(fileList, delimiter=',', skipinitialspace=True)
    subjectDirs = {}  # One StandardMBMDirectories for each subject
    index = 0
    for subj in subjectList:
        base = splitext(basename(subj[0]))[0]
        dirs = setupDirectories(firstLevelDir, base, module)
        subjectDirs[index] = dirs
        index += 1
    secondLevelDir = fh.createSubDir(outputDir, pipeName + "_secondlevel")
    dirs = setupDirectories(secondLevelDir, "second_level", "ALL")
    return (subjectDirs, dirs)
예제 #7
0
def setupTwoLevelDirectories(csvFile, outputDir, pipeName, module):
    """Creates outputDir/pipelineName_firstlevel for twolevel_registration
       Within first level directory, creates _lsq6/12/nlin/processed for each subject,
       based on the name of the first file in the csv
    """
    
    if not pipeName:
        pipeName = str(date.today()) + "_pipeline"
    firstLevelDir = fh.createSubDir(outputDir, pipeName + "_firstlevel")
    fileList = open(csvFile, 'rb')
    subjectList = csv.reader(fileList, delimiter=',', skipinitialspace=True)
    subjectDirs = {} # One StandardMBMDirectories for each subject
    index = 0
    for subj in subjectList:
        base = splitext(basename(subj[0]))[0]
        dirs = setupDirectories(firstLevelDir, base, module)
        subjectDirs[index] = dirs
        index += 1    
    secondLevelDir = fh.createSubDir(outputDir, pipeName + "_secondlevel")
    dirs = setupDirectories(secondLevelDir, "second_level", "ALL")
    return (subjectDirs, dirs)   
예제 #8
0
def setupInitModel(inputModel, pipeName, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space

        we should make sure that files related to the initial model end up in 
        a directory named analogous to all other files, i.e., {pipeline_name}_init_model
        so we need to have the pipeName here:
    """
    errorMsg = "Failed to properly set up initModel."

    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, pipeName + "_init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                raise Exception("Required mask for the --init-model does not exist: " + str(mask))
            standardFH = rfh.RegistrationPipeFH(imageFile, mask=mask, basedir=initModelDir)            
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    raise Exception("_native.mnc file included but associated mask not found")
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName, mask=mask, basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        raise Exception("Your initial model directory has both native and standard files but no transformation between them; you need to supply %s_native_to_standard.xfm" % imageBase)
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print(errorMsg)
        raise
예제 #9
0
def setupInitModel(inputModel, pipeDir=None):
    """
        Creates fileHandlers for the initModel by reading files from.
        The directory where the input is specified.
        The following files and naming scheme are required:
            name.mnc --> File in standard registration space.
            name_mask.mnc --> Mask for name.mnc
        The following can optionally be included in the same directory as the above:
            name_native.mnc --> File in native scanner space.
            name_native_mask.mnc --> Mask for name_native.mnc
            name_native_to_standard.xfm --> Transform from native space to standard space
    """
    errorMsg = "Failed to properly set up initModel."
    
    try:
        imageFile = abspath(inputModel)
        imageBase = fh.removeBaseAndExtension(imageFile)
        imageDirectory = dirname(imageFile)
        if not pipeDir:
            pipeDir = abspath(curdir)
        initModelDir = fh.createSubDir(pipeDir, "init_model")
        if not exists(imageFile):
            errorMsg = "Specified --init-model does not exist: " + str(inputModel)
            raise
        else:
            mask = imageDirectory + "/" + imageBase + "_mask.mnc"
            if not exists(mask):
                errorMsg = "Required mask for the --init-model does not exist: " + str(mask)
                raise
            standardFH = rfh.RegistrationPipeFH(imageFile, mask=mask, basedir=initModelDir)            
            #if native file exists, create FH
            nativeFileName = imageDirectory + "/" + imageBase + "_native.mnc"
            if exists(nativeFileName):
                mask = imageDirectory + "/" + imageBase + "_native_mask.mnc"
                if not exists(mask):
                    errorMsg = "_native.mnc file included but associated mask not found"
                    raise
                else:
                    nativeFH = rfh.RegistrationPipeFH(nativeFileName, mask=mask, basedir=initModelDir)
                    nativeToStdXfm = imageDirectory + "/" + imageBase + "_native_to_standard.xfm"
                    if exists(nativeToStdXfm):
                        nativeFH.setLastXfm(standardFH, nativeToStdXfm)
                    else:
                        nativeToStdXfm = None
            else:
                nativeFH = None
                nativeToStdXfm = None
            return (standardFH, nativeFH, nativeToStdXfm)
    except:
        print errorMsg
        print "Exiting..."
        sys.exit()
 def setupNames(self):
     """string munging to create necessary basenames and directories"""
     self.subjDir = fh.createSubDir(self.basedir, self.basename)
     self.logDir = fh.createLogDir(self.subjDir)
     self.resampledDir = fh.createSubDir(self.subjDir, "resampled")
     self.transformsDir = fh.createSubDir(self.subjDir, "transforms")
     self.labelsDir = fh.createSubDir(self.subjDir, "labels")
     self.tmpDir = fh.createSubDir(self.subjDir, "tmp")
     self.statsDir = fh.createSubDir(self.subjDir, "stats-volumes")
예제 #11
0
 def run(self):
     
     if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
         logger.error("Incorrect registration method specified: " + self.options.reg_method)
         sys.exit()
     
     atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
     
     """Read in atlases from directory specified in --atlas-library and 
         create fileHandling classes. Assumes atlas/label/mask groups have one 
         of the following naming schemes:
             name_average.mnc/name_labels.mnc/name_mask.mnc
             name.mnc/name_labels.mnc/name_mask.mnc
         Note that all three files are required even if masking is not used."""
     average = [] #array of input atlas averages
     labels = [] #array of input atlas labels, one for each average
     masks = [] # array of masks, one for each average
     atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
     numAtlases = 0
     for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
         if fnmatch.fnmatch(inFile, "*labels.mnc"):
             labels.append(abspath(inFile))
         elif fnmatch.fnmatch(inFile, "*mask.mnc"):
             masks.append(abspath(inFile))
         else:
             average.append(abspath(inFile))
     # check to make sure len(average)==len(labels)
     if not len(average) == len(labels):
         logger.error("Number of input atlas labels does not match averages.")
         logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
         sys.exit() 
     elif not len(average) == len(masks):
         logger.error("Number of input atlas masks does not match averages.")
         logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
         sys.exit()
     else:
     # match labels with averages
         numAtlases = len(labels)
         for iLabel in labels: 
             atlasStart = iLabel.split("_labels.mnc")
             for iAvg in average:
                 avgStart = iAvg.split("_average.mnc")
                 if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                     for iMask in masks:
                         maskStart = iMask.split("_mask.mnc")
                         if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                             atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                              mask=abspath(iMask),
                                                              basedir=atlasDir)
                             break
                     break
             atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
             atlases.append(atlasPipeFH)
     
     #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
     # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
     
     """ Create fileHandling classes for images. If a directory of masks is specified, 
         they will be assigned to the appropriate input file handlers."""
     inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
     
     templates = []
     numTemplates = len(self.args)
     
     """ If --mask is specified and we are masking brains, do it here."""
     if self.options.mask or self.options.mask_only:
         mp = MAGeTMask(atlases, 
                        inputs, 
                        numAtlases, 
                        self.options.mask_method,
                        lsq12_protocol=self.options.lsq12_protocol,
                        nlin_protocol=self.options.nlin_protocol)
         self.pipeline.addPipeline(mp)
     
     if not self.options.mask_only:
         if numTemplates > self.options.max_templates:
             numTemplates = self.options.max_templates
         # Register each atlas to each input image up to numTemplates
         for nfile in range(numTemplates):
             for afile in range(numAtlases):
                 sp = MAGeTRegister(inputs[nfile], 
                                    atlases[afile],
                                    self.options.reg_method,
                                    name="initial",
                                    createMask=False,
                                    lsq12_protocol=self.options.lsq12_protocol,
                                    nlin_protocol=self.options.nlin_protocol)
                 self.pipeline.addPipeline(sp)
             # each template needs to be added only once, but will have multiple 
             # input labels
             templates.append(inputs[nfile])
         
         # once the initial templates have been created, go and register each
         # inputFile to the templates. If --pairwise=False, do voxel voting on 
         # input-atlas registrations only
         if self.options.pairwise:
             for inputFH in inputs:
                 for tmplFH in templates:
                     if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                         sp = MAGeTRegister(inputFH, 
                                            tmplFH, 
                                            self.options.reg_method,
                                            name="templates", 
                                            createMask=False,
                                            lsq12_protocol=self.options.lsq12_protocol,
                                            nlin_protocol=self.options.nlin_protocol)
                         self.pipeline.addPipeline(sp)
                 voxel = voxelVote(inputFH, self.options.pairwise, False)
                 self.pipeline.addStage(voxel)
         else:
             # only do voxel voting in this case if there was more than one input atlas
             if numAtlases > 1:
                 for inputFH in inputs:
                     voxel = voxelVote(inputFH, self.options.pairwise, False)
                     self.pipeline.addStage(voxel)   
     
         logger.info("Number of input atlas/label pairs: " + str(numAtlases))   
         logger.info("Number of templates: " + str(numTemplates))     
예제 #12
0
파일: MBM.py 프로젝트: gdevenyi/pydpiper
    def run(self):
        options = self.options
        args = self.args

        # make sure only one of the lsq6 target options is provided
        lsq6.verifyCorrectLSQ6TargetOptions(options.bootstrap,
                                            options.init_model,
                                            options.lsq6_target)

        # if no pipeline name was provided, initialize it here with the current date
        # setupDirectories deals with a missing pipeline name well, but we use this variable
        # in some more places
        if not options.pipeline_name:
            options.pipeline_name = str(date.today()) + "_pipeline"

        # Setup output directories for different registration modules.        
        dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="ALL")
        inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir)

        # if we are running a bootstrap or lsq6_target option, pass in the correct target
        target_file_for_lsq6 = None
        target_file_directory = None
        if(options.bootstrap):
            target_file_for_lsq6 = inputFiles[0].inputFileName
            target_file_directory = fh.createSubDir(self.outputDir,options.pipeline_name + "_bootstrap_file")
        if(options.lsq6_target):
            target_file_for_lsq6 = options.lsq6_target
            target_file_directory = fh.createSubDir(self.outputDir,options.pipeline_name + "_target_file")

        #Setup init model and inital target. Function also exists if no target was specified.
        initModel, targetPipeFH = rf.setInitialTarget(options.init_model, 
                                                      target_file_for_lsq6, 
                                                      target_file_directory,
                                                      self.outputDir,
                                                      options.pipeline_name)
            
        #LSQ6 MODULE, NUC and INORM
        runLSQ6NucInorm = lsq6.LSQ6NUCInorm(inputFiles,
                                            targetPipeFH,
                                            initModel, 
                                            dirs.lsq6Dir, 
                                            options)
        self.pipeline.addPipeline(runLSQ6NucInorm.p)
        
        # LSQ12 MODULE
        # We need to specify a likeFile/space when all files are resampled
        # at the end of LSQ12. If one is not specified, use standard space. 
        # However, only change this when either an initial model is specified
        # or when an lsq12_likefile is given. If we are running a bootstrap
        # or lsq6_target pipeline, we do not have to change anything
        #
        # Also provide the lsq12 module with the resolution at which this should
        # all happen
        resolutionForLSQ12 = None
        if options.lsq12_likeFile == None:
            if initModel:
                targetPipeFH = initModel[0]
        else:
            targetPipeFH = rfh.RegistrationFHBase(os.path.abspath(options.lsq12_likeFile), 
                                                  basedir=dirs.lsq12Dir)
        resolutionForLSQ12 = rf.returnFinestResolution(targetPipeFH)


        lsq12module = lsq12.FullLSQ12(inputFiles, 
                                      dirs.lsq12Dir, 
                                      likeFile=targetPipeFH, 
                                      maxPairs=options.lsq12_max_pairs, 
                                      lsq12_protocol=options.lsq12_protocol,
                                      subject_matter=options.lsq12_subject_matter,
                                      resolution=resolutionForLSQ12)
        lsq12module.iterate()
        self.pipeline.addPipeline(lsq12module.p)
        
        #TODO: Additional NUC step here. This will impact both the lsq6 and lsq12 modules. 
        # May want to not do resampling and averaging by default. TBD. 
        
        #Target mask for registration--I HATE this hack, as is noted in check-in and
        #as a github issue. 
        if lsq12module.lsq12AvgFH.getMask()== None:
            if initModel:
                # if we are using an initial model, we can get that mask
                lsq12module.lsq12AvgFH.setMask(initModel[0].getMask())
        
        #NLIN MODULE - Register with minctracc or mincANTS based on options.reg_method
        # for now we can use the same resolution for the NLIN stages as we did for the 
        # LSQ12 stage. At some point we should look into the subject matter option...
        nlinObj = nlin.initializeAndRunNLIN(dirs.lsq12Dir,
                                            inputFiles,
                                            dirs.nlinDir,
                                            avgPrefix=options.pipeline_name,
                                            createAvg=False,
                                            targetAvg=lsq12module.lsq12AvgFH,
                                            nlin_protocol=options.nlin_protocol,
                                            reg_method=options.reg_method,
                                            resolution=resolutionForLSQ12)
        
        self.pipeline.addPipeline(nlinObj.p)
        self.nlinAverages = nlinObj.nlinAverages
        
        #STATS MODULE
        if options.calc_stats:
            #Choose final average from array of nlin averages
            finalNlin = self.nlinAverages[-1]
            # For each input file, calculate statistics from final average (finalNlin) 
            # to the inputFH space where all linear differences have been accounted for (LSQ12). 
            # The additionalXfm specified for each inputFH is the transform from the lsq6 to lsq12 
            # space for that scan. This encapsulates linear differences and is necessary for
            # some of the calculations in CalcStats.  
            for inputFH in inputFiles:
                stats = st.CalcStats(inputFH, 
                                     finalNlin, 
                                     options.stats_kernels,
                                     additionalXfm=lsq12module.lsq12AvgXfms[inputFH])
                self.pipeline.addPipeline(stats.p)
예제 #13
0
    def run(self):
        options = self.options
        args = self.args
        
        # Setup output directories for two-level model building (_processed and _nlin for now).        
        dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="NLIN")
        
        # read in files from CSV
        fileList = open(self.args[0], 'rb')
        subjectList = csv.reader(fileList, delimiter=',', skipinitialspace=True)
        subjects = {}
        index = 0
        for subj in subjectList:
            subjects[index] = rf.initializeInputFiles(subj, dirs.processedDir, maskDir=options.mask_dir)
            index += 1
        
        # testing only part of the code: run one lsq12 followed by an NLIN
        
        # this actually makes little sense, but what the hell
#         blurs = [10,5,5]
#         step = [4,4,4]
#         simplex = [20,20,20]
#         filesToAvg = []
#         LSQ12 = mm.LSQ12(inputFiles[0], inputFiles[1], blurs, step, simplex)
#         rs = ma.mincresample(inputFiles[0], inputFiles[1], likeFile=inputFiles[1])
#         filesToAvg.append(rs.outputFiles[0])
#         self.pipeline.addStage(rs)
#         self.pipeline.addPipeline(LSQ12.p)
#         LSQ12 = mm.LSQ12(inputFiles[1], inputFiles[0], blurs, step, simplex)
#         rs = ma.mincresample(inputFiles[1], inputFiles[0], likeFile=inputFiles[0])
#         filesToAvg.append(rs.outputFiles[0])
#         self.pipeline.addPipeline(LSQ12.p)
#         self.pipeline.addStage(rs)
#         lsq12AvgFile = abspath(processedDirectory) + "/" + "lsq12avg.mnc"
#         avg = ma.mincAverage(filesToAvg, lsq12AvgFile)
#         self.pipeline.addStage(avg)

        # TODO: LSQ6 registration if requested
        # TODO: LSQ12 registration if requested
        
        # for the moment assume that all input files are in LSQ12 space
        index = 0
        firstlevelNlins = [] # stores the per subject NLINs avgs
        ### first level of registrations: register within subject
        for i in range(len(subjects)):
            ### filename munging ###
            # takes the filename of the first file in the list and prepends FIRSTLEVEL- to it
            baseVol = subjects[i][0].getLastBasevol()
            subjBase = "FIRSTLEVEL-" + splitext(split(baseVol)[1])[0]
            # create an NLIN directory inside the main NLIN directory per subject
            firstNlinDirectory = fh.createSubDir(dirs.nlinDir, subjBase)
            # put the lsq12 averages in the processed directory for now
            lsq12AvgFile = abspath(dirs.processedDir) + "/" + subjBase + "-lsq12avg.mnc"
            lsq12FH = rfh.RegistrationPipeFH(lsq12AvgFile, basedir=dirs.nlinDir)
            ### step 1: create an average of all the input files per subject ###
            # TODO: optionally allow LSQ12 or LSQ6 + LSQ12 here rather than assume they come prealigned
            avg = ma.mincAverage(subjects[i], lsq12FH)
            lsq12FH.setLastBasevol(avg.outputFiles[0])
            self.pipeline.addStage(avg)
            ### step 2: run iterative ANTS model building for each subject
            NL = nl.NLINANTS(subjects[i], lsq12FH, firstNlinDirectory, options.nlin_protocol)
            NL.iterate()
            self.pipeline.addPipeline(NL.p)
            # add the last NLIN average to the volumes that will proceed to step 2
            firstlevelNlins.append(NL.nlinAvg[-1])
        ### second level of registrations: register across subjects
        ## start by averaging all the NLINs from the first level; should be replaced by an LSQ12
        lsq12AvgFile = abspath(dirs.processedDir) + "/firstlevelNlins-lsq12avg.mnc"
        lsq12FH = rfh.RegistrationPipeFH(lsq12AvgFile, basedir=dirs.nlinDir)
        avg = ma.mincAverage(firstlevelNlins, lsq12FH)
        lsq12FH.setLastBasevol(avg.outputFiles[0])
        self.pipeline.addStage(avg)
        ## run iterative ANTS model building across the per subject averages
        # TODO: allow for a different protocol here.
        NL = nl.NLINANTS(firstlevelNlins, lsq12FH, dirs.nlinDir, options.nlin_protocol)
        NL.iterate()
        self.pipeline.addPipeline(NL.p)
예제 #14
0
파일: MAGeT.py 프로젝트: edeguzman/pydpiper
    def run(self):
        checkInputFiles(self.args)
            
        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print("Incorrect registration method specified: ", self.options.reg_method)
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at 
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print("The lsq12 protocol does not exists: ", self.options.lsq12_protocol)
            print("You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/")
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print("The nlin protocol does not exists: ", self.options.nlin_protocol)
            print("You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/")
            sys.exit()
            
        # There are two variables that can be used to determine where the output
        # of the pipeline is stored: pipeline_name and outputDir
        # If the outputDir is not specified, the current working directory is used.
        if self.options.pipeline_name:
            self.outputDir += "/" + self.options.pipeline_name
            fh.makedirsIgnoreExisting(self.outputDir)
            
        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = [] #array of input atlas averages
        labels = [] #array of input atlas labels, one for each average
        masks = [] # array of masks, one for each average
        atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
        numLibraryAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if (not len(average) == len(labels)) or (not len(average) == len(masks)):
            print("\nError: not all atlases/labels/masks match.")
            print("The allowed naming conventions are:\n{atlas}.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc")
            print("\nand:\n{atlas}_average.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc\n")
            print("Check the atlas library directory: " + str(self.options.atlas_lib) + " and try again.")
            print("Exiting...")
            sys.exit() 
        else:
        # match labels with averages
            numLibraryAtlases = len(labels)
            for iLabel in labels: 
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                                 mask=abspath(iMask),
                                                                 basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
                atlases.append(atlasPipeFH)

        # exit if no atlases were found in the specified directory
        if numLibraryAtlases == 0:
            print("\nError: no atlases were found in the specified directory: %s" % self.options.atlas_lib)
            print("Exiting...")
            sys.exit()

        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
        
        templates = []
        numTemplates = len(self.args)
        
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases, 
                           inputs, 
                           numLibraryAtlases, 
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)
        
        if not self.options.mask_only:
            numLibraryAtlasesUsed = numLibraryAtlases
            if numLibraryAtlases > self.options.max_templates:
                numLibraryAtlasesUsed = self.options.max_templates
            # The first thing we need to do is to align the atlases from the
            # template library to all input files (unless there are more 
            # atlases in the given library than the specified maximum (max_templates)
            for inputFH in inputs:
                for afile in range(numLibraryAtlasesUsed):
                    sp = MAGeTRegister(inputFH, 
                                       atlases[afile],
                                       self.options.reg_method,
                                       name="initial",
                                       createMask=False,
                                       lsq12_protocol=self.options.lsq12_protocol,
                                       nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple 
                # input labels
                templates.append(inputFH)
            
            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on 
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    # in the previous loop, we aligned the atlases in the template 
                    # library to all input files. These are all stored in the 
                    # templates variable. We only need to register upto max_templates
                    # files to each input files:
                    num_currently_aligned_atlases = numLibraryAtlasesUsed
                    for tmplFH in templates:
                        # only align more atlases if not enough have been
                        # collected so far
                        if num_currently_aligned_atlases < self.options.max_templates:
                            if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                                sp = MAGeTRegister(inputFH, 
                                                   tmplFH, 
                                                   self.options.reg_method,
                                                   name="templates", 
                                                   createMask=False,
                                                   lsq12_protocol=self.options.lsq12_protocol,
                                                   nlin_protocol=self.options.nlin_protocol)
                                self.pipeline.addPipeline(sp)
                                num_currently_aligned_atlases += 1
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numLibraryAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise, False)
                        self.pipeline.addStage(voxel)   
        
            logger.info("Number of input atlas/label pairs: " + str(numLibraryAtlases))   
            logger.info("Number of templates created (all input files...): " + str(numTemplates))
            logger.info("Number of templates used for each inputfile: " + str(numLibraryAtlasesUsed))
예제 #15
0
파일: MAGeT.py 프로젝트: bcdarwin/pydpiper
    def run(self):

        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print "Incorrect registration method specified: ", self.options.reg_method
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at 
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print "The lsq12 protocol does not exists: ", self.options.lsq12_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print "The nlin protocol does not exists: ", self.options.nlin_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
            

        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = [] #array of input atlas averages
        labels = [] #array of input atlas labels, one for each average
        masks = [] # array of masks, one for each average
        atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
        numAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if not len(average) == len(labels):
            logger.error("Number of input atlas labels does not match averages.")
            logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
            sys.exit() 
        elif not len(average) == len(masks):
            logger.error("Number of input atlas masks does not match averages.")
            logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
            sys.exit()
        else:
        # match labels with averages
            numAtlases = len(labels)
            for iLabel in labels: 
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                                 mask=abspath(iMask),
                                                                 basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
                atlases.append(atlasPipeFH)
        
        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
        
        templates = []
        numTemplates = len(self.args)
        
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases, 
                           inputs, 
                           numAtlases, 
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)
        
        if not self.options.mask_only:
            if numTemplates > self.options.max_templates:
                numTemplates = self.options.max_templates
            # Register each atlas to each input image up to numTemplates
            for nfile in range(numTemplates):
                for afile in range(numAtlases):
                    sp = MAGeTRegister(inputs[nfile], 
                                       atlases[afile],
                                       self.options.reg_method,
                                       name="initial",
                                       createMask=False,
                                       lsq12_protocol=self.options.lsq12_protocol,
                                       nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple 
                # input labels
                templates.append(inputs[nfile])
            
            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on 
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    for tmplFH in templates:
                        if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                            sp = MAGeTRegister(inputFH, 
                                               tmplFH, 
                                               self.options.reg_method,
                                               name="templates", 
                                               createMask=False,
                                               lsq12_protocol=self.options.lsq12_protocol,
                                               nlin_protocol=self.options.nlin_protocol)
                            self.pipeline.addPipeline(sp)
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise, False)
                        self.pipeline.addStage(voxel)   
        
            logger.info("Number of input atlas/label pairs: " + str(numAtlases))   
            logger.info("Number of templates: " + str(numTemplates))     
예제 #16
0
 def run(self):
     
     """Directory handling etc as in MBM"""
     if not self.options.pipeline_name:
         pipeName = str(date.today()) + "_pipeline"
     else:
         pipeName = self.options.pipeline_name
     
     processedDirectory = fh.createSubDir(self.outputDir, pipeName + "_processed")
     
     """Check that correct registration method was specified"""
     if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
         logger.error("Incorrect registration method specified: " + self.options.reg_method)
         sys.exit()
     
     """Create file handling classes for each image"""
     inputs = rf.initializeInputFiles(self.args, processedDirectory, self.options.mask_dir)
     
     """Put blurs into array"""
     blurs = []
     for i in self.options.stats_kernels.split(","):
         blurs.append(float(i))
     
     """Create file handler for nlin average from MBM"""
     if self.options.nlin_avg:
         nlinFH = rfh.RegistrationFHBase(abspath(self.options.nlin_avg), processedDirectory)
     else:
         nlinFH = None
     if self.options.mbm_dir and not isdir(abspath(self.options.mbm_dir)):
         logger.error("The --mbm-directory specified does not exist: " + abspath(self.options.mbm_dir))
         sys.exit()
     
     """Get transforms from inputs to final nlin average and vice versa as well as lsq6 files"""
     if self.options.nlin_avg and self.options.mbm_dir:
         xfmsPipe = ombm.getXfms(nlinFH, inputs, self.options.input_space, abspath(self.options.mbm_dir))
         if len(xfmsPipe.stages) > 0:
             self.pipeline.addPipeline(xfmsPipe)
     else:
         logger.info("MBM directory and nlin_average not specified.")
         logger.info("Calculating pairwise nlin only without resampling to common space.")
     
     """Create a dictionary of statistics. Each subject gets an array of statistics
        indexed by inputFile."""
     subjectStats = {}
     
     """Register each image with every other image."""
     for inputFH in inputs:
         subjectStats[inputFH] = {}
         for targetFH in inputs:
             if inputFH != targetFH:
             # MF TODO: Make generalization of registration parameters easier. 
                 if self.options.reg_method == "mincANTS":
                     register = mm.LSQ12ANTSNlin(inputFH, targetFH)
                     self.pipeline.addPipeline(register.p)
                 elif self.options.reg_method == "minctracc":
                     hm = hmt.HierarchicalMinctracc(inputFH, targetFH)
                     self.pipeline.addPipeline(hm.p)
                 if nlinFH:
                     resample = ma.mincresample(inputFH, targetFH, likeFile=nlinFH)
                 else:
                     resample = ma.mincresample(inputFH, targetFH, likeFile=inputFH)
                 self.pipeline.addStage(resample)
                 inputFH.setLastBasevol(resample.outputFiles[0])
                 """Calculate statistics"""
                 stats = st.CalcChainStats(inputFH, targetFH, blurs)
                 stats.calcFullDisplacement()
                 stats.calcDetAndLogDet(useFullDisp=True)
                 self.pipeline.addPipeline(stats.p)
                 subjectStats[inputFH][targetFH] = stats.statsGroup
                 """Resample to nlin space from previous build model run, if specified"""
                 if self.options.nlin_avg and self.options.mbm_dir:
                     xfmToNlin = inputFH.getLastXfm(nlinFH, groupIndex=0)
                     res = mm.resampleToCommon(xfmToNlin, inputFH, subjectStats[inputFH][targetFH], blurs, nlinFH)
                     self.pipeline.addPipeline(res)
                 """Reset last base volume to original input before continuing to next pair in loop."""
                 inputFH.setLastBasevol(setToOriginalInput=True)
예제 #17
0
파일: MBM.py 프로젝트: edeguzman/pydpiper
    def run(self):
        options = self.options
        args = self.args

        rf.checkInputFiles(args)

        # make sure only one of the lsq6 target options is provided
        lsq6.verifyCorrectLSQ6TargetOptions(options.bootstrap,
                                            options.init_model,
                                            options.lsq6_target)

        # if no pipeline name was provided, initialize it here with the current date
        # setupDirectories deals with a missing pipeline name well, but we use this variable
        # in some more places
        if not options.pipeline_name:
            options.pipeline_name = str(date.today()) + "_pipeline"

        # Setup output directories for different registration modules.        
        dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="ALL")
        inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir)

        # if we are running a bootstrap or lsq6_target option, pass in the correct target
        target_file_for_lsq6 = None
        target_file_directory = None
        if(options.bootstrap):
            target_file_for_lsq6 = inputFiles[0].inputFileName
            target_file_directory = fh.createSubDir(self.outputDir,options.pipeline_name + "_bootstrap_file")
        if(options.lsq6_target):
            target_file_for_lsq6 = options.lsq6_target
            target_file_directory = fh.createSubDir(self.outputDir,options.pipeline_name + "_target_file")

        #Setup init model and inital target. Function also exists if no target was specified.
        initModel, targetPipeFH = rf.setInitialTarget(options.init_model, 
                                                      target_file_for_lsq6, 
                                                      target_file_directory,
                                                      self.outputDir,
                                                      options.pipeline_name)
        
        # We will create an initial verification image here. This
        # will show the user whether it is likely for the alignment to
        # work altogether (potentially the orientation of the target
        # and the input files is too different.) 
        montageBeforeRegistration = self.outputDir + "/" + options.pipeline_name + "_quality_control_target_and_inputfiles.png"
        initialVerificationImages = createQualityControlImages([targetPipeFH] + inputFiles,
                                                               montageOutPut=montageBeforeRegistration,
                                                               message="at the very start of the registration.")
        self.pipeline.addPipeline(initialVerificationImages.p)
        
        #LSQ6 MODULE, NUC and INORM
        runLSQ6NucInorm = lsq6.LSQ6NUCInorm(inputFiles,
                                            targetPipeFH,
                                            initModel, 
                                            dirs.lsq6Dir, 
                                            options)
        # TODO: This is a temporary hack: we add the output of the verification 
        # image as an input to all stages from the LSQ6 stage to make
        # sure that this image is created as soon as possible
        # This obviously is overkill, but it doens't really hurt either
        for lsq6Stage in runLSQ6NucInorm.p.stages:
            lsq6Stage.inputFiles.append(montageBeforeRegistration)
        self.pipeline.addPipeline(runLSQ6NucInorm.p)

        # At this point in the pipeline it's important to check the 
        # general alignment. If things are widly off here, there's no
        # need to continue on with the registration. Currently we will
        # inform the user by printing out a message pointing to 
        # a verification image showing slices through all files
        montageLSQ6 = self.outputDir + "/" + options.pipeline_name + "_quality_control_montage_lsq6.png"
        # TODO, base scaling factor on resolution of initial model or target
        # add the LSQ6 average file as well:
        filesToCreateImagesFrom = []
        if runLSQ6NucInorm.lsq6Avg:
            filesToCreateImagesFrom = [runLSQ6NucInorm.lsq6Avg] + inputFiles
        else:
            filesToCreateImagesFrom = inputFiles
        lsq6VerificationImages = createQualityControlImages(filesToCreateImagesFrom,
                                                            montageOutPut=montageLSQ6,
                                                            message="after the lsq6 alignment")
        self.pipeline.addPipeline(lsq6VerificationImages.p)

        # LSQ12 MODULE
        # We need to specify a likeFile/space when all files are resampled
        # at the end of LSQ12. If one is not specified, use standard space. 
        # However, only change this when either an initial model is specified
        # or when an lsq12_likefile is given. If we are running a bootstrap
        # or lsq6_target pipeline, we do not have to change anything
        #
        # Also provide the lsq12 module with the resolution at which this should
        # all happen
        resolutionForLSQ12 = None
        if options.lsq12_likeFile == None:
            if initModel:
                targetPipeFH = initModel[0]
        else:
            targetPipeFH = rfh.RegistrationFHBase(os.path.abspath(options.lsq12_likeFile), 
                                                  basedir=dirs.lsq12Dir)
        resolutionForLSQ12 = rf.returnFinestResolution(targetPipeFH)


        lsq12module = lsq12.FullLSQ12(inputFiles, 
                                      dirs.lsq12Dir,
                                      queue_type=options.queue_type,
                                      likeFile=targetPipeFH, 
                                      maxPairs=options.lsq12_max_pairs, 
                                      lsq12_protocol=options.lsq12_protocol,
                                      subject_matter=options.lsq12_subject_matter,
                                      resolution=resolutionForLSQ12)
        lsq12module.iterate()
        # TODO: This is also a temporary hack: we add the output of the verification 
        # image as an input to all stages from the LSQ12 stage to make
        # sure that this image is created as soon as possible
        # This obviously is overkill, but it doens't really hurt either
        for lsq12Stage in lsq12module.p.stages:
            lsq12Stage.inputFiles.append(montageLSQ6)
        self.pipeline.addPipeline(lsq12module.p)
        
        #TODO: Additional NUC step here. This will impact both the lsq6 and lsq12 modules. 
        # May want to not do resampling and averaging by default. TBD. 
        
        #Target mask for registration--I HATE this hack, as is noted in check-in and
        #as a github issue. 
        if lsq12module.lsq12AvgFH.getMask()== None:
            if initModel:
                # if we are using an initial model, we can get that mask
                lsq12module.lsq12AvgFH.setMask(initModel[0].getMask())
        
        #NLIN MODULE - Register with minctracc or mincANTS based on options.reg_method
        # for now we can use the same resolution for the NLIN stages as we did for the 
        # LSQ12 stage. At some point we should look into the subject matter option...
        nlinObj = nlin.initializeAndRunNLIN(dirs.lsq12Dir,
                                            inputFiles,
                                            dirs.nlinDir,
                                            avgPrefix=options.pipeline_name,
                                            createAvg=False,
                                            targetAvg=lsq12module.lsq12AvgFH,
                                            nlin_protocol=options.nlin_protocol,
                                            reg_method=options.reg_method,
                                            resolution=resolutionForLSQ12)
        
        self.pipeline.addPipeline(nlinObj.p)
        self.nlinAverages = nlinObj.nlinAverages
        
        #STATS MODULE
        if options.calc_stats:
            #Choose final average from array of nlin averages
            finalNlin = self.nlinAverages[-1]
            # For each input file, calculate statistics from final average (finalNlin) 
            # to the inputFH space where all linear differences have been accounted for (LSQ12). 
            # The additionalXfm specified for each inputFH is the transform from the lsq6 to lsq12 
            # space for that scan. This encapsulates linear differences and is necessary for
            # some of the calculations in CalcStats.  
            for inputFH in inputFiles:
                stats = st.CalcStats(inputFH, 
                                     finalNlin, 
                                     options.stats_kernels,
                                     additionalXfm=lsq12module.lsq12AvgXfms[inputFH])
                self.pipeline.addPipeline(stats.p)
예제 #18
0
    def run(self):
        """Directory handling etc as in MBM"""
        if not self.options.pipeline_name:
            pipeName = str(date.today()) + "_pipeline"
        else:
            pipeName = self.options.pipeline_name

        processedDirectory = fh.createSubDir(self.outputDir,
                                             pipeName + "_processed")
        """Check that correct registration method was specified"""
        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            logger.error("Incorrect registration method specified: " +
                         self.options.reg_method)
            sys.exit()
        """Create file handling classes for each image"""
        inputs = rf.initializeInputFiles(self.args, processedDirectory,
                                         self.options.mask_dir)
        """Put blurs into array"""
        blurs = []
        for i in self.options.stats_kernels.split(","):
            blurs.append(float(i))
        """Create file handler for nlin average from MBM"""
        if self.options.nlin_avg:
            nlinFH = rfh.RegistrationFHBase(abspath(self.options.nlin_avg),
                                            processedDirectory)
        else:
            nlinFH = None
        if self.options.mbm_dir and not isdir(abspath(self.options.mbm_dir)):
            logger.error("The --mbm-directory specified does not exist: " +
                         abspath(self.options.mbm_dir))
            sys.exit()
        """Get transforms from inputs to final nlin average and vice versa as well as lsq6 files"""
        if self.options.nlin_avg and self.options.mbm_dir:
            rf.getXfms(nlinFH, inputs, self.options.input_space,
                       abspath(self.options.mbm_dir))
        else:
            logger.info("MBM directory and nlin_average not specified.")
            logger.info(
                "Calculating pairwise nlin only without resampling to common space."
            )
        """Create a dictionary of statistics. Each subject gets an array of statistics
           indexed by inputFile."""
        subjectStats = {}
        """Register each image with every other image."""
        for inputFH in inputs:
            subjectStats[inputFH] = {}
            for targetFH in inputs:
                if inputFH != targetFH:
                    # MF TODO: Make generalization of registration parameters easier.
                    if self.options.reg_method == "mincANTS":
                        register = mm.LSQ12ANTSNlin(inputFH, targetFH)
                        self.pipeline.addPipeline(register.p)
                    elif self.options.reg_method == "minctracc":
                        hm = mm.HierarchicalMinctracc(inputFH, targetFH)
                        self.pipeline.addPipeline(hm.p)
                    if nlinFH:
                        resample = ma.mincresample(inputFH,
                                                   targetFH,
                                                   likeFile=nlinFH)
                    else:
                        resample = ma.mincresample(inputFH,
                                                   targetFH,
                                                   likeFile=inputFH)
                    self.pipeline.addStage(resample)
                    inputFH.setLastBasevol(resample.outputFiles[0])
                    """Calculate statistics"""
                    stats = st.CalcChainStats(inputFH, targetFH, blurs)
                    stats.calcFullDisplacement()
                    stats.calcDetAndLogDet(useFullDisp=True)
                    self.pipeline.addPipeline(stats.p)
                    subjectStats[inputFH][targetFH] = stats.statsGroup
                    """Resample to nlin space from previous build model run, if specified"""
                    if self.options.nlin_avg and self.options.mbm_dir:
                        xfmToNlin = inputFH.getLastXfm(nlinFH, groupIndex=0)
                        res = mm.resampleToCommon(
                            xfmToNlin, inputFH,
                            subjectStats[inputFH][targetFH], blurs, nlinFH)
                        self.pipeline.addPipeline(res)
                    """Reset last base volume to original input before continuing to next pair in loop."""
                    inputFH.setLastBasevol(setToOriginalInput=True)
예제 #19
0
    def run(self):

        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print "Incorrect registration method specified: ", self.options.reg_method
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print "The lsq12 protocol does not exists: ", self.options.lsq12_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print "The nlin protocol does not exists: ", self.options.nlin_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()

        # There are two variables that can be used to determine where the output
        # of the pipeline is stored: pipeline_name and outputDir
        # If the outputDir is not specified, the current working directory is used.
        if self.options.pipeline_name:
            self.outputDir += "/" + self.options.pipeline_name
            fh.makedirsIgnoreExisting(self.outputDir)

        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = []  #array of input atlas averages
        labels = []  #array of input atlas labels, one for each average
        masks = []  # array of masks, one for each average
        atlases = [
        ]  #array of RegistrationPipeFH classes for each atlas/label pair
        numLibraryAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if (not len(average) == len(labels)) or (not len(average)
                                                 == len(masks)):
            print "\nError: not all atlases/labels/masks match."
            print "The allowed naming conventions are:\n{atlas}.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc"
            print "\nand:\n{atlas}_average.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc\n"
            print "Check the atlas library directory: " + str(
                self.options.atlas_lib) + " and try again."
            print "Exiting..."
            sys.exit()
        else:
            # match labels with averages
            numLibraryAtlases = len(labels)
            for iLabel in labels:
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(
                                    abspath(iAvg),
                                    mask=abspath(iMask),
                                    basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True)
                atlases.append(atlasPipeFH)

        # exit if no atlases were found in the specified directory
        if numLibraryAtlases == 0:
            print "\nError: no atlases were found in the specified directory: %s" % self.options.atlas_lib
            print "Exiting..."
            sys.exit()

        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args,
                                      self.outputDir,
                                      maskDir=self.options.mask_dir)

        templates = []
        numTemplates = len(self.args)
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases,
                           inputs,
                           numLibraryAtlases,
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)

        if not self.options.mask_only:
            numLibraryAtlasesUsed = numLibraryAtlases
            if numLibraryAtlases > self.options.max_templates:
                numLibraryAtlasesUsed = self.options.max_templates
            # The first thing we need to do is to align the atlases from the
            # template library to all input files (unless there are more
            # atlases in the given library than the specified maximum (max_templates)
            for inputFH in inputs:
                for afile in range(numLibraryAtlasesUsed):
                    sp = MAGeTRegister(
                        inputFH,
                        atlases[afile],
                        self.options.reg_method,
                        name="initial",
                        createMask=False,
                        lsq12_protocol=self.options.lsq12_protocol,
                        nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple
                # input labels
                templates.append(inputFH)

            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    # in the previous loop, we aligned the atlases in the template
                    # library to all input files. These are all stored in the
                    # templates variable. We only need to register upto max_templates
                    # files to each input files:
                    num_currently_aligned_atlases = numLibraryAtlasesUsed
                    for tmplFH in templates:
                        # only align more atlases if not enough have been
                        # collected so far
                        if num_currently_aligned_atlases < self.options.max_templates:
                            if tmplFH.getLastBasevol(
                            ) != inputFH.getLastBasevol():
                                sp = MAGeTRegister(
                                    inputFH,
                                    tmplFH,
                                    self.options.reg_method,
                                    name="templates",
                                    createMask=False,
                                    lsq12_protocol=self.options.lsq12_protocol,
                                    nlin_protocol=self.options.nlin_protocol)
                                self.pipeline.addPipeline(sp)
                                num_currently_aligned_atlases += 1
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numLibraryAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise,
                                          False)
                        self.pipeline.addStage(voxel)

            logger.info("Number of input atlas/label pairs: " +
                        str(numLibraryAtlases))
            logger.info("Number of templates created (all input files...): " +
                        str(numTemplates))
            logger.info("Number of templates used for each inputfile: " +
                        str(numLibraryAtlasesUsed))