Esempio n. 1
0
 def setupTarget(self):
     if self.targetAvg:
         if isinstance(self.targetAvg, str): 
             self.initialTarget = RegistrationPipeFH(self.targetAvg, 
                                                     mask=self.targetMask, 
                                                     basedir=self.targetOutputDir)
             self.outputAvg = self.targetAvg
         elif isinstance(self.targetAvg, RegistrationPipeFH):
             self.initialTarget = self.targetAvg
             self.outputAvg = self.targetAvg.getLastBasevol()
             if not self.initialTarget.getMask():
                 if self.targetMask:
                     self.initialTarget.setMask(self.targetMask)
         else:
             print "You have passed a target average that is neither a string nor a file handler: " + str(self.targetAvg)
             print "Exiting..."
     else:
         self.targetAvg = abspath(self.targetOutputDir) + "/" + "initial-target.mnc" 
         self.initialTarget = RegistrationPipeFH(self.targetAvg, 
                                                 mask=self.targetMask, 
                                                 basedir=self.targetOutputDir)
         self.outputAvg = self.targetAvg
     if self.createAvg:
         avg = mincAverage(self.inputFiles, 
                           self.initialTarget, 
                           output=self.outputAvg,
                           defaultDir=self.targetOutputDir)
         self.p.addStage(avg)
Esempio n. 2
0
 def setupTarget(self):
     if self.targetAvg:
         if isinstance(self.targetAvg, str):
             self.initialTarget = RegistrationPipeFH(
                 self.targetAvg,
                 mask=self.targetMask,
                 basedir=self.targetOutputDir)
             self.outputAvg = self.targetAvg
         elif isinstance(self.targetAvg, RegistrationPipeFH):
             self.initialTarget = self.targetAvg
             self.outputAvg = self.targetAvg.getLastBasevol()
             if not self.initialTarget.getMask():
                 if self.targetMask:
                     self.initialTarget.setMask(self.targetMask)
         else:
             print "You have passed a target average that is neither a string nor a file handler: " + str(
                 self.targetAvg)
             print "Exiting..."
     else:
         self.targetAvg = abspath(
             self.targetOutputDir) + "/" + "initial-target.mnc"
         self.initialTarget = RegistrationPipeFH(
             self.targetAvg,
             mask=self.targetMask,
             basedir=self.targetOutputDir)
         self.outputAvg = self.targetAvg
     if self.createAvg:
         avg = mincAverage(self.inputFiles,
                           self.initialTarget,
                           output=self.outputAvg,
                           defaultDir=self.targetOutputDir)
         self.p.addStage(avg)
Esempio n. 3
0
 def iterate(self):
     for i in range(self.generations):
         outputName = "nlin-%g.mnc" % (i + 1)
         if self.avgPrefix:
             outputName = str(self.avgPrefix) + "-" + outputName
         nlinOutput = abspath(self.nlinDir) + "/" + outputName
         nlinFH = RegistrationPipeFH(nlinOutput,
                                     mask=self.target.getMask(),
                                     basedir=self.nlinDir)
         self.addBlurStage(self.target, i)
         filesToAvg = []
         for inputFH in self.inputs:
             self.addBlurStage(inputFH, i)
             self.regAndResample(inputFH, i, filesToAvg, nlinFH)
         """Because we don't reset lastBasevol on each inputFH, call mincAverage with files only.
            We create fileHandler first though, so we have log directory.
            This solution seems a bit hackish--may want to modify?  
            Additionally, we are currently using the full RegistrationPipeFH class, but ultimately
            we'll want to create a third class that is somewhere between a full and base class. 
         """
         logBase = removeBaseAndExtension(nlinOutput)
         avgLog = createLogFile(nlinFH.logDir, logBase)
         avg = mincAverage(filesToAvg, nlinOutput, logFile=avgLog)
         self.p.addStage(avg)
         """Reset target for next iteration and add to array"""
         self.target = nlinFH
         self.nlinAverages.append(nlinFH)
         """Create a final nlin group to add to the inputFH.
            lastBasevol = by default, will grab the lastBasevol used in these calculations (e.g. lsq12)
            setLastXfm between final nlin average and inputFH will be set for stats calculations.
         """
         if i == (self.generations - 1):
             for inputFH in self.inputs:
                 """NOTE: The last xfm being set below is NOT the result of a registration between
                    inputFH and nlinFH, but rather is the output transform from the previous generation's
                    average."""
                 finalXfm = inputFH.getLastXfm(
                     self.nlinAverages[self.generations - 2])
                 inputFH.newGroup(groupName="final")
                 inputFH.setLastXfm(nlinFH, finalXfm)
