Пример #1
0
 def linAndNlinDisplacement(self):    
     """The function calculates both the linear and nonlinear
        portions of the displacement, in order to find 
        pure nonlinear. Input is the commonSpace, so the pure
        nonlinear displacement will point from input to target.
     
        This is opposite from the standard stats class, where
        the common space is the target
        
     """
     
     """Calculate linear part of non-linear xfm from input to target"""
     lpnl = linearPartofNlin(self.inputFH, self.targetFH)
     self.p.addStage(lpnl)
     self.linearXfm = lpnl.outputFiles[0]
     
     """Invert the transform, so we get the linear xfm from target to input."""
     xi = xfmInvert(self.linearXfm, FH=self.inputFH)
     self.p.addStage(xi)
     
     """Calculate full displacement from input to target"""
     self.calcFullDisplacement()
     
     """Calculate pure non-linear displacement from input to target
        1. Concatenate inverse linear and full input-target xfm to 
           get pure_nlin xfm
        2. Compute mincDisplacement on this transform. 
     """
     nlinBase = fh.removeBaseAndExtension(self.xfm) + "_pure_nlin.xfm"
     nlinXfm = fh.createBaseName(self.inputFH.tmpDir, nlinBase)
     xc = xfmConcat([xi.outputFiles[0], self.xfm], nlinXfm, fh.logFromFile(self.inputFH.logDir, nlinXfm))
     self.p.addStage(xc)
     nlinDisp = mincDisplacement(self.inputFH, self.inputFH, nlinXfm)
     self.p.addStage(nlinDisp)
     self.nlinDisp = nlinDisp.outputFiles[0]
Пример #2
0
 def setupXfms(self):
     self.xfm = self.inputFH.getLastXfm(self.targetFH)
     if not self.xfm:
         print "Cannot calculate statistics. No transform between input and target specified."
         sys.exit()
     """Check for existence of inverse transform. If it doesn't exist, create it. """
     self.invXfm = self.targetFH.getLastXfm(self.inputFH)
     if not self.invXfm:
         xi = xfmInvert(self.xfm, FH=self.inputFH)
         self.p.addStage(xi)
         self.invXfm = xi.outputFiles[0]
Пример #3
0
 def setupXfms(self):
     self.xfm = self.inputFH.getLastXfm(self.targetFH)
     if not self.xfm:
         print("Cannot calculate statistics. No transform between input and target specified.")
         print("Input: " + self.inputFH.getLastBasevol())
         print("Target: " + self.targetFH.getLastBasevol())
         sys.exit()
     else:
         self.invXfm = self.targetFH.getLastXfm(self.inputFH)
         if not self.invXfm:
             xi = xfmInvert(self.xfm, FH=self.inputFH)
             self.p.addStage(xi)
             self.invXfm = xi.outputFiles[0]
Пример #4
0
 def setupXfms(self):
     self.xfm = self.inputFH.getLastXfm(self.targetFH)
     if not self.xfm:
         print "Cannot calculate statistics. No transform between input and target specified."
         print "Input: " + self.inputFH.getLastBasevol()
         print "Target: " + self.targetFH.getLastBasevol()
         sys.exit()
     else:
         self.invXfm = self.targetFH.getLastXfm(self.inputFH)
         if not self.invXfm:
             xi = xfmInvert(self.xfm, FH=self.inputFH)
             self.p.addStage(xi)
             self.invXfm = xi.outputFiles[0]
Пример #5
0
 def calcFullDisplacement(self):
     """Calculate full displacement from target to input. If an
        additionaXfm is specified, it is concatenated to self.xfm here """
     if self.additionalXfm:
         outXfm = createOutputFileName(self.inputFH, self.xfm, "transforms", "_with_additional.xfm")
         xc = xfmConcat([self.additionalXfm, self.xfm], outXfm, fh.logFromFile(self.inputFH.logDir, outXfm))
         self.p.addStage(xc)
         xi = xfmInvert(xc.outputFiles[0], FH=self.inputFH)
         self.p.addStage(xi)
         fullDisp = mincDisplacement(self.targetFH, self.inputFH, transform=xi.outputFiles[0])
     else:
         fullDisp = mincDisplacement(self.targetFH, self.inputFH, transform=self.invXfm)
     self.p.addStage(fullDisp)
     self.fullDisp = fullDisp.outputFiles[0]
