def __init__(self, inputFH, targetFH, lsq12_protocol=None, nlin_protocol=None, includeLinear = True, subject_matter = None, defaultDir="tmp"): self.p = Pipeline() self.inputFH = inputFH self.targetFH = targetFH self.lsq12_protocol = lsq12_protocol self.nlin_protocol = nlin_protocol self.includeLinear = includeLinear self.subject_matter = subject_matter self.defaultDir = defaultDir if ((self.lsq12_protocol == None and self.subject_matter==None) or self.nlin_protocol == None): # the resolution of the registration should be based on the target self.fileRes = rf.returnFinestResolution(self.targetFH) else: self.fileRes = None self.buildPipeline()
def __init__(self, inputFH, targetFH, lsq12_protocol=None, nlin_protocol=None, includeLinear=True, subject_matter=None, defaultDir="tmp"): self.p = Pipeline() self.inputFH = inputFH self.targetFH = targetFH self.lsq12_protocol = lsq12_protocol self.nlin_protocol = nlin_protocol self.includeLinear = includeLinear self.subject_matter = subject_matter self.defaultDir = defaultDir if ((self.lsq12_protocol == None and self.subject_matter == None) or self.nlin_protocol == None): # the resolution of the registration should be based on the target self.fileRes = rf.returnFinestResolution(self.targetFH) else: self.fileRes = None self.buildPipeline()
def buildPipeline(self): lsq12LikeFH = None resolutionForLSQ12 = None if self.initModel: lsq12LikeFH = self.initModel[0] elif self.options.lsq12_likeFile: lsq12LikeFH = self.options.lsq12_likeFile if lsq12LikeFH == None and self.options.lsq12_subject_matter == None: print "\nError: the FullIterativeLSQ12Nlin module was called without specifying either an initial model, nor an lsq12_subject_matter. Currently that means that the code can not determine the resolution at which the registrations should be run. Please specify one of the two. Exiting\n" sys.exit() if not (lsq12LikeFH == None): resolutionForLSQ12 = rf.returnFinestResolution(lsq12LikeFH) lsq12module = lsq12.FullLSQ12( self.inputs, self.dirs.lsq12Dir, likeFile=lsq12LikeFH, maxPairs=self.options.lsq12_max_pairs, lsq12_protocol=self.options.lsq12_protocol, subject_matter=self.options.lsq12_subject_matter, resolution=resolutionForLSQ12) lsq12module.iterate() self.p.addPipeline(lsq12module.p) self.lsq12Params = lsq12module.lsq12Params if lsq12module.lsq12AvgFH.getMask() == None: if self.initModel: lsq12module.lsq12AvgFH.setMask(self.initModel[0].getMask()) if not self.avgPrefix: self.avgPrefix = self.options.pipeline_name # same as in MBM.py: # 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... nlinModule = nlin.initializeAndRunNLIN( self.dirs.lsq12Dir, self.inputs, self.dirs.nlinDir, avgPrefix=self.avgPrefix, createAvg=False, targetAvg=lsq12module.lsq12AvgFH, nlin_protocol=self.options.nlin_protocol, reg_method=self.options.reg_method, resolution=resolutionForLSQ12) self.p.addPipeline(nlinModule.p) self.nlinFH = nlinModule.nlinAverages[-1] self.nlinParams = nlinModule.nlinParams self.initialTarget = nlinModule.initialTarget # Now we need the full transform to go back to LSQ6 space for i in self.inputs: linXfm = lsq12module.lsq12AvgXfms[i] nlinXfm = i.getLastXfm(self.nlinFH) outXfm = st.createOutputFileName(i, nlinXfm, "transforms", "_with_additional.xfm") xc = ma.xfmConcat([linXfm, nlinXfm], outXfm, fh.logFromFile(i.logDir, outXfm)) self.p.addStage(xc) i.addAndSetXfmToUse(self.nlinFH, outXfm)
def __init__( self, inSource, inTarget, output=None, # ability to specify output transform when using strings for input logFile=None, maskFile=None, defaultDir="transforms", blur=0.56, resample_step=4, registration_step=10, w_translations=8, rotational_range=50, rotational_interval=10, mousedata=False): CmdStage.__init__(self, None) #don't do any arg processing in superclass # handling of the input files try: if rf.isFileHandler(inSource, inTarget): self.source = inSource.getBlur(fwhm=blur) self.target = inTarget.getBlur(fwhm=blur) if (output == None): self.output = inSource.registerVolume(inTarget, defaultDir) else: self.output = output if (logFile == None): self.logFile = fh.logFromFile(inSource.logDir, self.output) else: self.logFile = logFile else: # TODO: fix this to work with string input files self.source = inSource self.target = inTarget except: print "Failed in putting together RotationalMinctracc command; unexpected error:" raise # The resolution is used to determine the step size and # blurring kernels for the rotational minctracc call. This # should be based on the target, not the input file (source) highestResolution = rf.returnFinestResolution(inTarget) # TODO: finish the following if clause... hahaha #if(mousedata): self.addDefaults(resample_step * highestResolution, registration_step * highestResolution, w_translations * highestResolution, int(rotational_range), int(rotational_interval)) # potentially add a mask to the command self.finalizeCommand(inTarget, maskFile) self.setName() self.colour = "green"
def __init__(self, inSource, inTarget, output = None, # ability to specify output transform when using strings for input logFile = None, maskFile = None, defaultDir="transforms", blur=0.56, resample_step=4, registration_step=10, w_translations=8, rotational_range=50, rotational_interval=10, mousedata=False): CmdStage.__init__(self, None) #don't do any arg processing in superclass # handling of the input files try: if rf.isFileHandler(inSource, inTarget): self.source = inSource.getBlur(fwhm=blur) self.target = inTarget.getBlur(fwhm=blur) if(output == None): self.output = inSource.registerVolume(inTarget, defaultDir) else: self.output = output if(logFile == None): self.logFile = fh.logFromFile(inSource.logDir, self.output) else: self.logFile = logFile else: # TODO: fix this to work with string input files self.source = inSource self.target = inTarget except: print "Failed in putting together RotationalMinctracc command." print "Unexpected error: ", sys.exc_info() raise highestResolution = rf.returnFinestResolution(inSource) # TODO: finish the following if clause... hahaha #if(mousedata): self.addDefaults(resample_step * highestResolution, registration_step * highestResolution, w_translations * highestResolution, int(rotational_range), int(rotational_interval)) # potentially add a mask to the command self.finalizeCommand(inTarget, maskFile) self.setName() self.colour = "green"
def run(self): options = self.options args = self.args # Setup output directories for LSQ12 registration. dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="LSQ12") #Initialize input files from args inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir) # we potentially use the resolution of the input files to determine some # minctracc parameters and blurring kernels (if no protocol or subject matter is specified) resolutionForLSQ12 = None #Set up like file for resampling, if one is specified if options.lsq12_likeFile: likeFH = RegistrationFHBase(abspath(options.lsq12_likeFile), basedir=dirs.lsq12Dir) resolutionForLSQ12 = rf.returnFinestResolution(likeFH) else: likeFH = None # if there is not a like file, we can use the resolution of # the first input file. The assumption being that all input # files have the same resolution resolutionForLSQ12 = rf.returnFinestResolution(inputFiles[0]) #Iterative LSQ12 model building lsq12 = FullLSQ12(inputFiles, dirs.lsq12Dir, likeFile=likeFH, maxPairs=options.lsq12_max_pairs, lsq12_protocol=options.lsq12_protocol, subject_matter=options.lsq12_subject_matter, resolution=resolutionForLSQ12) lsq12.iterate() self.pipeline.addPipeline(lsq12.p)
def run(self): options = self.options args = self.args # Setup output directories for non-linear registration. dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="NLIN") #Initialize input files (from args) inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir) #Setup initial target and run iterative non-linear registration if options.target_avg: createAvg = False else: createAvg = True resolutionForNlin = None if options.target_avg: resolutionForNlin = returnFinestResolution(options.target_avg) nlinObj = initializeAndRunNLIN(self.outputDir, inputFiles, dirs.nlinDir, avgPrefix=options.pipeline_name, createAvg=createAvg, targetAvg=options.target_avg, targetMask=options.target_mask, nlin_protocol=options.nlin_protocol, reg_method=options.reg_method, resolution=resolutionForNlin) self.pipeline.addPipeline(nlinObj.p) self.nlinAverages = nlinObj.nlinAverages """Calculate statistics between final nlin average and individual mice""" if options.calc_stats: """Choose final average from array of nlin averages""" finalNlin = self.nlinAverages[-1] """For each input file, calculate statistics from finalNlin to input""" for inputFH in inputFiles: stats = CalcStats(inputFH, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p)
def __init__(self, inputArray, outputDir, likeFile=None, maxPairs=None, lsq12_protocol=None, subject_matter=None): self.p = Pipeline() """Initial inputs should be an array of fileHandlers with lastBasevol in lsq12 space""" self.inputs = inputArray """Output directory should be _nlin """ self.lsq12Dir = outputDir """likeFile for resampling""" self.likeFile = likeFile """Maximum number of pairs to calculate""" self.maxPairs = maxPairs """Final lsq12 average""" self.lsq12Avg = None """Final lsq12 average file handler (e.g. the file handler associated with lsq12Avg)""" self.lsq12AvgFH = None """ Dictionary of lsq12 average transforms, which will include one per input. Key is input file handler and value is string pointing to final average lsq12 transform for that particular subject. These xfms may be used subsequently for statistics calculations. """ self.lsq12AvgXfms = {} """Create the blurring resolution from the file resolution""" if (subject_matter == None and lsq12_protocol == None): self.fileRes = rf.returnFinestResolution(self.inputs[0]) else: self.fileRes = None """"Set up parameter array""" self.lsq12Params = mp.setLSQ12MinctraccParams( self.fileRes, subject_matter=subject_matter, reg_protocol=lsq12_protocol) self.blurs = self.lsq12Params.blurs self.stepSize = self.lsq12Params.stepSize self.useGradient = self.lsq12Params.useGradient self.simplex = self.lsq12Params.simplex self.w_translations = self.lsq12Params.w_translations self.generations = self.lsq12Params.generations # Create new lsq12 group for each input prior to registration for i in range(len(self.inputs)): self.inputs[i].newGroup(groupName="lsq12")
def run(self): options = self.options args = self.args rf.checkInputFiles(args) # Setup output directories for non-linear registration. dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="NLIN") #Initialize input files (from args) inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir) #Setup initial target and run iterative non-linear registration if options.target_avg: createAvg=False else: createAvg=True resolutionForNlin = None if options.target_avg: resolutionForNlin = returnFinestResolution(options.target_avg) nlinObj = initializeAndRunNLIN(self.outputDir, inputFiles, dirs.nlinDir, avgPrefix=options.pipeline_name, createAvg=createAvg, targetAvg=options.target_avg, targetMask=options.target_mask, nlin_protocol=options.nlin_protocol, reg_method=options.reg_method, resolution=resolutionForNlin) self.pipeline.addPipeline(nlinObj.p) self.nlinAverages = nlinObj.nlinAverages """Calculate statistics between final nlin average and individual mice""" if options.calc_stats: """Choose final average from array of nlin averages""" finalNlin = self.nlinAverages[-1] """For each input file, calculate statistics from finalNlin to input""" for inputFH in inputFiles: stats = CalcStats(inputFH, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p)
def __init__(self, inputArray, targetFH, nlinOutputDir, avgPrefix, nlin_protocol): self.p = Pipeline() """Initial inputs should be an array of fileHandlers with lastBasevol in lsq12 space""" self.inputs = inputArray """Initial target should be the file handler for the lsq12 average""" self.target = targetFH """Output directory should be _nlin """ self.nlinDir = nlinOutputDir """Prefix to pre-pend to averages at each generation""" self.avgPrefix = avgPrefix """Empty array that we will fill with averages as we create them""" self.nlinAverages = [] """Create the blurring resolution from the file resolution""" if nlin_protocol==None: self.fileRes = rf.returnFinestResolution(self.inputs[0]) else: self.fileRes = None # Create new nlin group for each input prior to registration for i in range(len(self.inputs)): self.inputs[i].newGroup(groupName="nlin")
def __init__(self, inputFH, targetFH, lsq12_protocol=None, nlin_protocol=None, subject_matter=None, defaultDir="tmp"): self.p = Pipeline() self.inputFH = inputFH self.targetFH = targetFH self.lsq12_protocol = lsq12_protocol self.nlin_protocol = nlin_protocol self.subject_matter = subject_matter self.defaultDir = defaultDir if ((self.lsq12_protocol == None and self.subject_matter==None) or self.nlin_protocol == None): self.fileRes = rf.returnFinestResolution(self.inputFH) else: self.fileRes = None self.buildPipeline()
def __init__(self, inputArray, targetFH, nlinOutputDir, avgPrefix, nlin_protocol): self.p = Pipeline() """Initial inputs should be an array of fileHandlers with lastBasevol in lsq12 space""" self.inputs = inputArray """Initial target should be the file handler for the lsq12 average""" self.target = targetFH """Output directory should be _nlin """ self.nlinDir = nlinOutputDir """Prefix to pre-pend to averages at each generation""" self.avgPrefix = avgPrefix """Empty array that we will fill with averages as we create them""" self.nlinAverages = [] """Create the blurring resolution from the file resolution""" if nlin_protocol == None: self.fileRes = rf.returnFinestResolution(self.inputs[0]) else: self.fileRes = None # Create new nlin group for each input prior to registration for i in range(len(self.inputs)): self.inputs[i].newGroup(groupName="nlin")
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: (subjectDirs, dirs) = rf.setupTwoLevelDirectories(args[0], self.outputDir, options.pipeline_name, module="ALL") # read in files from CSV subjects = rf.setupSubjectHash(args[0], subjectDirs, options.mask_dir) #firstlevelNlins stores per subject NLIN avgs, subjStats stores first level stats, to be resampled at the end firstlevelNlins = [] subjStats = [] ### first level of registrations: register within subject for i in range(len(subjects)): baseVol = subjects[i][0].getLastBasevol() subjBase = splitext(split(baseVol)[1])[0] if options.input_space == "native": initModel, targetPipeFH = rf.setInitialTarget( options.init_model, options.lsq6_target, subjectDirs[i].lsq6Dir, self.outputDir) #LSQ6 MODULE, NUC and INORM runLSQ6NucInorm = lsq6.LSQ6NUCInorm(subjects[i], targetPipeFH, initModel, subjectDirs[i].lsq6Dir, options) self.pipeline.addPipeline(runLSQ6NucInorm.p) if options.input_space == "native" or options.input_space == "lsq6": #LSQ12+NLIN (registration starts here or is run after LSQ6) if options.input_space == "lsq6": initModel = None lsq12Nlin = mm.FullIterativeLSQ12Nlin(subjects[i], subjectDirs[i], options, avgPrefix=subjBase, initModel=initModel) self.pipeline.addPipeline(lsq12Nlin.p) finalNlin = lsq12Nlin.nlinFH #If no protocols are specified, use same lsq12 and nlin protocols as for first level registration if not options.lsq12_protocol: options.lsq12_protocol = lsq12Nlin.lsq12Params if not options.nlin_protocol: options.nlin_protocol = lsq12Nlin.nlinParams elif options.input_space == "lsq12": #If inputs in lsq12 space, run NLIN only lsq12AvgFile = abspath( subjectDirs[i].lsq12Dir) + "/" + subjBase + "-lsq12avg.mnc" nlinObj = nl.initializeAndRunNLIN( subjectDirs[i].lsq12Dir, subjects[i], subjectDirs[i].nlinDir, avgPrefix=subjBase, createAvg=True, targetAvg=lsq12AvgFile, targetMask=options.target_mask, nlin_protocol=options.nlin_protocol, reg_method=options.reg_method) self.pipeline.addPipeline(nlinObj.p) finalNlin = nlinObj.nlinAverages[-1] # If no protocols are specified, get lsq12 based on resolution of one of the existing input files. # Use same nlin protocol as the one we ran previously. if not options.lsq12_protocol: if not options.lsq12_subject_matter: fileRes = rf.returnFinestResolution(subjects[i][0]) options.lsq12_protocol = mp.setLSQ12MinctraccParams( fileRes, subject_matter=options.lsq12_subject_matter) if not options.nlin_protocol: options.nlin_protocol = nlinObj.nlinParams else: print "--input-space can only be native, lsq6 or lsq12. You specified: " + str( options.input_space) sys.exit() # add the last NLIN average to the volumes that will proceed to step 2 firstlevelNlins.append(finalNlin) if options.calc_stats: tmpStats = [] for s in subjects[i]: stats = st.CalcStats(s, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p) tmpStats.append(stats) subjStats.append(tmpStats) # second level of registrations: register final averages from first level # TODO: Allow for LSQ6 reg first, or just NLIN. Right now, we allow LSQ12+NLIN only firstLevelNlinsNewFH = [] for nlin in firstlevelNlins: nlinFH = rfh.RegistrationPipeFH(nlin.getLastBasevol(), mask=nlin.getMask(), basedir=dirs.processedDir) firstLevelNlinsNewFH.append(nlinFH) lsq12Nlin = mm.FullIterativeLSQ12Nlin(firstLevelNlinsNewFH, dirs, options, avgPrefix="second_level") self.pipeline.addPipeline(lsq12Nlin.p) finalNlin = lsq12Nlin.nlinFH initialTarget = lsq12Nlin.initialTarget if options.calc_stats: for s in firstLevelNlinsNewFH: stats = st.CalcStats(s, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p) # now resample the stats files from the first level registration to the common space # created by the second level of registration for i in range(len(subjects)): for s in range(len(subjects[i])): # get the last xfm from the second level registrations xfm = firstLevelNlinsNewFH[i].getLastXfm(finalNlin) p = mm.resampleToCommon(xfm, subjects[i][s], subjStats[i][s].statsGroup, options.stats_kernels, initialTarget) self.pipeline.addPipeline(p)
def run(self): options = self.options args = self.args # Setup output directories for two-level model building: (subjectDirs, dirs) = rf.setupTwoLevelDirectories(args[0], self.outputDir, options.pipeline_name, module="ALL") # read in files from CSV subjects = rf.setupSubjectHash(args[0], subjectDirs, options.mask_dir) #firstlevelNlins stores per subject NLIN avgs, subjStats stores first level stats, to be resampled at the end firstlevelNlins = [] subjStats = [] ### first level of registrations: register within subject for i in range(len(subjects)): baseVol = subjects[i][0].getLastBasevol() subjBase = splitext(split(baseVol)[1])[0] if options.input_space == "native": initModel, targetPipeFH = rf.setInitialTarget(options.init_model, options.lsq6_target, subjectDirs[i].lsq6Dir, self.outputDir, options.pipeline_name) #LSQ6 MODULE, NUC and INORM runLSQ6NucInorm = lsq6.LSQ6NUCInorm(subjects[i], targetPipeFH, initModel, subjectDirs[i].lsq6Dir, options) self.pipeline.addPipeline(runLSQ6NucInorm.p) if options.input_space=="native" or options.input_space=="lsq6": # LSQ12+NLIN (registration starts here or is run after LSQ6) if options.input_space == "lsq6": initModel=None lsq12Nlin = mm.FullIterativeLSQ12Nlin(subjects[i], subjectDirs[i], options, avgPrefix=subjBase, initModel=initModel) self.pipeline.addPipeline(lsq12Nlin.p) finalNlin = lsq12Nlin.nlinFH #If no protocols are specified, use same lsq12 and nlin protocols as for first level registration if not options.lsq12_protocol: options.lsq12_protocol = lsq12Nlin.lsq12Params if not options.nlin_protocol: options.nlin_protocol = lsq12Nlin.nlinParams elif options.input_space=="lsq12": #If inputs in lsq12 space, run NLIN only lsq12AvgFile = abspath(subjectDirs[i].lsq12Dir) + "/" + subjBase + "-lsq12avg.mnc" nlinObj = nl.initializeAndRunNLIN(subjectDirs[i].lsq12Dir, subjects[i], subjectDirs[i].nlinDir, avgPrefix=subjBase, createAvg=True, targetAvg=lsq12AvgFile, targetMask=options.target_mask, nlin_protocol=options.nlin_protocol, reg_method=options.reg_method) self.pipeline.addPipeline(nlinObj.p) finalNlin = nlinObj.nlinAverages[-1] # If no protocols are specified, get lsq12 based on resolution of one of the existing input files. # Use same nlin protocol as the one we ran previously. if not options.lsq12_protocol: if not options.lsq12_subject_matter: fileRes = rf.returnFinestResolution(subjects[i][0]) options.lsq12_protocol = mp.setLSQ12MinctraccParams(fileRes, subject_matter=options.lsq12_subject_matter) if not options.nlin_protocol: options.nlin_protocol = nlinObj.nlinParams else: print("--input-space can only be native, lsq6 or lsq12. You specified: " + str(options.input_space)) sys.exit() # add the last NLIN average to the volumes that will proceed to step 2 firstlevelNlins.append(finalNlin) if options.calc_stats: tmpStats=[] for s in subjects[i]: stats = st.CalcStats(s, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p) tmpStats.append(stats) subjStats.append(tmpStats) # second level of registrations: register final averages from first level # TODO: Allow for LSQ6 reg first, or just NLIN. Right now, we allow LSQ12+NLIN only firstLevelNlinsNewFH = [] for nlin in firstlevelNlins: nlinFH = rfh.RegistrationPipeFH(nlin.getLastBasevol(), mask=nlin.getMask(), basedir=dirs.processedDir) firstLevelNlinsNewFH.append(nlinFH) # the following call needs to figure out at what resolution the LSQ12 and NLIN stages # are supposed to be run. For this reason (if no subject matter is specified), # we will pass along the initial model lsq12Nlin = mm.FullIterativeLSQ12Nlin(firstLevelNlinsNewFH, dirs, options, avgPrefix="second_level", initModel=initModel) self.pipeline.addPipeline(lsq12Nlin.p) finalNlin = lsq12Nlin.nlinFH initialTarget = lsq12Nlin.initialTarget if options.calc_stats: for s in firstLevelNlinsNewFH: stats = st.CalcStats(s, finalNlin, options.stats_kernels) self.pipeline.addPipeline(stats.p) # now resample the stats files from the first level registration to the common space # created by the second level of registration for i in range(len(subjects)): for s in range(len(subjects[i])): # get the last xfm from the second level registrations xfm = firstLevelNlinsNewFH[i].getLastXfm(finalNlin) p = mm.resampleToCommon(xfm, subjects[i][s], subjStats[i][s].statsGroup, options.stats_kernels, initialTarget) self.pipeline.addPipeline(p)
def buildPipeline(self): lsq12LikeFH = None resolutionForLSQ12 = None if self.initModel: lsq12LikeFH = self.initModel[0] elif self.options.lsq12_likeFile: lsq12LikeFH = self.options.lsq12_likeFile if lsq12LikeFH == None and self.options.lsq12_subject_matter == None and self.providedResolution == None: print("\nError: the FullIterativeLSQ12Nlin module was called without specifying either an initial model, nor an lsq12_subject_matter. Currently that means that the code can not determine the resolution at which the registrations should be run. Please specify one of the two. Exiting\n") sys.exit() if not (lsq12LikeFH == None): resolutionForLSQ12 = rf.returnFinestResolution(lsq12LikeFH) if resolutionForLSQ12 == None and self.providedResolution == None: print("\nError: the resolution at which the LSQ12 and the NLIN registration should be run could not be determined from either the initial model nor the LSQ12 like file. Please provide the fileResolution to the FullIterativeLSQ12Nlin module. Exiting\n") sys.exit() if resolutionForLSQ12 == None and self.providedResolution: resolutionForLSQ12 = self.providedResolution lsq12module = lsq12.FullLSQ12(self.inputs, self.dirs.lsq12Dir, queue_type=self.options.queue_type, likeFile=lsq12LikeFH, maxPairs=self.options.lsq12_max_pairs, lsq12_protocol=self.options.lsq12_protocol, subject_matter=self.options.lsq12_subject_matter, resolution=resolutionForLSQ12) lsq12module.iterate() self.p.addPipeline(lsq12module.p) self.lsq12Params = lsq12module.lsq12Params if lsq12module.lsq12AvgFH.getMask()== None: if self.initModel: lsq12module.lsq12AvgFH.setMask(self.initModel[0].getMask()) if not self.avgPrefix: self.avgPrefix = self.options.pipeline_name # same as in MBM.py: # 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... nlinModule = nlin.initializeAndRunNLIN(self.dirs.lsq12Dir, self.inputs, self.dirs.nlinDir, avgPrefix=self.avgPrefix, createAvg=False, targetAvg=lsq12module.lsq12AvgFH, nlin_protocol=self.options.nlin_protocol, reg_method=self.options.reg_method, resolution=resolutionForLSQ12) self.p.addPipeline(nlinModule.p) self.nlinFH = nlinModule.nlinAverages[-1] self.nlinParams = nlinModule.nlinParams self.initialTarget = nlinModule.initialTarget # Now we need the full transform to go back to LSQ6 space for i in self.inputs: linXfm = lsq12module.lsq12AvgXfms[i] nlinXfm = i.getLastXfm(self.nlinFH) outXfm = st.createOutputFileName(i, nlinXfm, "transforms", "_with_additional.xfm") xc = ma.xfmConcat([linXfm, nlinXfm], outXfm, fh.logFromFile(i.logDir, outXfm)) self.p.addStage(xc) i.addAndSetXfmToUse(self.nlinFH, outXfm)
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)