Esempio n. 4
0
 def iterate(self):
     if not self.maxPairs:
         xfmsToAvg = {}
         lsq12ResampledFiles = {}
         for inputFH in self.inputs:
             """Create an array of xfms, to compute an average lsq12 xfm for each input"""
             xfmsToAvg[inputFH] = []
             for targetFH in self.inputs:
                 if inputFH != targetFH:
                     lsq12 = LSQ12(inputFH,
                                   targetFH,
                                   blurs=self.blurs,
                                   step=self.stepSize,
                                   gradient=self.useGradient,
                                   simplex=self.simplex,
                                   w_translations=self.w_translations)
                     self.p.addPipeline(lsq12.p)
                     xfmsToAvg[inputFH].append(inputFH.getLastXfm(targetFH))
             """Create average xfm for inputFH using xfmsToAvg array"""
             cmd = ["xfmavg"]
             for i in range(len(xfmsToAvg[inputFH])):
                 cmd.append(InputFile(xfmsToAvg[inputFH][i]))
             avgXfmOutput = createBaseName(
                 inputFH.transformsDir, inputFH.basename + "-avg-lsq12.xfm")
             cmd.append(OutputFile(avgXfmOutput))
             xfmavg = CmdStage(cmd)
             xfmavg.setLogFile(
                 LogFile(logFromFile(inputFH.logDir, avgXfmOutput)))
             self.p.addStage(xfmavg)
             self.lsq12AvgXfms[inputFH] = avgXfmOutput
             """ resample brain and add to array for mincAveraging"""
             if not self.likeFile:
                 likeFile = inputFH
             else:
                 likeFile = self.likeFile
             rslOutput = createBaseName(
                 inputFH.resampledDir,
                 inputFH.basename + "-resampled-lsq12.mnc")
             res = ma.mincresample(inputFH,
                                   inputFH,
                                   transform=avgXfmOutput,
                                   likeFile=likeFile,
                                   output=rslOutput,
                                   argArray=["-sinc"])
             self.p.addStage(res)
             lsq12ResampledFiles[inputFH] = rslOutput
         """ After all registrations complete, setLastBasevol for each subject to be
             resampled file in lsq12 space. We can then call mincAverage on fileHandlers,
             as it will use the lastBasevol for each by default."""
         for inputFH in self.inputs:
             inputFH.setLastBasevol(lsq12ResampledFiles[inputFH])
         """ mincAverage all resampled brains and put in lsq12Directory"""
         self.lsq12Avg = abspath(self.lsq12Dir) + "/" + basename(
             self.lsq12Dir) + "-pairs.mnc"
         self.lsq12AvgFH = RegistrationPipeFH(self.lsq12Avg,
                                              basedir=self.lsq12Dir)
         avg = ma.mincAverage(self.inputs,
                              self.lsq12AvgFH,
                              output=self.lsq12Avg,
                              defaultDir=self.lsq12Dir)
         self.p.addStage(avg)
     else:
         print "Registration using a specified number of max pairs not yet working. Check back soon!"
         sys.exit()
Esempio n. 5
0
    def run(self):

        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print "Incorrect registration method specified: ", self.options.reg_method
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at 
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print "The lsq12 protocol does not exists: ", self.options.lsq12_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print "The nlin protocol does not exists: ", self.options.nlin_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
            

        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = [] #array of input atlas averages
        labels = [] #array of input atlas labels, one for each average
        masks = [] # array of masks, one for each average
        atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
        numAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if not len(average) == len(labels):
            logger.error("Number of input atlas labels does not match averages.")
            logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
            sys.exit() 
        elif not len(average) == len(masks):
            logger.error("Number of input atlas masks does not match averages.")
            logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
            sys.exit()
        else:
        # match labels with averages
            numAtlases = len(labels)
            for iLabel in labels: 
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                                 mask=abspath(iMask),
                                                                 basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
                atlases.append(atlasPipeFH)
        
        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
        
        templates = []
        numTemplates = len(self.args)
        
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases, 
                           inputs, 
                           numAtlases, 
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)
        
        if not self.options.mask_only:
            if numTemplates > self.options.max_templates:
                numTemplates = self.options.max_templates
            # Register each atlas to each input image up to numTemplates
            for nfile in range(numTemplates):
                for afile in range(numAtlases):
                    sp = MAGeTRegister(inputs[nfile], 
                                       atlases[afile],
                                       self.options.reg_method,
                                       name="initial",
                                       createMask=False,
                                       lsq12_protocol=self.options.lsq12_protocol,
                                       nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple 
                # input labels
                templates.append(inputs[nfile])
            
            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on 
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    for tmplFH in templates:
                        if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                            sp = MAGeTRegister(inputFH, 
                                               tmplFH, 
                                               self.options.reg_method,
                                               name="templates", 
                                               createMask=False,
                                               lsq12_protocol=self.options.lsq12_protocol,
                                               nlin_protocol=self.options.nlin_protocol)
                            self.pipeline.addPipeline(sp)
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise, False)
                        self.pipeline.addStage(voxel)   
        
            logger.info("Number of input atlas/label pairs: " + str(numAtlases))   
            logger.info("Number of templates: " + str(numTemplates))     
