def setup_options(self): helpString=""" twolevel_model_building A pydpiper application designed to work with longitudinal data. LSQ12 and nonlinear registration is used to create a consensus average of every subject. A second level of LSQ12 and nonlinear registrations is then used to bring all the consensus averages from each subject into their own consensus average. Some assumptions: * at least two timepoints per subject * future work should be able to extend this to allow single timepoint subjects * all images must be similar enough to allow registration The last point is particularly important: the consensus average building process aligns every image from each subject to every other image from that subject. Early developmental data or tumour data, where the first image in the series might not be alignable to the last image in the series, is thus not suited for this approach. Data is passed to the application through a CSV file. This file has one line per subject, with each scan per subject listed on the same line and separated by a comma. """ # own options go here lsq6.addLSQ6ArgumentGroup(self.parser) lsq12.addLSQ12ArgumentGroup(self.parser) nl.addNlinRegArgumentGroup(self.parser) rf.addGenRegArgumentGroup(self.parser) st.addStatsArguments(self.parser) # set help - note that the format is messed up, something that can be fixed if we upgrade # from optparse to argparse. self.parser.description = helpString
def setup_options(self): """Add option groups from specific modules""" addMBMGroup(self.parser) rf.addGenRegArgumentGroup(self.parser) lsq6.addLSQ6ArgumentGroup(self.parser) lsq12.addLSQ12ArgumentGroup(self.parser) nlin.addNlinRegArgumentGroup(self.parser) st.addStatsArguments(self.parser)
def setup_options(self): """Add option groups from specific modules""" addMBMGroup(self.parser) rf.addGenRegOptionGroup(self.parser) lsq6.addLSQ6OptionGroup(self.parser) lsq12.addLSQ12OptionGroup(self.parser) nlin.addNlinRegOptionGroup(self.parser) st.addStatsOptions(self.parser) self.parser.set_usage("%prog [options] input files")
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 different registration modules. dirs = rf.setupDirectories(self.outputDir, options.pipeline_name, module="ALL") inputFiles = rf.initializeInputFiles(args, dirs.processedDir, maskDir=options.mask_dir) #Setup init model and inital target. Function also exists if no target was specified. initModel, targetPipeFH = rf.setInitialTarget(options.init_model, options.lsq6_target, dirs.lsq6Dir, self.outputDir) #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. if options.lsq12_likeFile == None: targetPipeFH = initModel[0] else: targetPipeFH = rfh.RegistrationFHBase(os.path.abspath(options.lsq12_likeFile), basedir=dirs.lsq12Dir) lsq12module = lsq12.FullLSQ12(inputFiles, dirs.lsq12Dir, likeFile=targetPipeFH, maxPairs=None, lsq12_protocol=options.lsq12_protocol, subject_matter=options.lsq12_subject_matter) 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[0]: lsq12module.lsq12AvgFH.setMask(initModel[0].getMask()) #NLIN MODULE - Register with minctracc or mincANTS based on options.reg_method 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) 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 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): #Setup output directories for registration chain (_processed only) dirs = rf.setupDirectories(self.outputDir, self.options.pipeline_name, module="ALL") #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() #Take average time point, subtract 1 for proper indexing avgTime = self.options.avg_time_point - 1 #Read in files from csv subjects = rf.setupSubjectHash(self.args[0], dirs, self.options.mask_dir) # If input = native space then do LSQ6 first on all files. if self.options.input_space == "native": initModel, targetPipeFH = rf.setInitialTarget( self.options.init_model, self.options.lsq6_target, dirs.lsq6Dir, self.outputDir) #LSQ6 MODULE, NUC and INORM inputFiles = [] for subj in subjects: for i in range(len(subjects[subj])): inputFiles.append(subjects[subj][i]) runLSQ6NucInorm = lsq6.LSQ6NUCInorm(inputFiles, targetPipeFH, initModel, dirs.lsq6Dir, self.options) self.pipeline.addPipeline(runLSQ6NucInorm.p) elif self.options.input_space == "lsq6": initModel = None else: print """Only native and lsq6 are allowed as input_space options for the registration chain. You specified: """ + str( self.options.input_space) print "Exiting..." sys.exit() #Get current group index for use later, when chain is run. #Value will be different for input_space == native vs LSQ6 currGroupIndex = rf.getCurrIndexForInputs(subjects) #If requested, run iterative groupwise registration for all subjects at the specified #common timepoint, otherwise look to see if files are specified from a previous run. if self.options.run_groupwise: inputs = [] for s in subjects: inputs.append(subjects[s][avgTime]) #Run full LSQ12 and NLIN modules. lsq12Nlin = mm.FullIterativeLSQ12Nlin( inputs, dirs, self.options, avgPrefix=self.options.common_name, initModel=initModel) self.pipeline.addPipeline(lsq12Nlin.p) nlinFH = lsq12Nlin.nlinFH #Set lastBasevol and group to lsq6 space, using currGroupIndex set above. for i in inputs: i.currentGroupIndex = currGroupIndex else: if self.options.mbm_dir and self.options.nlin_avg: if (not isdir(self.options.mbm_dir)) or (not isfile( self.options.nlin_avg)): logger.error( "The specified MBM-directory or nlin-average do not exist." ) logger.error("Specified MBM-directory: " + abspath(self.options.mbm_dir)) logger.error("Specified nlin average: " + abspath(self.options.nlin_avg)) sys.exit() # create file handler for nlin average nlinFH = rfh.RegistrationPipeFH(abspath(self.options.nlin_avg), basedir=dirs.processedDir) # Get transforms from subjects at avg time point to final nlin average and vice versa rf.getXfms(nlinFH, subjects, "lsq6", abspath(self.options.mbm_dir), time=avgTime) else: logger.info("MBM directory and nlin_average not specified.") logger.info("Calculating registration chain only") nlinFH = None for subj in subjects: s = subjects[subj] count = len(s) for i in range(count - 1): s[i].newGroup(groupName="chain") if self.options.reg_method == "mincANTS": register = mm.LSQ12ANTSNlin( s[i], s[i + 1], lsq12_protocol=self.options.lsq12_protocol, nlin_protocol=self.options.nlin_protocol) self.pipeline.addPipeline(register.p) elif self.options.reg_method == "minctracc": hm = mm.HierarchicalMinctracc( s[i], s[i + 1], lsq12_protocol=self.options.lsq12_protocol, nlin_protocol=self.options.nlin_protocol) self.pipeline.addPipeline(hm.p) """Resample s[i] into space of s[i+1]""" if nlinFH: resample = ma.mincresample(s[i], s[i + 1], likeFile=nlinFH, argArray=["-sinc"]) else: resample = ma.mincresample(s[i], s[i + 1], likeFile=s[i], argArray=["-sinc"]) self.pipeline.addStage(resample) """Invert transforms for use later in stats""" lastXfm = s[i].getLastXfm(s[i + 1]) inverseXfm = s[i + 1].getLastXfm(s[i]) if not inverseXfm: "invert xfm and calculate" xi = ma.xfmInvert(lastXfm, FH=s[i]) self.pipeline.addStage(xi) s[i + 1].addAndSetXfmToUse(s[i], xi.outputFiles[0]) """Now that all registration is complete, calculate stats, concat transforms and resample""" car = mm.LongitudinalStatsConcatAndResample(subjects, avgTime, nlinFH, self.options.stats_kernels, self.options.common_name) self.pipeline.addPipeline(car.p)
def run(self): options = self.options args = self.args # 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) # TODO: Write this as a function in LSQ6 and call from there. initModel = None if(options.lsq6_target != None): targetPipeFH = rfh.RegistrationPipeFH(os.path.abspath(options.lsq6_target), basedir=dirs.lsq6Dir) else: # options.init_model != None initModel = rf.setupInitModel(options.init_model, self.outputDir) if (initModel[1] != None): # we have a target in "native" space targetPipeFH = initModel[1] else: # we will use the target in "standard" space targetPipeFH = initModel[0] #LSQ6 MODULE lsq6module = lsq6.getLSQ6Module(inputFiles, targetPipeFH, lsq6Directory = dirs.lsq6Dir, initialTransform = options.lsq6_method, initModel = initModel, lsq6Protocol = options.lsq6_protocol, largeRotationParameters = options.large_rotation_parameters, largeRotationRange = options.large_rotation_range, largeRotationInterval = options.large_rotation_interval) # after the correct module has been set, get the transformation and # deal with resampling and potential model building lsq6module.createLSQ6Transformation() lsq6module.finalize() self.pipeline.addPipeline(lsq6module.p) # NUC nucorrection = lsq6.NonUniformityCorrection(inputFiles, initial_model = initModel, resampleNUCtoLSQ6 = False) nucorrection.finalize() self.pipeline.addPipeline(nucorrection.p) # INORMALIZE intensity_normalization = lsq6.IntensityNormalization(inputFiles, initial_model = initModel, resampleINORMtoLSQ6 = True) self.pipeline.addPipeline(intensity_normalization.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. if options.lsq12_likeFile == None: targetPipeFH = initModel[0] else: targetPipeFH = rfh.RegistrationFHBase(os.path.abspath(options.lsq12_likeFile), basedir=dirs.lsq12Dir) lsq12module = lsq12.FullLSQ12(inputFiles, dirs.lsq12Dir, likeFile=targetPipeFH, maxPairs=None, lsq12_protocol=options.lsq12_protocol, subject_matter=options.lsq12_subject_matter) 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. #NLIN MODULE - Register with minctracc or mincANTS based on options.reg_method nlinModule = nlin.initNLINModule(inputFiles, lsq12module.lsq12AvgFH, dirs.nlinDir, options.nlin_protocol, options.reg_method) nlinModule.iterate() self.pipeline.addPipeline(nlinModule.p) #STATS MODULE if options.calc_stats: """Get blurs from command line option and put into array""" blurs = [] for i in options.stats_kernels.split(","): blurs.append(float(i)) """Choose final average from array of nlin averages""" numGens = len(nlinModule.nlinAverages) finalNlin = nlinModule.nlinAverages[numGens-1] """For each input file, calculate statistics from finalNlin to input""" for inputFH in inputFiles: stats = st.CalcStats(inputFH, finalNlin, blurs, inputArray=inputFiles, scalingFactor=lsq12module.lsq12AvgXfms[inputFH]) stats.fullStatsCalc() self.pipeline.addPipeline(stats.p)