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