Esempio n. 6
0
 def run(self):
     
     if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
         logger.error("Incorrect registration method specified: " + self.options.reg_method)
         sys.exit()
     
     atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
     
     """Read in atlases from directory specified in --atlas-library and 
         create fileHandling classes. Assumes atlas/label/mask groups have one 
         of the following naming schemes:
             name_average.mnc/name_labels.mnc/name_mask.mnc
             name.mnc/name_labels.mnc/name_mask.mnc
         Note that all three files are required even if masking is not used."""
     average = [] #array of input atlas averages
     labels = [] #array of input atlas labels, one for each average
     masks = [] # array of masks, one for each average
     atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
     numAtlases = 0
     for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
         if fnmatch.fnmatch(inFile, "*labels.mnc"):
             labels.append(abspath(inFile))
         elif fnmatch.fnmatch(inFile, "*mask.mnc"):
             masks.append(abspath(inFile))
         else:
             average.append(abspath(inFile))
     # check to make sure len(average)==len(labels)
     if not len(average) == len(labels):
         logger.error("Number of input atlas labels does not match averages.")
         logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
         sys.exit() 
     elif not len(average) == len(masks):
         logger.error("Number of input atlas masks does not match averages.")
         logger.error("Check " + str(self.options.atlas_lib) + " and try again.")
         sys.exit()
     else:
     # match labels with averages
         numAtlases = len(labels)
         for iLabel in labels: 
             atlasStart = iLabel.split("_labels.mnc")
             for iAvg in average:
                 avgStart = iAvg.split("_average.mnc")
                 if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                     for iMask in masks:
                         maskStart = iMask.split("_mask.mnc")
                         if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                             atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                              mask=abspath(iMask),
                                                              basedir=atlasDir)
                             break
                     break
             atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
             atlases.append(atlasPipeFH)
     
     #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
     # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
     
     """ Create fileHandling classes for images. If a directory of masks is specified, 
         they will be assigned to the appropriate input file handlers."""
     inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
     
     templates = []
     numTemplates = len(self.args)
     
     """ If --mask is specified and we are masking brains, do it here."""
     if self.options.mask or self.options.mask_only:
         mp = MAGeTMask(atlases, 
                        inputs, 
                        numAtlases, 
                        self.options.mask_method,
                        lsq12_protocol=self.options.lsq12_protocol,
                        nlin_protocol=self.options.nlin_protocol)
         self.pipeline.addPipeline(mp)
     
     if not self.options.mask_only:
         if numTemplates > self.options.max_templates:
             numTemplates = self.options.max_templates
         # Register each atlas to each input image up to numTemplates
         for nfile in range(numTemplates):
             for afile in range(numAtlases):
                 sp = MAGeTRegister(inputs[nfile], 
                                    atlases[afile],
                                    self.options.reg_method,
                                    name="initial",
                                    createMask=False,
                                    lsq12_protocol=self.options.lsq12_protocol,
                                    nlin_protocol=self.options.nlin_protocol)
                 self.pipeline.addPipeline(sp)
             # each template needs to be added only once, but will have multiple 
             # input labels
             templates.append(inputs[nfile])
         
         # once the initial templates have been created, go and register each
         # inputFile to the templates. If --pairwise=False, do voxel voting on 
         # input-atlas registrations only
         if self.options.pairwise:
             for inputFH in inputs:
                 for tmplFH in templates:
                     if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                         sp = MAGeTRegister(inputFH, 
                                            tmplFH, 
                                            self.options.reg_method,
                                            name="templates", 
                                            createMask=False,
                                            lsq12_protocol=self.options.lsq12_protocol,
                                            nlin_protocol=self.options.nlin_protocol)
                         self.pipeline.addPipeline(sp)
                 voxel = voxelVote(inputFH, self.options.pairwise, False)
                 self.pipeline.addStage(voxel)
         else:
             # only do voxel voting in this case if there was more than one input atlas
             if numAtlases > 1:
                 for inputFH in inputs:
                     voxel = voxelVote(inputFH, self.options.pairwise, False)
                     self.pipeline.addStage(voxel)   
     
         logger.info("Number of input atlas/label pairs: " + str(numAtlases))   
         logger.info("Number of templates: " + str(numTemplates))     