Пример #6
0
 def calcFullDisplacement(self):
     """Calculate full displacement from target to input. If an
        additionaXfm is specified, it is concatenated to self.xfm here """
     if self.additionalXfm:
         outXfm = createOutputFileName(self.inputFH, self.xfm, "transforms", "_with_additional.xfm")
         xc = xfmConcat([self.additionalXfm, self.xfm], outXfm, fh.logFromFile(self.inputFH.logDir, outXfm))
         self.p.addStage(xc)
         xi = xfmInvert(xc.outputFiles[0], FH=self.inputFH)
         self.p.addStage(xi)
         fullDisp = mincDisplacement(self.targetFH, self.inputFH, transform=xi.outputFiles[0])
     else:
         fullDisp = mincDisplacement(self.targetFH, self.inputFH, transform=self.invXfm)
     self.p.addStage(fullDisp)
     self.fullDisp = fullDisp.outputFiles[0]
def getXfms(nlinFH, subjects, space, mbmDir, time=None):

    """For each file in the build-model registration (associated with the specified
       time point), do the following:
       
       1. Find the to-native.xfm for that file. 
       2. Find the matching subject at the specified time point
       3. Set this xfm to be the last xfm from nlin average to subject from step #2. 
       4. Find the -from-native.xfm file.
       5. Set this xfm to be the last xfm from subject to nlin.
       
       Note: assume that the names in processedDir match beginning file 
             names for each subject
             We are also assuming subjects is either a dictionary or a list. 
    """
    
    """First handle subjects if dictionary or list"""
    if isinstance(subjects, list):
        inputs = subjects
    elif isinstance(subjects, dict):
        inputs = []
        for s in subjects:
            inputs.append(subjects[s][time])
    else:
        logger.error("getXfms only takes a dictionary or list of subjects. Incorrect type has been passed. Exiting...")
        sys.exit()
    
    pipeline = Pipeline()
    baseNames = walk(mbmDir).next()[1]
    for b in baseNames:
        if space == "lsq6":
            xfmToNative = abspath(mbmDir + "/" + b + "/transforms/" + b + "-final-to_lsq6.xfm")
        elif space == "lsq12":
            xfmToNative = abspath(mbmDir + "/" + b + "/transforms/" + b + "-final-nlin.xfm")
            xfmFromNative = abspath(mbmDir + "/" + b + "/transforms/" + b + "_inv_nonlinear.xfm")
        elif space == "native":
            xfmToNative = abspath(mbmDir + "/" + b + "/transforms/" + b + "-to-native.xfm")
            xfmFromNative = abspath(mbmDir + "/" + b + "/transforms/" + b + "-from-native.xfm")
        else:
            logger.error("getXfms can only retrieve transforms to and from native, lsq6 or lsq12 space. Invalid parameter has been passed.")
            sys.exit()
        for inputFH in inputs:
            if fnmatch.fnmatch(inputFH.getLastBasevol(), "*" + b + "*"):
                if space=="lsq6":
                    ix = ma.xfmInvert(xfmToNative, inputFH)
                    pipeline.addStage(ix)
                    xfmFromNative = ix.outputFiles[0]
                nlinFH.setLastXfm(inputFH, xfmToNative)
                inputFH.setLastXfm(nlinFH, xfmFromNative)
    return pipeline
Пример #8
0
 def calcNlinDisplacement(self):
     """Calculate pure non-linear displacement from input to target 
        1. Invert the linear transform, so we get the linear xfm from target to input.
        2. Concatenate the full non-linear (input to target) transform with the
           linear target to input transform.
        3. Calculate the displacement on this transform. """
     xi = xfmInvert(self.linearPartOfNlinXfm, FH=self.inputFH)
     self.p.addStage(xi)
     
     pureNlinXfm = createOutputFileName(self.inputFH, self.xfm, "transforms", "_pure_nlin.xfm")
     xc = xfmConcat([self.xfm, xi.outputFiles[0]], 
                    pureNlinXfm, fh.logFromFile(self.inputFH.logDir, pureNlinXfm))
     self.p.addStage(xc)
     nlinDisp = mincDisplacement(self.inputFH, self.inputFH, transform=pureNlinXfm)
     self.p.addStage(nlinDisp)
     self.nlinDisp = nlinDisp.outputFiles[0]
