Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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
Exemplo n.º 3
0
 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)
Exemplo n.º 4
0
 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)
Exemplo n.º 5
0
 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") 
Exemplo n.º 6
0
 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") 
Exemplo n.º 7
0
    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)
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
 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)
Exemplo n.º 10
0
    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)
Exemplo n.º 11
0
    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)
Exemplo n.º 12
0
 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)