Esempio n. 7
0
class initializeAndRunNLIN(object):
    """Class to setup target average (if needed), 
       instantiate correct version of NLIN class,
       and run NLIN registration."""
    def __init__(self, 
                  targetOutputDir, #Output directory for files related to initial target (often _lsq12)
                  inputFiles, 
                  nlinDir, 
                  avgPrefix, #Prefix for nlin-1.mnc, ... nlin-k.mnc 
                  createAvg=True, #True=call mincAvg, False=targetAvg already exists
                  targetAvg=None, #Optional path to initial target - passing name does not guarantee existence
                  targetMask=None, #Optional path to mask for initial target
                  nlin_protocol=None,
                  reg_method=None):
        self.p = Pipeline()
        self.targetOutputDir = targetOutputDir
        self.inputFiles = inputFiles
        self.nlinDir = nlinDir
        self.avgPrefix = avgPrefix
        self.createAvg = createAvg
        self.targetAvg = targetAvg
        self.targetMask = targetMask
        self.nlin_protocol = nlin_protocol
        self.reg_method = reg_method
        
        # setup initialTarget (if needed) and initialize non-linear module
        self.setupTarget()
        self.initNlinModule()
        
        #iterate through non-linear registration and setup averages
        self.nlinModule.iterate()
        self.p.addPipeline(self.nlinModule.p)
        self.nlinAverages = self.nlinModule.nlinAverages
        self.nlinParams = self.nlinModule.nlinParams
        
    def setupTarget(self):
        if self.targetAvg:
            if isinstance(self.targetAvg, str): 
                self.initialTarget = RegistrationPipeFH(self.targetAvg, 
                                                        mask=self.targetMask, 
                                                        basedir=self.targetOutputDir)
                self.outputAvg = self.targetAvg
            elif isinstance(self.targetAvg, RegistrationPipeFH):
                self.initialTarget = self.targetAvg
                self.outputAvg = self.targetAvg.getLastBasevol()
                if not self.initialTarget.getMask():
                    if self.targetMask:
                        self.initialTarget.setMask(self.targetMask)
            else:
                print "You have passed a target average that is neither a string nor a file handler: " + str(self.targetAvg)
                print "Exiting..."
        else:
            self.targetAvg = abspath(self.targetOutputDir) + "/" + "initial-target.mnc" 
            self.initialTarget = RegistrationPipeFH(self.targetAvg, 
                                                    mask=self.targetMask, 
                                                    basedir=self.targetOutputDir)
            self.outputAvg = self.targetAvg
        if self.createAvg:
            avg = mincAverage(self.inputFiles, 
                              self.initialTarget, 
                              output=self.outputAvg,
                              defaultDir=self.targetOutputDir)
            self.p.addStage(avg)
            
    def initNlinModule(self):
        if self.reg_method=="mincANTS":
            self.nlinModule = NLINANTS(self.inputFiles, self.initialTarget, self.nlinDir, self.avgPrefix, self.nlin_protocol)
        elif self.reg_method=="minctracc":
            self.nlinModule = NLINminctracc(self.inputFiles, self.initialTarget, self.nlinDir, self.avgPrefix, self.nlin_protocol)
        else:
            logger.error("Incorrect registration method specified: " + self.reg_method)
            sys.exit()