Пример #9
0
 def calcNlinDisplacement(self):
     """Calculate pure non-linear displacement from input to target 
        1. Invert the linear transform, so we get the linear xfm from target to input.
        2. Concatenate the full non-linear (input to target) transform with the
           linear target to input transform.
        3. Calculate the displacement on this transform. """
     xi = xfmInvert(self.linearPartOfNlinXfm, FH=self.inputFH)
     self.p.addStage(xi)
     
     pureNlinXfm = createOutputFileName(self.inputFH, self.xfm, "transforms", "_pure_nlin.xfm")
     xc = xfmConcat([self.xfm, xi.outputFiles[0]], 
                    pureNlinXfm, fh.logFromFile(self.inputFH.logDir, pureNlinXfm))
     self.p.addStage(xc)
     nlinDisp = mincDisplacement(self.inputFH, self.inputFH, transform=pureNlinXfm)
     self.p.addStage(nlinDisp)
     self.nlinDisp = nlinDisp.outputFiles[0]
Пример #10
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)
Пример #11
0
 def run(self):
     
     # Setup output directories for registration chain (_processed only).        
     dirs = rf.setupDirectories(self.outputDir, self.options.pipeline_name, module=None)
     
     """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()
     
     """Read in files from csv"""
     fileList = open(self.args[0], 'rb')
     subjectList = csv.reader(fileList, delimiter=',', skipinitialspace=True)
     subjects = {} # One array of images for each subject
     index = 0 
     for subj in subjectList:
         subjects[index] = rf.initializeInputFiles(subj, dirs.processedDir, self.options.mask_dir)
         index += 1
     
     """Put blurs into array"""
     blurs = []
     for i in self.options.stats_kernels.split(","):
         blurs.append(float(i))
     
     """Create file handler for nlin average from MBM"""
     if self.options.nlin_avg:
         nlinFH = rfh.RegistrationPipeFH(abspath(self.options.nlin_avg), basedir=dirs.processedDir)
     else:
         nlinFH = None
     if self.options.mbm_dir and not isdir(abspath(self.options.mbm_dir)):
         logger.error("The --mbm-directory specified does not exist: " + abspath(self.options.mbm_dir))
         sys.exit()
     
     """Take average time point, subtract 1 for proper indexing"""
     avgTime = self.options.avg_time_point - 1
     
     """Get transforms from inputs to final nlin average and vice versa"""
     if self.options.nlin_avg and self.options.mbm_dir:
         xfmsPipe = ombm.getXfms(nlinFH, subjects, self.options.input_space, abspath(self.options.mbm_dir), time=avgTime)
         if len(xfmsPipe.stages) > 0:
             self.pipeline.addPipeline(xfmsPipe)
         
         """ Possible TODO: Align everything to lsq6 space, with ordering depending on time point.
             This functionality was previously partially implemented (ChainAlignLSQ6), but was removed, as it was
             never fully working or tested. Leaving this comment as a place holder in case we want to re-implement. 
         """
     else:
         logger.info("MBM directory and nlin_average not specified.")
         logger.info("Calculating registration chain only")
     
     for subj in subjects:
         s = subjects[subj]
         count = len(s) 
         for i in range(count - 1):
             # Create new groups
             # MF TODO: Make generalization of registration parameters easier. 
             if self.options.reg_method == "mincANTS":
                 register = mm.LSQ12ANTSNlin(s[i], s[i+1])
                 self.pipeline.addPipeline(register.p)
             elif self.options.reg_method == "minctracc":
                 hm = hmt.HierarchicalMinctracc(s[i], s[i+1])
                 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, 
                                                 blurs, 
                                                 self.options.common_name) 
     self.pipeline.addPipeline(car.p)
Пример #12
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)