Esempio n. 8
0
    def run(self):
        checkInputFiles(self.args)
            
        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print("Incorrect registration method specified: ", self.options.reg_method)
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at 
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print("The lsq12 protocol does not exists: ", self.options.lsq12_protocol)
            print("You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/")
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print("The nlin protocol does not exists: ", self.options.nlin_protocol)
            print("You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/")
            sys.exit()
            
        # There are two variables that can be used to determine where the output
        # of the pipeline is stored: pipeline_name and outputDir
        # If the outputDir is not specified, the current working directory is used.
        if self.options.pipeline_name:
            self.outputDir += "/" + self.options.pipeline_name
            fh.makedirsIgnoreExisting(self.outputDir)
            
        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = [] #array of input atlas averages
        labels = [] #array of input atlas labels, one for each average
        masks = [] # array of masks, one for each average
        atlases = [] #array of RegistrationPipeFH classes for each atlas/label pair
        numLibraryAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if (not len(average) == len(labels)) or (not len(average) == len(masks)):
            print("\nError: not all atlases/labels/masks match.")
            print("The allowed naming conventions are:\n{atlas}.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc")
            print("\nand:\n{atlas}_average.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc\n")
            print("Check the atlas library directory: " + str(self.options.atlas_lib) + " and try again.")
            print("Exiting...")
            sys.exit() 
        else:
        # match labels with averages
            numLibraryAtlases = len(labels)
            for iLabel in labels: 
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(abspath(iAvg), 
                                                                 mask=abspath(iMask),
                                                                 basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True) 
                atlases.append(atlasPipeFH)

        # exit if no atlases were found in the specified directory
        if numLibraryAtlases == 0:
            print("\nError: no atlases were found in the specified directory: %s" % self.options.atlas_lib)
            print("Exiting...")
            sys.exit()

        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args, self.outputDir, maskDir=self.options.mask_dir)
        
        templates = []
        numTemplates = len(self.args)
        
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases, 
                           inputs, 
                           numLibraryAtlases, 
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)
        
        if not self.options.mask_only:
            numLibraryAtlasesUsed = numLibraryAtlases
            if numLibraryAtlases > self.options.max_templates:
                numLibraryAtlasesUsed = self.options.max_templates
            # The first thing we need to do is to align the atlases from the
            # template library to all input files (unless there are more 
            # atlases in the given library than the specified maximum (max_templates)
            for inputFH in inputs:
                for afile in range(numLibraryAtlasesUsed):
                    sp = MAGeTRegister(inputFH, 
                                       atlases[afile],
                                       self.options.reg_method,
                                       name="initial",
                                       createMask=False,
                                       lsq12_protocol=self.options.lsq12_protocol,
                                       nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple 
                # input labels
                templates.append(inputFH)
            
            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on 
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    # in the previous loop, we aligned the atlases in the template 
                    # library to all input files. These are all stored in the 
                    # templates variable. We only need to register upto max_templates
                    # files to each input files:
                    num_currently_aligned_atlases = numLibraryAtlasesUsed
                    for tmplFH in templates:
                        # only align more atlases if not enough have been
                        # collected so far
                        if num_currently_aligned_atlases < self.options.max_templates:
                            if tmplFH.getLastBasevol() != inputFH.getLastBasevol():
                                sp = MAGeTRegister(inputFH, 
                                                   tmplFH, 
                                                   self.options.reg_method,
                                                   name="templates", 
                                                   createMask=False,
                                                   lsq12_protocol=self.options.lsq12_protocol,
                                                   nlin_protocol=self.options.nlin_protocol)
                                self.pipeline.addPipeline(sp)
                                num_currently_aligned_atlases += 1
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numLibraryAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise, False)
                        self.pipeline.addStage(voxel)   
        
            logger.info("Number of input atlas/label pairs: " + str(numLibraryAtlases))   
            logger.info("Number of templates created (all input files...): " + str(numTemplates))
            logger.info("Number of templates used for each inputfile: " + str(numLibraryAtlasesUsed))
Esempio n. 9
0
class initializeAndRunNLIN(object):
    """Class to setup target average (if needed), 
       instantiate correct version of NLIN class,
       and run NLIN registration."""
    def __init__(
            self,
            targetOutputDir,  #Output directory for files related to initial target (often _lsq12)
            inputFiles,
            nlinDir,
            avgPrefix,  #Prefix for nlin-1.mnc, ... nlin-k.mnc 
            createAvg=True,  #True=call mincAvg, False=targetAvg already exists
            targetAvg=None,  #Optional path to initial target - passing name does not guarantee existence
            targetMask=None,  #Optional path to mask for initial target
            nlin_protocol=None,
            reg_method=None):
        self.p = Pipeline()
        self.targetOutputDir = targetOutputDir
        self.inputFiles = inputFiles
        self.nlinDir = nlinDir
        self.avgPrefix = avgPrefix
        self.createAvg = createAvg
        self.targetAvg = targetAvg
        self.targetMask = targetMask
        self.nlin_protocol = nlin_protocol
        self.reg_method = reg_method

        # setup initialTarget (if needed) and initialize non-linear module
        self.setupTarget()
        self.initNlinModule()

        #iterate through non-linear registration and setup averages
        self.nlinModule.iterate()
        self.p.addPipeline(self.nlinModule.p)
        self.nlinAverages = self.nlinModule.nlinAverages
        self.nlinParams = self.nlinModule.nlinParams

    def setupTarget(self):
        if self.targetAvg:
            if isinstance(self.targetAvg, str):
                self.initialTarget = RegistrationPipeFH(
                    self.targetAvg,
                    mask=self.targetMask,
                    basedir=self.targetOutputDir)
                self.outputAvg = self.targetAvg
            elif isinstance(self.targetAvg, RegistrationPipeFH):
                self.initialTarget = self.targetAvg
                self.outputAvg = self.targetAvg.getLastBasevol()
                if not self.initialTarget.getMask():
                    if self.targetMask:
                        self.initialTarget.setMask(self.targetMask)
            else:
                print "You have passed a target average that is neither a string nor a file handler: " + str(
                    self.targetAvg)
                print "Exiting..."
        else:
            self.targetAvg = abspath(
                self.targetOutputDir) + "/" + "initial-target.mnc"
            self.initialTarget = RegistrationPipeFH(
                self.targetAvg,
                mask=self.targetMask,
                basedir=self.targetOutputDir)
            self.outputAvg = self.targetAvg
        if self.createAvg:
            avg = mincAverage(self.inputFiles,
                              self.initialTarget,
                              output=self.outputAvg,
                              defaultDir=self.targetOutputDir)
            self.p.addStage(avg)

    def initNlinModule(self):
        if self.reg_method == "mincANTS":
            self.nlinModule = NLINANTS(self.inputFiles, self.initialTarget,
                                       self.nlinDir, self.avgPrefix,
                                       self.nlin_protocol)
        elif self.reg_method == "minctracc":
            self.nlinModule = NLINminctracc(self.inputFiles,
                                            self.initialTarget, self.nlinDir,
                                            self.avgPrefix, self.nlin_protocol)
        else:
            logger.error("Incorrect registration method specified: " +
                         self.reg_method)
            sys.exit()
Esempio n. 10
0
    def run(self):

        if self.options.reg_method != "minctracc" and self.options.reg_method != "mincANTS":
            print "Incorrect registration method specified: ", self.options.reg_method
            sys.exit()

        # given that the lsq12 and nlin protocols are hard coded at the moment, exit if we are not at
        # MICe, and provide some information as to where to find them
        if not exists(self.options.lsq12_protocol):
            print "The lsq12 protocol does not exists: ", self.options.lsq12_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()
        if not exists(self.options.nlin_protocol):
            print "The nlin protocol does not exists: ", self.options.nlin_protocol
            print "You can find the default MAGeT protocols in your pydpiper source directory, in: applications_testing/test_data/"
            sys.exit()

        # There are two variables that can be used to determine where the output
        # of the pipeline is stored: pipeline_name and outputDir
        # If the outputDir is not specified, the current working directory is used.
        if self.options.pipeline_name:
            self.outputDir += "/" + self.options.pipeline_name
            fh.makedirsIgnoreExisting(self.outputDir)

        atlasDir = fh.createSubDir(self.outputDir, "input_atlases")
        """Read in atlases from directory specified in --atlas-library and 
            create fileHandling classes. Assumes atlas/label/mask groups have one 
            of the following naming schemes:
                name_average.mnc/name_labels.mnc/name_mask.mnc
                name.mnc/name_labels.mnc/name_mask.mnc
            Note that all three files are required even if masking is not used."""
        average = []  #array of input atlas averages
        labels = []  #array of input atlas labels, one for each average
        masks = []  # array of masks, one for each average
        atlases = [
        ]  #array of RegistrationPipeFH classes for each atlas/label pair
        numLibraryAtlases = 0
        for inFile in glob.glob(join(self.options.atlas_lib, "*.mnc")):
            if fnmatch.fnmatch(inFile, "*labels.mnc"):
                labels.append(abspath(inFile))
            elif fnmatch.fnmatch(inFile, "*mask.mnc"):
                masks.append(abspath(inFile))
            else:
                average.append(abspath(inFile))
        # check to make sure len(average)==len(labels)
        if (not len(average) == len(labels)) or (not len(average)
                                                 == len(masks)):
            print "\nError: not all atlases/labels/masks match."
            print "The allowed naming conventions are:\n{atlas}.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc"
            print "\nand:\n{atlas}_average.mnc\n{atlas}_labels.mnc\n{atlas}_mask.mnc\n"
            print "Check the atlas library directory: " + str(
                self.options.atlas_lib) + " and try again."
            print "Exiting..."
            sys.exit()
        else:
            # match labels with averages
            numLibraryAtlases = len(labels)
            for iLabel in labels:
                atlasStart = iLabel.split("_labels.mnc")
                for iAvg in average:
                    avgStart = iAvg.split("_average.mnc")
                    if fnmatch.fnmatch(atlasStart[0], avgStart[0]):
                        for iMask in masks:
                            maskStart = iMask.split("_mask.mnc")
                            if fnmatch.fnmatch(atlasStart[0], maskStart[0]):
                                atlasPipeFH = RegistrationPipeFH(
                                    abspath(iAvg),
                                    mask=abspath(iMask),
                                    basedir=atlasDir)
                                break
                        break
                atlasPipeFH.addLabels(abspath(iLabel), inputLabel=True)
                atlases.append(atlasPipeFH)

        # exit if no atlases were found in the specified directory
        if numLibraryAtlases == 0:
            print "\nError: no atlases were found in the specified directory: %s" % self.options.atlas_lib
            print "Exiting..."
            sys.exit()

        #MF TODO: add some checking to make sure that atlas/labels/naming all worked correctly
        # eg if we have A4_mask.mnc "matching" with A3_labels, we wont get right thing.
        """ Create fileHandling classes for images. If a directory of masks is specified, 
            they will be assigned to the appropriate input file handlers."""
        inputs = initializeInputFiles(self.args,
                                      self.outputDir,
                                      maskDir=self.options.mask_dir)

        templates = []
        numTemplates = len(self.args)
        """ If --mask is specified and we are masking brains, do it here."""
        if self.options.mask or self.options.mask_only:
            mp = MAGeTMask(atlases,
                           inputs,
                           numLibraryAtlases,
                           self.options.mask_method,
                           lsq12_protocol=self.options.lsq12_protocol,
                           nlin_protocol=self.options.nlin_protocol)
            self.pipeline.addPipeline(mp)

        if not self.options.mask_only:
            numLibraryAtlasesUsed = numLibraryAtlases
            if numLibraryAtlases > self.options.max_templates:
                numLibraryAtlasesUsed = self.options.max_templates
            # The first thing we need to do is to align the atlases from the
            # template library to all input files (unless there are more
            # atlases in the given library than the specified maximum (max_templates)
            for inputFH in inputs:
                for afile in range(numLibraryAtlasesUsed):
                    sp = MAGeTRegister(
                        inputFH,
                        atlases[afile],
                        self.options.reg_method,
                        name="initial",
                        createMask=False,
                        lsq12_protocol=self.options.lsq12_protocol,
                        nlin_protocol=self.options.nlin_protocol)
                    self.pipeline.addPipeline(sp)
                # each template needs to be added only once, but will have multiple
                # input labels
                templates.append(inputFH)

            # once the initial templates have been created, go and register each
            # inputFile to the templates. If --pairwise=False, do voxel voting on
            # input-atlas registrations only
            if self.options.pairwise:
                for inputFH in inputs:
                    # in the previous loop, we aligned the atlases in the template
                    # library to all input files. These are all stored in the
                    # templates variable. We only need to register upto max_templates
                    # files to each input files:
                    num_currently_aligned_atlases = numLibraryAtlasesUsed
                    for tmplFH in templates:
                        # only align more atlases if not enough have been
                        # collected so far
                        if num_currently_aligned_atlases < self.options.max_templates:
                            if tmplFH.getLastBasevol(
                            ) != inputFH.getLastBasevol():
                                sp = MAGeTRegister(
                                    inputFH,
                                    tmplFH,
                                    self.options.reg_method,
                                    name="templates",
                                    createMask=False,
                                    lsq12_protocol=self.options.lsq12_protocol,
                                    nlin_protocol=self.options.nlin_protocol)
                                self.pipeline.addPipeline(sp)
                                num_currently_aligned_atlases += 1
                    voxel = voxelVote(inputFH, self.options.pairwise, False)
                    self.pipeline.addStage(voxel)
            else:
                # only do voxel voting in this case if there was more than one input atlas
                if numLibraryAtlases > 1:
                    for inputFH in inputs:
                        voxel = voxelVote(inputFH, self.options.pairwise,
                                          False)
                        self.pipeline.addStage(voxel)

            logger.info("Number of input atlas/label pairs: " +
                        str(numLibraryAtlases))
            logger.info("Number of templates created (all input files...): " +
                        str(numTemplates))
            logger.info("Number of templates used for each inputfile: " +
                        str(numLibraryAtlasesUsed))
Esempio n. 11
0
 def iterate(self):
     xfmsToAvg = {}
     lsq12ResampledFiles = {}
     for inputFH in self.inputs:
         """Create an array of xfms, to compute an average lsq12 xfm for each input"""
         xfmsToAvg[inputFH] = []
         if self.maxPairs is not None:
             if self.maxPairs >= len(self.inputs) - 1:
                 # -1 prevents unnecessary sampling in the case self.maxPairs = len(self.inputs) - 1
                 inputs = self.inputs
             else:
                 random.seed(
                     tuple(map(lambda fh: fh.inputFileName, self.inputs)))
                 # if inputFH is included in the sample, we will register against one fewer target
                 inputs = random.sample(
                     filter(lambda fh: fh != inputFH, self.inputs),
                     self.maxPairs)
         else:
             inputs = self.inputs
         for targetFH in inputs:
             if inputFH != targetFH:
                 lsq12 = LSQ12(inputFH,
                               targetFH,
                               blurs=self.blurs,
                               step=self.stepSize,
                               gradient=self.useGradient,
                               simplex=self.simplex,
                               w_translations=self.w_translations)
                 self.p.addPipeline(lsq12.p)
                 xfmsToAvg[inputFH].append(inputFH.getLastXfm(targetFH))
         """Create average xfm for inputFH using xfmsToAvg array"""
         avgXfmOutput = createBaseName(inputFH.transformsDir,
                                       inputFH.basename + "-avg-lsq12.xfm")
         cmd = ["xfmavg", "-verbose", "-clobber"] \
               + map(InputFile, xfmsToAvg[inputFH]) + [OutputFile(avgXfmOutput)]
         #for i in range(len(xfmsToAvg[inputFH])):
         #    cmd.append(InputFile(xfmsToAvg[inputFH][i]))
         # '-clobber' works around #157, but is probably better in general
         #cmd.append(OutputFile(avgXfmOutput))
         xfmavg = CmdStage(cmd)
         xfmavg.setLogFile(
             LogFile(logFromFile(inputFH.logDir, avgXfmOutput)))
         self.p.addStage(xfmavg)
         self.lsq12AvgXfms[inputFH] = avgXfmOutput
         """ resample brain and add to array for mincAveraging"""
         if not self.likeFile:
             likeFile = inputFH
         else:
             likeFile = self.likeFile
         rslOutput = createBaseName(
             inputFH.resampledDir,
             inputFH.basename + "-resampled-lsq12.mnc")
         res = ma.mincresample(inputFH,
                               inputFH,
                               transform=avgXfmOutput,
                               likeFile=likeFile,
                               output=rslOutput,
                               argArray=["-sinc"])
         self.p.addStage(res)
         lsq12ResampledFiles[inputFH] = rslOutput
     """ After all registrations complete, setLastBasevol for each subject to be
         resampled file in lsq12 space. We can then call mincAverage on fileHandlers,
         as it will use the lastBasevol for each by default."""
     for inputFH in self.inputs:
         inputFH.setLastBasevol(lsq12ResampledFiles[inputFH])
     """ mincAverage all resampled brains and put in lsq12Directory"""
     self.lsq12Avg = abspath(self.lsq12Dir) + "/" + basename(
         self.lsq12Dir) + "-pairs.mnc"
     self.lsq12AvgFH = RegistrationPipeFH(self.lsq12Avg,
                                          basedir=self.lsq12Dir)
     avg = ma.mincAverage(inputs,
                          self.lsq12AvgFH,
                          output=self.lsq12Avg,
                          defaultDir=self.lsq12Dir)
     self.p.addStage(avg)